diff options
Diffstat (limited to 'libcharconv_joined.c')
| -rw-r--r-- | libcharconv_joined.c | 68 |
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; } |
