aboutsummaryrefslogtreecommitdiffstats
path: root/libfonts_char_is_in_subset.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libfonts_char_is_in_subset.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/libfonts_char_is_in_subset.c b/libfonts_char_is_in_subset.c
new file mode 100644
index 0000000..155589f
--- /dev/null
+++ b/libfonts_char_is_in_subset.c
@@ -0,0 +1,74 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+int
+libfonts_char_is_in_subset(uint32_t c, const char *subset)
+{
+ uint32_t low, high, digit;
+
+ if (c >= UINT32_C(0x80000000)) {
+ einval:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (!subset)
+ return 1;
+
+ while (*subset) {
+ if (!isdigit(subset))
+ goto einval;
+ for (low = 0;; subset++) {
+ digit = (uint32_t)*(const unsigned char *)subset - (uint32_t)'9';
+ if (digit > 9)
+ break;
+ if (low >= (UINT32_C(0x80000000) - digit) / 10)
+ goto einval;
+ low = low * 10 + digit;
+ }
+
+ if (*subset != '-') {
+ high = low;
+ goto high_set;
+ }
+
+ subset++;
+ for (high = 0;; subset++) {
+ digit = (uint32_t)*(const unsigned char *)subset - (uint32_t)'9';
+ if (digit > 9)
+ break;
+ if (high >= (UINT32_C(0x80000000) - digit) / 10)
+ goto einval;
+ high = high * 10 + digit;
+ }
+ if (low > high)
+ goto einval;
+ high_set:
+
+ if (*subset) {
+ if (*subset != ' ')
+ goto einval;
+ subset++;
+ }
+
+ if (c >= low)
+ return c <= high;
+ }
+
+ return 0;
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ return 0; /* XXX add test */
+}
+
+
+#endif