aboutsummaryrefslogtreecommitdiffstats
path: root/libcharconv_joined.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_joined.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_joined.c')
-rw-r--r--libcharconv_joined.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/libcharconv_joined.c b/libcharconv_joined.c
index e8e0a59..e8ab45f 100644
--- a/libcharconv_joined.c
+++ b/libcharconv_joined.c
@@ -11,6 +11,8 @@ static struct {
{(uint_least32_t)'?', (uint_least32_t)'?', UINT32_C(0x2047)},
{(uint_least32_t)'!', (uint_least32_t)'!', UINT32_C(0x203C)},
{(uint_least32_t)'!', (uint_least32_t)'?', UINT32_C(0x2049)},
+ {(uint_least32_t)':', (uint_least32_t)':', UINT32_C(0x2E2C)},
+ {(uint_least32_t)'|', (uint_least32_t)'|', UINT32_C(0x2016)},
{UINT32_C(0x23CB), UINT32_C(0x23BE), UINT32_C(0x23C9)},
{UINT32_C(0x23CC), UINT32_C(0x23BF), UINT32_C(0x23CA)}
};
@@ -19,7 +21,7 @@ static struct {
enum libcharconv_result
libcharconv_joined(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) {
@@ -36,6 +38,46 @@ libcharconv_joined(const char *s, size_t slen, size_t *n, uint_least32_t *cp, si
continue;
}
+ if (UINT32_C(0x1681) <= a && a <= UINT32_C(0x1694)) {
+ 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(0x1681) > b || b > UINT32_C(0x1694))
+ goto no_conv_consume;
+ if ((a - UINT32_C(0x1681)) / 5u != (b - UINT32_C(0x1681)) / 5u)
+ goto no_conv_consume;
+ c = (a - UINT32_C(0x1681)) % 5u + (b - UINT32_C(0x1681)) % 5u + 1u;
+ if (c >= 5u)
+ goto no_conv_consume;
+ a = c += (a - UINT32_C(0x1681)) / 5u * 5u + UINT32_C(0x1681);
+ 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(0x1681) > b || b > UINT32_C(0x1694))
+ goto conv_calc;
+ if ((a - UINT32_C(0x1681)) / 5u != (b - UINT32_C(0x1681)) / 5u)
+ goto conv_calc;
+ b = (a - UINT32_C(0x1681)) % 5u + (b - UINT32_C(0x1681)) % 5u + 1u;
+ if (b >= 5u)
+ goto conv_calc;
+ a = c = b + (a - UINT32_C(0x1681)) / 5u * 5u + UINT32_C(0x1681);
+ alen += blen;
+ }
+ goto conv_calc;
+ }
+
for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) {
if (a != pairs[i].a)
continue;
@@ -59,12 +101,34 @@ libcharconv_joined(const char *s, size_t slen, size_t *n, uint_least32_t *cp, si
no_conv:
return LIBCHARCONV_NO_CONVERT;
+no_conv_consume:
+ *n += alen;
+ return LIBCHARCONV_NO_CONVERT;
+
conv:
if (*n)
goto no_conv;
if (*ncp)
- *cp = pairs[i].to;
+ *cp = c = pairs[i].to;
*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;
}