aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-26 17:57:59 +0100
committerMattias Andrée <m@maandree.se>2026-01-26 17:57:59 +0100
commitb48e74772cc4e6879a6d37a5c00ad6df2db1edc3 (patch)
tree4d1497bc28ff8ef8f2c4102195326dfe76b2622d
parentAdd flipping and turning for yijing n-grams, and add invisible (diff)
downloadcharconv-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--Makefile7
-rw-r--r--convert-to-enclosed.c22
-rw-r--r--libcharconv.h15
-rw-r--r--libcharconv_enclosed_negative.c150
-rw-r--r--libcharconv_enclosed_positive.c209
-rw-r--r--libcharconv_latin.c93
-rw-r--r--libcharconv_negative.c85
-rw-r--r--libcharconv_sans_serif.c52
8 files changed, 583 insertions, 50 deletions
diff --git a/Makefile b/Makefile
index d6a2431..615f7f2 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
}