aboutsummaryrefslogtreecommitdiffstats
path: root/libcharconv_overlaid.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-31 12:31:10 +0100
committerMattias Andrée <m@maandree.se>2026-01-31 12:31:10 +0100
commit9324c85254fbc515528cf9370b4d8564d646f043 (patch)
treee08b921135451eba680c2382e4124e4d2f596cf3 /libcharconv_overlaid.c
parentClean up (diff)
downloadcharconv-9324c85254fbc515528cf9370b4d8564d646f043.tar.gz
charconv-9324c85254fbc515528cf9370b4d8564d646f043.tar.bz2
charconv-9324c85254fbc515528cf9370b4d8564d646f043.tar.xz
Misc
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libcharconv_overlaid.c')
-rw-r--r--libcharconv_overlaid.c76
1 files changed, 74 insertions, 2 deletions
diff --git a/libcharconv_overlaid.c b/libcharconv_overlaid.c
index 05cf0d3..5b738b9 100644
--- a/libcharconv_overlaid.c
+++ b/libcharconv_overlaid.c
@@ -55,14 +55,26 @@ static struct {
{UINT32_C(0x23CA), UINT32_C(0x23C6), UINT32_C(0x23C8)},
{(uint_least32_t)'-', UINT32_C(0x238F), UINT32_C(0x2390)},
{(uint_least32_t)'-', UINT32_C(0x2391), UINT32_C(0x2392)},
- {(uint_least32_t)'-', (uint_least32_t)'~', UINT32_C(0x23E6)}
+ {(uint_least32_t)'-', (uint_least32_t)'~', UINT32_C(0x23E6)},
+ {UINT32_C(0x1681), UINT32_C(0x1686), UINT32_C(0x168B)},
+ {UINT32_C(0x1682), UINT32_C(0x1687), UINT32_C(0x168C)},
+ {UINT32_C(0x1683), UINT32_C(0x1688), UINT32_C(0x168D)},
+ {UINT32_C(0x1684), UINT32_C(0x1689), UINT32_C(0x168E)},
+ {UINT32_C(0x1685), UINT32_C(0x168A), UINT32_C(0x168F)},
+ {UINT32_C(0x2571), UINT32_C(0x2572), UINT32_C(0x2573)},
+ {(uint_least32_t)'S', (uint_least32_t)'S', UINT32_C(0x00A7)},
+ {(uint_least32_t)'s', (uint_least32_t)'s', UINT32_C(0x00A7)},
+ {UINT32_C(0x2E2C), (uint_least32_t)'+', UINT32_C(0x205C)},
+ {UINT32_C(0x2058), (uint_least32_t)'x', UINT32_C(0x203B)},
+ {UINT32_C(0x2058), (uint_least32_t)'X', UINT32_C(0x203B)},
+ {(uint_least32_t)'>', (uint_least32_t)':', UINT32_C(0x2E16)}
};
enum libcharconv_result
libcharconv_overlaid(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
{
- uint_least32_t a, b;
+ uint_least32_t a, b, c;
size_t i, alen, blen;
*n = 0;
while (slen) {
@@ -79,6 +91,44 @@ libcharconv_overlaid(const char *s, size_t slen, size_t *n, uint_least32_t *cp,
continue;
}
+ if (UINT32_C(0x1FBA0) <= a && a <= UINT32_C(0x1FBAE)) {
+ if (*n)
+ goto no_conv;
+ if (slen == alen)
+ return LIBCHARCONV_INDETERMINATE;
+ blen = libcharconv_decode_utf8_(&s[alen], slen - alen, &b);
+ if (blen > slen)
+ return LIBCHARCONV_INDETERMINATE;
+ if (!blen)
+ goto no_conv;
+ if (UINT32_C(0x1FBA0) > b || b > UINT32_C(0x1FBAE))
+ goto no_conv_consume;
+ a = (uint_least32_t)"\x01\x02\x04\x08\x05\x0A\x0C\x03\x09\x06\x0E\x0D\x0B\x07\x0F"[a & 0xF];
+ b = (uint_least32_t)"\x01\x02\x04\x08\x05\x0A\x0C\x03\x09\x06\x0E\x0D\x0B\x07\x0F"[b & 0xF];
+ c = (uint_least32_t)" \x00\x01\x07\x02\x04\x09\x0D\x03\x08\x05\x0C\x06\x0B\x0A\x0E"[a | b];
+ a = c |= UINT32_C(0x1FBA0);
+ alen += blen;
+ for (;;) {
+ if (slen == alen)
+ goto conv_if_end_calc;
+ blen = libcharconv_decode_utf8_(&s[alen], slen - alen, &b);
+ if (blen > slen)
+ return LIBCHARCONV_INDETERMINATE;
+ if (!blen)
+ goto conv_calc;
+ if (UINT32_C(0x1FBA0) > b || b > UINT32_C(0x1FBAE))
+ goto conv_calc;
+ a &= 0xF;
+ b &= 0xF;
+ a = (uint_least32_t)"\x01\x02\x04\x08\x05\x0A\x0C\x03\x09\x06\x0E\x0D\x0B\x07\x0F"[a & 0xF];
+ b = (uint_least32_t)"\x01\x02\x04\x08\x05\x0A\x0C\x03\x09\x06\x0E\x0D\x0B\x07\x0F"[b & 0xF];
+ c = (uint_least32_t)" \x00\x01\x07\x02\x04\x09\x0D\x03\x08\x05\x0C\x06\x0B\x0A\x0E"[a | b];
+ a = c |= UINT32_C(0x1FBA0);
+ alen += blen;
+ }
+ goto conv_calc;
+ }
+
for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) {
if (a != pairs[i].a && a != pairs[i].b)
continue;
@@ -102,6 +152,10 @@ libcharconv_overlaid(const char *s, size_t slen, size_t *n, uint_least32_t *cp,
no_conv:
return LIBCHARCONV_NO_CONVERT;
+no_conv_consume:
+ *n += alen;
+ return LIBCHARCONV_NO_CONVERT;
+
conv:
if (*n)
goto no_conv;
@@ -110,4 +164,22 @@ conv:
*n += alen + blen;
*ncp = 1u;
return LIBCHARCONV_CONVERTED;
+
+conv_calc:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += alen;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+
+conv_if_end_calc:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += alen;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERT_IF_END;
}