aboutsummaryrefslogtreecommitdiffstats
path: root/libcharconv_control_characters.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-25 21:03:48 +0100
committerMattias Andrée <m@maandree.se>2026-01-25 21:03:48 +0100
commitb710c7eb580d8f291bee9bc760d806ec305f26b2 (patch)
tree30f50ee2832a80d37a4a9615ccec543bdfd6a79b /libcharconv_control_characters.c
parentlatin: do not covert LF and SP to text (diff)
downloadcharconv-b710c7eb580d8f291bee9bc760d806ec305f26b2.tar.gz
charconv-b710c7eb580d8f291bee9bc760d806ec305f26b2.tar.bz2
charconv-b710c7eb580d8f291bee9bc760d806ec305f26b2.tar.xz
Add control character representations
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--libcharconv_control_characters.c24
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;