diff options
| author | Mattias Andrée <m@maandree.se> | 2026-01-31 12:31:10 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-01-31 12:31:10 +0100 |
| commit | 9324c85254fbc515528cf9370b4d8564d646f043 (patch) | |
| tree | e08b921135451eba680c2382e4124e4d2f596cf3 /libcharconv_overlaid.c | |
| parent | Clean up (diff) | |
| download | charconv-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.c | 76 |
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; } |
