diff options
Diffstat (limited to 'libcharconv_buhid.c')
| -rw-r--r-- | libcharconv_buhid.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/libcharconv_buhid.c b/libcharconv_buhid.c new file mode 100644 index 0000000..812a1c0 --- /dev/null +++ b/libcharconv_buhid.c @@ -0,0 +1,108 @@ +/* See LICENSE file for copyright and license details. */ +#include "libcharconv.h" + + +enum libcharconv_result +libcharconv_buhid(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) +{ + uint_least32_t c; + *n = 0; + for (; slen--; s++) { + switch (s[0]) { + case 'A': case 'a': c = UINT32_C(0x1740); goto conv1; + case 'I': case 'i': c = UINT32_C(0x1741); goto conv1; + case 'U': case 'u': c = UINT32_C(0x1742); goto conv1; + case '^': + if (!slen) + return LIBCHARCONV_INDETERMINATE; + switch (s[1]) { + case 'I': case 'i': c = UINT32_C(0x1752); goto conv2; + case 'U': case 'u': c = UINT32_C(0x1753); goto conv2; + default: + goto no_match; + } + goto no_match; + case 'B': case 'b': c = UINT32_C(0x174A); goto conv; + case 'D': case 'd': c = UINT32_C(0x1747); goto conv; + case 'G': case 'g': c = UINT32_C(0x1744); goto conv; + case 'H': case 'h': c = UINT32_C(0x1751); goto conv; + case 'K': case 'k': c = UINT32_C(0x1743); goto conv; + case 'L': case 'l': c = UINT32_C(0x174E); goto conv; + case 'M': case 'm': c = UINT32_C(0x174B); goto conv; + case 'N': case 'n': c = UINT32_C(0x1748); goto conv; + case 'P': case 'p': c = UINT32_C(0x1749); goto conv; + case 'R': case 'r': c = UINT32_C(0x174D); goto conv; + case 'S': case 's': c = UINT32_C(0x1750); goto conv; + case 'T': case 't': c = UINT32_C(0x1746); goto conv; + case 'Y': case 'y': c = UINT32_C(0x174C); goto conv; + case 'W': case 'w': c = UINT32_C(0x174F); goto conv; + default: + no_match: + *n += 1u; + break; + } + } +no_conv: + return LIBCHARCONV_NO_CONVERT; + +conv: + if (*n) + goto no_conv; +conv_again: + if (!slen) + return LIBCHARCONV_INDETERMINATE; + switch (s[1]) { + case 'A': case 'a': + if (*ncp >= 1u) + cp[0] = c; + *n += 2u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + case 'I': case 'i': + if (*ncp >= 1u) + cp[0] = c; + if (*ncp >= 2u) + cp[1] = UINT32_C(0x1752); + *n += 2u; + *ncp = 2u; + return LIBCHARCONV_CONVERTED; + case 'U': case 'u': + if (*ncp >= 1u) + cp[0] = c; + if (*ncp >= 2u) + cp[1] = UINT32_C(0x1753); + *n += 2u; + *ncp = 2u; + return LIBCHARCONV_CONVERTED; + case 'G': case 'g': + if (c == UINT32_C(0x1745)) + goto no_match; + if (s[0] != 'N' && s[0] != 'n') + goto no_match; + c = UINT32_C(0x1745); + *n += 1u; + slen--; + s++; + goto conv_again; + default: + goto no_match; + } + +conv1: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 1u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + +conv2: + if (*n) + goto no_conv; + if (*ncp) + *cp = c; + *n += 2u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; +} |
