diff options
| author | Mattias Andrée <m@maandree.se> | 2026-01-26 17:57:59 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-01-26 17:57:59 +0100 |
| commit | b48e74772cc4e6879a6d37a5c00ad6df2db1edc3 (patch) | |
| tree | 4d1497bc28ff8ef8f2c4102195326dfe76b2622d | |
| parent | Add flipping and turning for yijing n-grams, and add invisible (diff) | |
| download | charconv-b48e74772cc4e6879a6d37a5c00ad6df2db1edc3.tar.gz charconv-b48e74772cc4e6879a6d37a5c00ad6df2db1edc3.tar.bz2 charconv-b48e74772cc4e6879a6d37a5c00ad6df2db1edc3.tar.xz | |
Add enclosed
Signed-off-by: Mattias Andrée <m@maandree.se>
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | convert-to-enclosed.c | 22 | ||||
| -rw-r--r-- | libcharconv.h | 15 | ||||
| -rw-r--r-- | libcharconv_enclosed_negative.c | 150 | ||||
| -rw-r--r-- | libcharconv_enclosed_positive.c | 209 | ||||
| -rw-r--r-- | libcharconv_latin.c | 93 | ||||
| -rw-r--r-- | libcharconv_negative.c | 85 | ||||
| -rw-r--r-- | libcharconv_sans_serif.c | 52 |
8 files changed, 583 insertions, 50 deletions
@@ -80,7 +80,8 @@ BIN =\ convert-to-rotated-90deg-cw\ convert-to-rotated-45deg-ccw\ convert-to-rotated-90deg-ccw\ - convert-to-invisible + convert-to-invisible\ + convert-to-enclosed LIBOBJ =\ libcharconv_decode_utf8_.o\ @@ -152,7 +153,9 @@ LIBOBJ =\ libcharconv_rotated_90deg_cw.o\ libcharconv_rotated_45deg_ccw.o\ libcharconv_rotated_90deg_ccw.o\ - libcharconv_invisible.o + libcharconv_invisible.o\ + libcharconv_enclosed_positive.o\ + libcharconv_enclosed_negative.o LOBJ = $(LIBOBJ:.o=.lo) diff --git a/convert-to-enclosed.c b/convert-to-enclosed.c new file mode 100644 index 0000000..8127b2f --- /dev/null +++ b/convert-to-enclosed.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-n | -p]"); + + +int +main(int argc, char *argv[]) +{ + int negative = 0; + + ARGBEGIN { + case 'n': negative = 1; break; + case 'p': negative = 0; break; + default: + usage(); + } ARGEND; + if (argc) + usage(); + + return convert(negative ? &libcharconv_enclosed_negative : &libcharconv_enclosed_positive); +} diff --git a/libcharconv.h b/libcharconv.h index 00aa7a9..1c8c4b9 100644 --- a/libcharconv.h +++ b/libcharconv.h @@ -145,7 +145,8 @@ LIBCHARCONV_FUNC_(libcharconv_monospace); LIBCHARCONV_FUNC_(libcharconv_segmented); /** - * Convert from Latin to MATHEMATICAL SANS-SERIF + * Convert from Latin and enclosed numbers to + * MATHEMATICAL SANS-SERIF */ LIBCHARCONV_FUNC_(libcharconv_sans_serif); @@ -459,6 +460,18 @@ LIBCHARCONV_FUNC_(libcharconv_rotated_90deg_ccw); */ LIBCHARCONV_FUNC_(libcharconv_invisible); +/** + * Convert alphanumerics, including regular and + * MATHEMATICAL SANS-SERIF, to outlined enclosed form + */ +LIBCHARCONV_FUNC_(libcharconv_enclosed_positive); + +/** + * Convert alphanumerics, including regular and + * MATHEMATICAL SANS-SERIF, to filled enclosed form + */ +LIBCHARCONV_FUNC_(libcharconv_enclosed_negative); + #undef LIBCHARCONV_FUNC_ #endif diff --git a/libcharconv_enclosed_negative.c b/libcharconv_enclosed_negative.c new file mode 100644 index 0000000..d7be6a7 --- /dev/null +++ b/libcharconv_enclosed_negative.c @@ -0,0 +1,150 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" + + +enum libcharconv_result +libcharconv_enclosed_negative(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) +{ + uint_least32_t c; + size_t old_slen; + *n = 0; + for (; slen--; s++) { + old_slen = slen; + if (s[0] == '(') { + if (!slen--) + goto indeterminate; + if ((unsigned char)s[1] == 0xF0u) { + if (!slen--) + goto indeterminate; + if ((unsigned char)s[2] != 0x9Du) + goto no_match; + if (!slen--) + goto indeterminate; + if ((unsigned char)s[3] != 0x9Fu) + goto no_match; + if (!slen--) + goto indeterminate; + if (0xA2u > (unsigned char)s[4] || (unsigned char)s[4] > 0xABu) + goto no_match; + if (!slen--) + goto indeterminate; + if (s[5] != ')') + goto no_match; + c = (unsigned char)s[4] - 0xA2u; + if (c == 0) + c = UINT32_C(0x1F10C); + else + c += UINT32_C(0x278A) - 1u; + goto conv6; + } else if (s[1] == '1') { + if (!slen--) + goto indeterminate; + if (s[2] == ')') { + c = UINT32_C(0x2776); + goto conv3; + } else if ('0' <= s[2] && s[2] <= '9') { + if (!slen--) + goto indeterminate; + if (s[3] != ')') + goto no_match; + if (s[2] == '0') + c = UINT32_C(0x277F); + else + c = UINT32_C(0x24EB) + (unsigned)(s[2] - '1'); + goto conv4; + } else { + goto no_match; + } + } else if (s[1] == '2') { + if (!slen--) + goto indeterminate; + if (s[2] == ')') { + c = UINT32_C(0x2777); + goto conv3; + } else if (s[2] == '0') { + if (!slen--) + goto indeterminate; + if (s[3] != ')') + goto no_match; + c = UINT32_C(0x24F4); + goto conv4; + } else { + goto no_match; + } + } else if (s[1] == '0') { + if (!slen--) + goto indeterminate; + if (s[2] != ')') + goto no_match; + c = UINT32_C(0x24FF); + goto conv3; + } else if ('3' <= s[1] && s[1] <= '9') { + if (!slen--) + goto indeterminate; + if (s[2] != ')') + goto no_match; + c = UINT32_C(0x2776) + (unsigned)(s[1] - '1'); + goto conv3; + } else if ('A' <= s[1] && s[1] <= 'Z') { + if (!slen--) + goto indeterminate; + if (s[2] != ')') + goto no_match; + c = UINT32_C(0x1F150) + (unsigned)(s[1] - 'A'); + goto conv3; + } else { + goto no_match; + } + } else if (s[0] == '[') { + if (!slen--) + goto indeterminate; + if ('A' <= s[1] && s[1] <= 'Z') { + if (!slen--) + goto indeterminate; + if (s[2] != ']') + goto no_match; + c = UINT32_C(0x1F170) + (unsigned)(s[1] - 'A'); + goto conv3; + } + } else { + no_match: + slen = old_slen; + *n += 1u; + break; + } + } +no_conv: + return LIBCHARCONV_NO_CONVERT; + +indeterminate: + if (*n) + goto no_conv; + return LIBCHARCONV_INDETERMINATE; + +conv3: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 3u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv4: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 4u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv6: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 6u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; +} diff --git a/libcharconv_enclosed_positive.c b/libcharconv_enclosed_positive.c new file mode 100644 index 0000000..15dd51e --- /dev/null +++ b/libcharconv_enclosed_positive.c @@ -0,0 +1,209 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" + + +enum libcharconv_result +libcharconv_enclosed_positive(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) +{ + uint_least32_t c; + size_t old_slen; + *n = 0; + for (; slen--; s++) { + old_slen = slen; + if (s[0] == '(') { + if (!slen--) + goto indeterminate; + if ((unsigned char)s[1] == 0xF0u) { + if (!slen--) + goto indeterminate; + if ((unsigned char)s[2] != 0x9Du) + goto no_match; + if (!slen--) + goto indeterminate; + if ((unsigned char)s[3] != 0x9Fu) + goto no_match; + if (!slen--) + goto indeterminate; + if (0xA2u > (unsigned char)s[4] || (unsigned char)s[4] > 0xABu) + goto no_match; + if (!slen--) + goto indeterminate; + if (s[5] != ')') + goto no_match; + c = (unsigned char)s[4] - 0xA2u; + if (c == 0) + c = UINT32_C(0x1F10B); + else + c += UINT32_C(0x2780) - 1u; + goto conv6; + } else if (s[1] == '(') { + if (!slen--) + goto indeterminate; + if (s[2] == '1') { + if (!slen--) + goto indeterminate; + if (s[3] == ')') { + if (!slen--) + goto indeterminate; + if (s[4] != ')') + goto no_match; + c = UINT32_C(0x24F5); + goto conv5; + } else if (s[3] == '0') { + if (!slen--) + goto indeterminate; + if (s[4] != ')') + goto no_match; + if (!slen--) + goto indeterminate; + if (s[5] != ')') + goto no_match; + c = UINT32_C(0x24FE); + goto conv6; + } else { + goto no_match; + } + } else if ('2' <= s[2] && s[2] <= '9') { + c = UINT32_C(0x24F6) + (unsigned)(s[2] - '2'); + if (!slen--) + goto indeterminate; + if (s[3] != ')') + goto no_match; + if (!slen--) + goto indeterminate; + if (s[4] != ')') + goto no_match; + goto conv5; + } + } else if (s[1] == '1') { + if (!slen--) + goto indeterminate; + if (s[2] == ')') { + c = UINT32_C(0x2460); + goto conv3; + } else if ('0' <= s[2] && s[2] <= '9') { + if (!slen--) + goto indeterminate; + if (s[3] != ')') + goto no_match; + c = UINT32_C(0x2469) + (unsigned)(s[2] - '0'); + goto conv4; + } else { + goto no_match; + } + } else if (s[1] == '2') { + if (!slen--) + goto indeterminate; + if (s[2] == ')') { + c = UINT32_C(0x2461); + goto conv3; + } else if (s[2] == '0') { + if (!slen--) + goto indeterminate; + if (s[3] != ')') + goto no_match; + c = UINT32_C(0x2473); + goto conv4; + } else { + goto no_match; + } + } else if (s[1] == '0') { + if (!slen--) + goto indeterminate; + if (s[2] != ')') + goto no_match; + c = UINT32_C(0x24EA); + goto conv3; + } else if ('3' <= s[1] && s[1] <= '9') { + if (!slen--) + goto indeterminate; + if (s[2] != ')') + goto no_match; + c = UINT32_C(0x2460) + (unsigned)(s[1] - '1'); + goto conv3; + } else if ('a' <= s[1] && s[1] <= 'z') { + if (!slen--) + goto indeterminate; + if (s[2] != ')') + goto no_match; + c = UINT32_C(0x24D0) + (unsigned)(s[1] - 'a'); + goto conv3; + } else if ('A' <= s[1] && s[1] <= 'Z') { + if (!slen--) + goto indeterminate; + if (s[2] != ')') + goto no_match; + c = UINT32_C(0x24B6) + (unsigned)(s[1] - 'A'); + goto conv3; + } else { + goto no_match; + } + } else if (s[0] == '[') { + if (!slen--) + goto indeterminate; + if (s[1] == 'd') { + if (!slen--) + goto indeterminate; + if (s[2] != ']') + goto no_match; + c = UINT32_C(0x1F1A5); + goto conv3; + } else if ('A' <= s[1] && s[1] <= 'Z') { + if (!slen--) + goto indeterminate; + if (s[2] != ']') + goto no_match; + c = UINT32_C(0x1F130) + (unsigned)(s[1] - 'A'); + goto conv3; + } + } else { + no_match: + slen = old_slen; + *n += 1u; + break; + } + } +no_conv: + return LIBCHARCONV_NO_CONVERT; + +indeterminate: + if (*n) + goto no_conv; + return LIBCHARCONV_INDETERMINATE; + +conv3: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 3u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv4: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 4u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv5: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 5u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv6: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 6u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; +} diff --git a/libcharconv_latin.c b/libcharconv_latin.c index 5e90e1e..4b41391 100644 --- a/libcharconv_latin.c +++ b/libcharconv_latin.c @@ -473,6 +473,84 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz c = (uint_least32_t)"eEe"[(c - UINT32_C(0x1FA48)) % 3u]; goto conv; + } else if (UINT32_C(0x2460) <= c && c <= UINT32_C(0x2468)) { + /* enclosed (positive) */ + c1 = '('; + c2 = (char)(c - (UINT32_C(0x2460) - (uint_least32_t)'1')); + c3 = ')'; + goto conv3; + } else if (UINT32_C(0x2469) <= c && c <= UINT32_C(0x2472)) { + /* enclosed (positive) */ + c1 = '('; + c2 = '1'; + c3 = (char)(c - (UINT32_C(0x2469) - (uint_least32_t)'0')); + c4 = ')'; + goto conv4; + } else if (UINT32_C(0x24D0) <= c && c <= UINT32_C(0x24E9)) { + /* enclosed (positive) */ + c1 = '('; + c2 = (char)(c - (UINT32_C(0x24D0) - (uint_least32_t)'a')); + c3 = ')'; + goto conv3; + } else if (UINT32_C(0x24B6) <= c && c <= UINT32_C(0x24CF)) { + /* enclosed (positive) */ + c1 = '('; + c2 = (char)(c - (UINT32_C(0x24B6) - (uint_least32_t)'A')); + c3 = ')'; + goto conv3; + } else if (UINT32_C(0x1F130) <= c && c <= UINT32_C(0x1F149)) { + /* enclosed (positive) */ + c1 = '['; + c2 = (char)(c - (UINT32_C(0x1F130) - (uint_least32_t)'A')); + c3 = ']'; + goto conv3; + } else if (UINT32_C(0x2780) <= c && c <= UINT32_C(0x2788)) { + /* enclosed (positive) */ + c1 = '('; + c2 = (char)(c - (UINT32_C(0x2780) - (uint_least32_t)'1')); + c3 = ')'; + goto conv3; + } else if (UINT32_C(0x24F5) <= c && c <= UINT32_C(0x24FD)) { + /* enclosed (positive) */ + c1 = '('; + c2 = '('; + c3 = (char)(c - (UINT32_C(0x24F5) - (uint_least32_t)'1')); + c4 = ')'; + c5 = ')'; + goto conv5; + + } else if (UINT32_C(0x2776) <= c && c <= UINT32_C(0x277E)) { + /* enclosed (negative) */ + c1 = '('; + c2 = (char)(c - (UINT32_C(0x2776) - (uint_least32_t)'1')); + c3 = ')'; + goto conv3; + } else if (UINT32_C(0x24EB) <= c && c <= UINT32_C(0x24F3)) { + /* enclosed (negative) */ + c1 = '('; + c2 = '1'; + c3 = (char)(c - (UINT32_C(0x24EB) - (uint_least32_t)'1')); + c4 = ')'; + goto conv4; + } else if (UINT32_C(0x1F150) <= c && c <= UINT32_C(0x1F169)) { + /* enclosed (negative) */ + c1 = '('; + c2 = (char)(c - (UINT32_C(0x1F150) - (uint_least32_t)'A')); + c3 = ')'; + goto conv3; + } else if (UINT32_C(0x1F170) <= c && c <= UINT32_C(0x1F189)) { + /* enclosed (negative) */ + c1 = '['; + c2 = (char)(c - (UINT32_C(0x1F170) - (uint_least32_t)'A')); + c3 = ']'; + goto conv3; + } else if (UINT32_C(0x278A) <= c && c <= UINT32_C(0x2792)) { + /* enclosed (negative) */ + c1 = '('; + c2 = (char)(c - (UINT32_C(0x278A) - (uint_least32_t)'1')); + c3 = ')'; + goto conv3; + } else { use_switch: switch (c) { @@ -888,6 +966,21 @@ libcharconv_latin(const char *s, size_t slen, size_t *n, uint_least32_t *cp, siz case UINT32_C(0x2063): c = (uint_least32_t)'|'; goto conv; case UINT32_C(0x2064): c = (uint_least32_t)'+'; goto conv; + /* enclosed (positive) */ + case UINT32_C(0x24EA): c1 = '('; c2 = '0'; c3 = ')'; goto conv3; + case UINT32_C(0x2473): c1 = '('; c2 = '2'; c3 = '0'; c4 = ')'; goto conv4; + case UINT32_C(0x1F1A5): c1 = '['; c2 = 'd'; c3 = ']'; goto conv3; + case UINT32_C(0x24FE): c1 = '('; c2 = '('; c3 = '1'; c4 = '0'; c5 = ')'; c6 = ')'; goto conv6; + case UINT32_C(0x2789): c1 = '('; c2 = '1'; c3 = '0'; c4 = ')'; goto conv4; + case UINT32_C(0x1F10B): c1 = '('; c2 = '0'; c3 = ')'; goto conv3; + + /* enclosed (negative) */ + case UINT32_C(0x24FF): c1 = '('; c2 = '0'; c3 = ')'; goto conv3; + case UINT32_C(0x277F): c1 = '('; c2 = '1'; c3 = '0'; c4 = ')'; goto conv4; + case UINT32_C(0x24F4): c1 = '('; c2 = '2'; c3 = '0'; c4 = ')'; goto conv4; + case UINT32_C(0x2793): c1 = '('; c2 = '1'; c3 = '0'; c4 = ')'; goto conv4; + case UINT32_C(0x1F10C): c1 = '('; c2 = '0'; c3 = ')'; goto conv3; + default: no_match: *n += clen; diff --git a/libcharconv_negative.c b/libcharconv_negative.c index 3bbbccb..92470c8 100644 --- a/libcharconv_negative.c +++ b/libcharconv_negative.c @@ -23,7 +23,26 @@ static struct { {UINT32_C(0x1FA30), UINT32_C(0x1FA31)}, {UINT32_C(0x1FA45), UINT32_C(0x1FA46)}, {UINT32_C(0x1FA48), UINT32_C(0x1FA49)}, - {UINT32_C(0x1FA4B), UINT32_C(0x1FA4C)} + {UINT32_C(0x1FA4B), UINT32_C(0x1FA4C)}, + {UINT32_C(0x24EA), UINT32_C(0x24FF)}, + {UINT32_C(0x1F10B), UINT32_C(0x1F10C)} +}; + + +static struct { + struct {uint_least32_t low, high;} low, high; +} range_pairs[] = { + {{UINT32_C(0x2654), UINT32_C(0x2659)}, {UINT32_C(0x265A), UINT32_C(0x265F)}}, + {{UINT32_C(0x1FA60), UINT32_C(0x1FA66)}, {UINT32_C(0x1FA67), UINT32_C(0x1FA6D)}}, + {{UINT32_C(0x1FA09), UINT32_C(0x1FA0E)}, {UINT32_C(0x1FA0F), UINT32_C(0x1FA14)}}, + {{UINT32_C(0x1FA1E), UINT32_C(0x1FA23)}, {UINT32_C(0x1FA24), UINT32_C(0x1FA29)}}, + {{UINT32_C(0x1FA33), UINT32_C(0x1FA38)}, {UINT32_C(0x1FA39), UINT32_C(0x1FA3E)}}, + {{UINT32_C(0x1FA4E), UINT32_C(0x1FA50)}, {UINT32_C(0x1FA51), UINT32_C(0x1FA53)}}, + {{UINT32_C(0x2460), UINT32_C(0x2469)}, {UINT32_C(0x2776), UINT32_C(0x277F)}}, + {{UINT32_C(0x246A), UINT32_C(0x2473)}, {UINT32_C(0x24EB), UINT32_C(0x24F4)}}, + {{UINT32_C(0x24B6), UINT32_C(0x24CF)}, {UINT32_C(0x1F150), UINT32_C(0x1F169)}}, + {{UINT32_C(0x1F130), UINT32_C(0x1F149)}, {UINT32_C(0x1F170), UINT32_C(0x1F189)}}, + {{UINT32_C(0x2780), UINT32_C(0x2789)}, {UINT32_C(0x278A), UINT32_C(0x2793)}} }; @@ -47,52 +66,24 @@ libcharconv_negative(const char *s, size_t slen, size_t *n, uint_least32_t *cp, continue; } - if (UINT32_C(0x2654) <= c && c <= UINT32_C(0x2659)) { - c += 6u; - goto conv; - } else if (UINT32_C(0x265A) <= c && c <= UINT32_C(0x265F)) { - c -= 6u; - goto conv; - } else if (UINT32_C(0x1FA60) <= c && c <= UINT32_C(0x1FA66)) { - c += 7u; - goto conv; - } else if (UINT32_C(0x1FA67) <= c && c <= UINT32_C(0x1FA6D)) { - c -= 7u; - goto conv; - } else if (UINT32_C(0x1FA09) <= c && c <= UINT32_C(0x1FA0E)) { - c += UINT32_C(0x1FA0F) - UINT32_C(0x1FA09); - goto conv; - } else if (UINT32_C(0x1FA0F) <= c && c <= UINT32_C(0x1FA14)) { - c -= UINT32_C(0x1FA0F) - UINT32_C(0x1FA09); - goto conv; - } else if (UINT32_C(0x1FA1E) <= c && c <= UINT32_C(0x1FA23)) { - c += UINT32_C(0x1FA24) - UINT32_C(0x1FA1E); - goto conv; - } else if (UINT32_C(0x1FA24) <= c && c <= UINT32_C(0x1FA29)) { - c -= UINT32_C(0x1FA24) - UINT32_C(0x1FA1E); - goto conv; - } else if (UINT32_C(0x1FA33) <= c && c <= UINT32_C(0x1FA38)) { - c += UINT32_C(0x1FA39) - UINT32_C(0x1FA33); - goto conv; - } else if (UINT32_C(0x1FA39) <= c && c <= UINT32_C(0x1FA3E)) { - c -= UINT32_C(0x1FA39) - UINT32_C(0x1FA33); - goto conv; - } else if (UINT32_C(0x1FA4E) <= c && c <= UINT32_C(0x1FA50)) { - c += UINT32_C(0x1FA51) - UINT32_C(0x1FA4E); - goto conv; - } else if (UINT32_C(0x1FA51) <= c && c <= UINT32_C(0x1FA53)) { - c -= UINT32_C(0x1FA51) - UINT32_C(0x1FA4E); - goto conv; - } else { - for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) { - if (c == pairs[i].a) { - c = pairs[i].b; - goto conv; - } - if (c == pairs[i].b) { - c = pairs[i].a; - goto conv; - } + for (i = 0u; i < sizeof(range_pairs) / sizeof(*range_pairs); i++) { + if (range_pairs[i].low.low <= c && c <= range_pairs[i].low.high) { + c += range_pairs[i].high.low - range_pairs[i].low.low; + goto conv; + } + if (range_pairs[i].high.low <= c && c <= range_pairs[i].high.high) { + c -= range_pairs[i].high.low - range_pairs[i].low.low; + goto conv; + } + } + for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) { + if (c == pairs[i].a) { + c = pairs[i].b; + goto conv; + } + if (c == pairs[i].b) { + c = pairs[i].a; + goto conv; } } diff --git a/libcharconv_sans_serif.c b/libcharconv_sans_serif.c index 152ce0c..787d14b 100644 --- a/libcharconv_sans_serif.c +++ b/libcharconv_sans_serif.c @@ -6,8 +6,10 @@ enum libcharconv_result libcharconv_sans_serif(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) { uint_least32_t c; + size_t old_slen; *n = 0; for (; slen--; s++) { + old_slen = slen; if ('A' <= *s && *s <= 'Z') { c = (uint_least32_t)(UINT32_C(0x1D5A0) + (unsigned)(*s - 'A')); goto conv; @@ -17,13 +19,54 @@ libcharconv_sans_serif(const char *s, size_t slen, size_t *n, uint_least32_t *cp } else if ('0' <= *s && *s <= '9') { c = (uint_least32_t)(UINT32_C(0x1D7E2) + (unsigned)(*s - '0')); goto conv; + } else if ((unsigned char)s[0] == 0xE2u) { + if (!slen--) + goto indeterminate; + if ((unsigned char)s[1] == 0x93u) { + if (!slen--) + goto indeterminate; + if ((unsigned char)s[2] == 0xAAu) + c = (uint_least32_t)UINT32_C(0x1F10B); + else if ((unsigned char)s[2] == 0xBFu) + c = (uint_least32_t)UINT32_C(0x1F10C); + else + goto no_match; + goto conv3; + } else if ((unsigned char)s[1] == 0x91u) { + if (!slen--) + goto indeterminate; + if (0xA0u <= (unsigned char)s[2] && (unsigned char)s[2] <= 0xA9u) + c = (uint_least32_t)UINT32_C(0x2780); + else + goto no_match; + c += (unsigned char)s[2] - 0xA0u; + goto conv3; + } else if ((unsigned char)s[1] == 0x9Du) { + if (!slen--) + goto indeterminate; + if (!slen--) + goto indeterminate; + if (0xB6u <= (unsigned char)s[2] && (unsigned char)s[2] <= 0xBFu) + c = (uint_least32_t)UINT32_C(0x278A); + else + goto no_match; + c += (unsigned char)s[2] - 0xB6u; + goto conv3; + } else { + goto no_match; + } } else { + no_match: + slen = old_slen; *n += 1u; } } no_conv: return LIBCHARCONV_NO_CONVERT; +indeterminate: + return LIBCHARCONV_INDETERMINATE; + conv: if (*n) goto no_conv; @@ -32,4 +75,13 @@ conv: *n += 1u; *ncp = 1u; return LIBCHARCONV_CONVERTED; + +conv3: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 3u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; } |
