/* See LICENSE file for copyright and license details. */ #include "lib-common.h" static struct { uint_least32_t a; uint_least32_t b; uint_least32_t to; } pairs[] = { {UINT32_C(0x00BF), UINT32_C(0x00A1), UINT32_C(0x2E18)}, {UINT32_C(0x0021), UINT32_C(0x003F), UINT32_C(0x203D)}, {UINT32_C(0x1FA06), UINT32_C(0x1FA07), UINT32_C(0x1FA08)}, {UINT32_C(0x1FA1B), UINT32_C(0x1FA1C), UINT32_C(0x1FA1D)}, {UINT32_C(0x1FA30), UINT32_C(0x1FA31), UINT32_C(0x1FA32)}, {UINT32_C(0x1FA45), UINT32_C(0x1FA46), UINT32_C(0x1FA47)}, {UINT32_C(0x1FA48), UINT32_C(0x1FA49), UINT32_C(0x1FA4A)}, {UINT32_C(0x1FA4B), UINT32_C(0x1FA4C), UINT32_C(0x1FA4D)}, {UINT32_C(0x2654), UINT32_C(0x265A), UINT32_C(0x1FA00)}, {UINT32_C(0x2655), UINT32_C(0x265B), UINT32_C(0x1FA01)}, {UINT32_C(0x2656), UINT32_C(0x265C), UINT32_C(0x1FA02)}, {UINT32_C(0x2657), UINT32_C(0x265D), UINT32_C(0x1FA03)}, {UINT32_C(0x2658), UINT32_C(0x265E), UINT32_C(0x1FA04)}, {UINT32_C(0x2659), UINT32_C(0x265F), UINT32_C(0x1FA05)}, {UINT32_C(0x1FA09), UINT32_C(0x1FA0F), UINT32_C(0x1FA15)}, {UINT32_C(0x1FA0A), UINT32_C(0x1FA10), UINT32_C(0x1FA16)}, {UINT32_C(0x1FA0B), UINT32_C(0x1FA11), UINT32_C(0x1FA17)}, {UINT32_C(0x1FA0C), UINT32_C(0x1FA12), UINT32_C(0x1FA18)}, {UINT32_C(0x1FA0D), UINT32_C(0x1FA13), UINT32_C(0x1FA19)}, {UINT32_C(0x1FA0E), UINT32_C(0x1FA14), UINT32_C(0x1FA1A)}, {UINT32_C(0x1FA1E), UINT32_C(0x1FA24), UINT32_C(0x1FA2A)}, {UINT32_C(0x1FA1F), UINT32_C(0x1FA25), UINT32_C(0x1FA2B)}, {UINT32_C(0x1FA20), UINT32_C(0x1FA26), UINT32_C(0x1FA2C)}, {UINT32_C(0x1FA21), UINT32_C(0x1FA27), UINT32_C(0x1FA2D)}, {UINT32_C(0x1FA22), UINT32_C(0x1FA28), UINT32_C(0x1FA2E)}, {UINT32_C(0x1FA23), UINT32_C(0x1FA29), UINT32_C(0x1FA2F)}, {UINT32_C(0x1FA33), UINT32_C(0x1FA39), UINT32_C(0x1FA3F)}, {UINT32_C(0x1FA34), UINT32_C(0x1FA3A), UINT32_C(0x1FA40)}, {UINT32_C(0x1FA35), UINT32_C(0x1FA3B), UINT32_C(0x1FA41)}, {UINT32_C(0x1FA36), UINT32_C(0x1FA3C), UINT32_C(0x1FA42)}, {UINT32_C(0x1FA37), UINT32_C(0x1FA3D), UINT32_C(0x1FA43)}, {UINT32_C(0x1FA38), UINT32_C(0x1FA3E), UINT32_C(0x1FA44)}, {UINT32_C(0x2658), UINT32_C(0x2655), UINT32_C(0x1FA4E)}, {UINT32_C(0x2658), UINT32_C(0x2656), UINT32_C(0x1FA4F)}, {UINT32_C(0x2658), UINT32_C(0x2657), UINT32_C(0x1FA50)}, {UINT32_C(0x265E), UINT32_C(0x265B), UINT32_C(0x1FA51)}, {UINT32_C(0x265E), UINT32_C(0x265C), UINT32_C(0x1FA52)}, {UINT32_C(0x265E), UINT32_C(0x265D), UINT32_C(0x1FA53)}, {UINT32_C(0x23CB), UINT32_C(0x23BE), UINT32_C(0x23C9)}, {UINT32_C(0x23CC), UINT32_C(0x23BF), UINT32_C(0x23CA)}, {UINT32_C(0x23C9), UINT32_C(0x23C0), UINT32_C(0x23C1)}, {UINT32_C(0x23C9), UINT32_C(0x23C3), UINT32_C(0x23C4)}, {UINT32_C(0x23C9), UINT32_C(0x23C6), UINT32_C(0x23C7)}, {UINT32_C(0x23CA), UINT32_C(0x23C0), UINT32_C(0x23C2)}, {UINT32_C(0x23CA), UINT32_C(0x23C3), UINT32_C(0x23C5)}, {UINT32_C(0x23CA), UINT32_C(0x23C6), UINT32_C(0x23C8)} }; 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; size_t i, alen, blen; *n = 0; while (slen) { alen = libcharconv_decode_utf8_(s, slen, &a); if (alen > slen) { if (*n) goto no_conv; return LIBCHARCONV_INDETERMINATE; } if (!alen) { *n += 1u; slen -= 1u; s = &s[1]; continue; } for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) { if (a != pairs[i].a && a != pairs[i].b) continue; 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 ((a ^ b) == (pairs[i].a ^ pairs[i].b)) goto conv; } *n += alen; s = &s[alen]; slen -= alen; } no_conv: return LIBCHARCONV_NO_CONVERT; conv: if (*n) goto no_conv; if (*ncp) *cp = pairs[i].to; *n += alen + blen; *ncp = 1u; return LIBCHARCONV_CONVERTED; }