diff options
Diffstat (limited to 'libcharconv_box_drawing.c')
| -rw-r--r-- | libcharconv_box_drawing.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/libcharconv_box_drawing.c b/libcharconv_box_drawing.c new file mode 100644 index 0000000..0cba3bb --- /dev/null +++ b/libcharconv_box_drawing.c @@ -0,0 +1,52 @@ +/* See LICENSE file for copyright and license details. */ +#include "lib-common.h" + + +enum libcharconv_result +libcharconv_box_drawing(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) +{ + uint_least32_t a, c; + size_t i; + *n = 0; + for (; slen--; s++, ++*n) { + PLAIN_CASE_SELECT("/\\X", 0x2571); + if ('1' <= *s && *s <= '4') { + c = (uint_least32_t)1 << (*s - '1'); + for (i = 1u;; i++) { + if (slen < i) + goto indeterminate; + if ('1' <= s[i] && s[i] <= '4') { + a = (uint_least32_t)1 << (s[i] - '1'); + if (a & c) + goto next; + c |= a; + } else if (s[i] == 'O') { + c = (uint_least32_t)" \x00\x01\x07\x02\x04\x09\x0D\x03\x08\x05\x0C\x06\x0B\x0A\x0E"[c]; + c |= UINT32_C(0x1FBA0); + if (*n) + goto no_conv; + *n += i + 1u; + goto conv_prechecked; + } + } + } + next:; + } +no_conv: + return LIBCHARCONV_NO_CONVERT; + +indeterminate: + if (*n) + goto no_conv; + return LIBCHARCONV_INDETERMINATE; + +conv: + if (*n) + goto no_conv; + *n += 1u; +conv_prechecked: + if (*ncp) + *cp = c; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; +} |
