diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | libfonts.h | 17 | ||||
-rw-r--r-- | libfonts_char_is_in_subset.c | 74 |
3 files changed, 92 insertions, 0 deletions
@@ -18,6 +18,7 @@ LIB_NAME = fonts PUBLIC_OBJ =\ libfonts_calculate_subpixel_order.o\ + libfonts_char_is_in_subset.o\ libfonts_decode_font_description.o\ libfonts_do_decoded_font_descriptions_match.o\ libfonts_do_font_descriptions_match.o\ @@ -1826,6 +1826,23 @@ int libfonts_parse_alias_line(enum libfonts_alias_line_type *, char **, char **, */ int libfonts_parse_dir_line(char **, char **, const char *, char **); +/** + * Sets if a specific character is in a subset of + * of character set + * + * @param c The character to test; it is assumed that + * it is a member of the complete character set + * @param subset The subset (of the complete character set) + * to test against; shall be formatted as + * `struct libfonts_font_description.charset_subset` + * @return 1 if the character is a member of the subset, + * or `subset` is `NULL`, 0 otherwise; -1 on failure + * + * @throws EINVAL If `c` is equal to greater than 0x80000000 + * @throws EINVAL If `subset` is invalid + */ +int libfonts_char_is_in_subset(uint32_t, const char *); + /* TODO add font listing */ 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 |