diff options
Diffstat (limited to '')
| -rw-r--r-- | libcharconv_control_characters.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/libcharconv_control_characters.c b/libcharconv_control_characters.c index 55e4bbf..c45f03e 100644 --- a/libcharconv_control_characters.c +++ b/libcharconv_control_characters.c @@ -132,6 +132,21 @@ libcharconv_control_characters(const char *s, size_t slen, size_t *n, uint_least int indeterminate; *n = 0; for (; slen; s++, slen--, ++*n) { + if (s[0] == '\xE2') { + if (slen == 1u) + return LIBCHARCONV_INDETERMINATE; + if (s[1] != '\x90') + goto search; + if (slen == 2u) + return LIBCHARCONV_INDETERMINATE; + i = ((const unsigned char *)s)[2]; + if (0x80u > i || i > 0xA1u) + goto search; + i &= 0x3Fu; + i = i == 0x21u ? 0x7Fu : i; + goto conv_repr; + } + search: indeterminate = 0; found = SIZE_MAX; found_len = 0u; @@ -158,6 +173,15 @@ libcharconv_control_characters(const char *s, size_t slen, size_t *n, uint_least no_conv: return LIBCHARCONV_NO_CONVERT; +conv_repr: + if (*n) + goto no_conv; + if (*ncp) + *cp = (uint_least32_t)i; + *n += 3u; + *ncp = 1u; + return LIBCHARCONV_CONVERTED; + conv: if (*n) goto no_conv; |
