/* See LICENSE file for copyright and license details. */ #include "lib-common.h" enum libcharconv_result libcharconv_variation_selectors(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp) { enum libcharconv_result ret = LIBCHARCONV_CONVERTED; uint_least32_t c; *n = 0; for (; slen--; s++) { if ('1' <= s[0] && s[0] <= '9') { c = (uint_least32_t)(s[0] - '0'); if (!slen--) goto conv_if_end; if ('0' > s[1] || s[1] > '9') goto conv; c *= 10u; c += (uint_least32_t)(s[1] - '0'); if (!slen--) goto conv_if_end; if ('0' > s[2] || s[2] > '9') goto conv; c *= 10u; c += (uint_least32_t)(s[2] - '0'); if (c > 256u) { c /= 10u; goto conv; } goto conv; } else { *n += 1u; break; } } no_conv: return LIBCHARCONV_NO_CONVERT; conv_if_end: ret = LIBCHARCONV_CONVERT_IF_END; conv: if (*n) goto no_conv; *n = c < 10u ? 1u : c < 100u ? 2u : 3u; if (c < 17u) c = UINT32_C(0xFE00) + (c - 1u); else c = UINT32_C(0xE0100) + (c - 17u); if (*ncp) *cp = c; *ncp = 1u; return ret; }