/* See LICENSE file for copyright and license details. */ #include "lib-common.h" static struct { uint_least32_t a; uint_least32_t b; } pairs[] = { {UINT32_C(0x2032), UINT32_C(0x2035)}, {UINT32_C(0x2033), UINT32_C(0x2036)}, {UINT32_C(0x2034), UINT32_C(0x2037)}, {UINT32_C(0x204F), UINT32_C(0x003B)}, {UINT32_C(0x2E2E), UINT32_C(0x003F)}, {UINT32_C(0x2143), UINT32_C(0x004C)}, {UINT32_C(0xA4ED), (uint_least32_t)'B'}, {UINT32_C(0xA4DB), (uint_least32_t)'C'}, {UINT32_C(0xA4F7), (uint_least32_t)'D'}, {UINT32_C(0xA4F1), (uint_least32_t)'E'}, {UINT32_C(0xA4D8), (uint_least32_t)'K'}, {UINT32_C(0x1F12F), UINT32_C(0x00A9)}, {UINT32_C(0x230C), UINT32_C(0x230D)}, {UINT32_C(0x230E), UINT32_C(0x230F)}, {UINT32_C(0x23BE), UINT32_C(0x23CB)}, {UINT32_C(0x23BF), UINT32_C(0x23CC)}, {UINT32_C(0x169B), UINT32_C(0x169C)}, {UINT32_C(0x2571), UINT32_C(0x2572)}, {UINT32_C(0x250C), UINT32_C(0x2510)}, {UINT32_C(0x250D), UINT32_C(0x2511)}, {UINT32_C(0x250E), UINT32_C(0x2512)}, {UINT32_C(0x250F), UINT32_C(0x2513)}, {UINT32_C(0x2514), UINT32_C(0x2518)}, {UINT32_C(0x2515), UINT32_C(0x2519)}, {UINT32_C(0x2516), UINT32_C(0x251A)}, {UINT32_C(0x2517), UINT32_C(0x251B)}, {UINT32_C(0x251C), UINT32_C(0x2524)}, {UINT32_C(0x251D), UINT32_C(0x2525)}, {UINT32_C(0x251E), UINT32_C(0x2526)}, {UINT32_C(0x251F), UINT32_C(0x2527)}, {UINT32_C(0x2520), UINT32_C(0x2528)}, {UINT32_C(0x2521), UINT32_C(0x2529)}, {UINT32_C(0x2522), UINT32_C(0x252A)}, {UINT32_C(0x2523), UINT32_C(0x252B)}, {UINT32_C(0x252E), UINT32_C(0x252D)}, {UINT32_C(0x2532), UINT32_C(0x2531)}, {UINT32_C(0x2536), UINT32_C(0x2535)}, {UINT32_C(0x253A), UINT32_C(0x2539)}, {UINT32_C(0x253E), UINT32_C(0x253D)}, {UINT32_C(0x2544), UINT32_C(0x2543)}, {UINT32_C(0x2546), UINT32_C(0x2545)}, {UINT32_C(0x254A), UINT32_C(0x2549)}, {UINT32_C(0x2552), UINT32_C(0x2555)}, {UINT32_C(0x2553), UINT32_C(0x2556)}, {UINT32_C(0x2554), UINT32_C(0x2557)}, {UINT32_C(0x2558), UINT32_C(0x255B)}, {UINT32_C(0x2559), UINT32_C(0x255C)}, {UINT32_C(0x255A), UINT32_C(0x255D)}, {UINT32_C(0x255E), UINT32_C(0x2561)}, {UINT32_C(0x255F), UINT32_C(0x2562)}, {UINT32_C(0x2560), UINT32_C(0x2563)}, {UINT32_C(0x256D), UINT32_C(0x256E)}, {UINT32_C(0x2570), UINT32_C(0x256F)}, {UINT32_C(0x2574), UINT32_C(0x2576)}, {UINT32_C(0x2578), UINT32_C(0x257A)}, {UINT32_C(0x257C), UINT32_C(0x257E)}, }; enum libcharconv_result libcharconv_mirrored(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) { uint_least32_t c; size_t i, clen; *n = 0; while (slen) { clen = libcharconv_decode_utf8_(s, slen, &c); if (clen > slen) { if (*n) goto no_conv; return LIBCHARCONV_INDETERMINATE; } if (!clen) { *n += 1u; slen -= 1u; s = &s[1]; continue; } if (UINT32_C(0x1F031) <= c && c <= UINT32_C(0x1F061)) { c -= UINT32_C(0x1F031); c = c % 7u * 7u + c / 7u; c += UINT32_C(0x1F031); goto conv; } else if (UINT32_C(0x2800) <= c && c <= UINT32_C(0x28FF)) { c = ((c & 0x07u) << 3) | ((c & 0x38u) >> 3) | ((c & 0x40u) << 1) | ((c & 0x80u) >> 1) | UINT32_C(0x2800); goto conv; } else if (UINT32_C(0x1FBA0) <= c && c <= UINT32_C(0x1FBAD)) { c ^= 1u; goto conv; } else { for (i = 0u; i < sizeof(pairs) / sizeof(*pairs); i++) { if (c == pairs[i].a) { c = pairs[i].b; goto conv; } if (c == pairs[i].b) { c = pairs[i].a; goto conv; } } } *n += clen; s = &s[clen]; slen -= clen; } no_conv: return LIBCHARCONV_NO_CONVERT; conv: if (*n) goto no_conv; if (*ncp) *cp = c; *n += clen; *ncp = 1u; return LIBCHARCONV_CONVERTED; }