aboutsummaryrefslogtreecommitdiffstats
path: root/libcharconv_bracketed.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-24 17:27:23 +0100
committerMattias Andrée <m@maandree.se>2026-01-24 17:27:23 +0100
commitbe3e7dec7e19a8ddc527a188306c097900a6da99 (patch)
tree094d0c9bd936dc1c5853210f3ae94455b670748d /libcharconv_bracketed.c
parentMake UTF-8 decoding function available to the entire library (diff)
downloadcharconv-be3e7dec7e19a8ddc527a188306c097900a6da99.tar.gz
charconv-be3e7dec7e19a8ddc527a188306c097900a6da99.tar.bz2
charconv-be3e7dec7e19a8ddc527a188306c097900a6da99.tar.xz
Add bracketed
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libcharconv_bracketed.c')
-rw-r--r--libcharconv_bracketed.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/libcharconv_bracketed.c b/libcharconv_bracketed.c
new file mode 100644
index 0000000..cff49c9
--- /dev/null
+++ b/libcharconv_bracketed.c
@@ -0,0 +1,141 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+enum libcharconv_result
+libcharconv_bracketed(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++) {
+ if ('0' <= s[0] && s[0] <= '9') {
+ if (!slen)
+ goto indeterminate;
+ if (s[1] == ',') {
+ c = UINT32_C(0x1F101) + (unsigned)(s[0] - '0');
+ goto conv2;
+ } else if (s[1] == '.') {
+ if (s[0] == '0')
+ c = UINT32_C(0x1F100);
+ else
+ c = UINT32_C(0x2488) + (unsigned)(s[0] - '1');
+ goto conv2;
+ } else if (s[0] == '1' && '0' <= s[1] && s[1] <= '9') {
+ if (slen < 2u)
+ goto indeterminate;
+ if (s[2] == '.')
+ c = UINT32_C(0x2491) + (unsigned)(s[1] - '0');
+ else
+ goto no_match;
+ goto conv3;
+ } else if (s[0] == '2' && s[1] == '0') {
+ if (slen < 2u)
+ goto indeterminate;
+ if (s[2] == '.')
+ c = UINT32_C(0x249B);
+ else
+ goto no_match;
+ goto conv3;
+ } else {
+ goto no_match;
+ }
+ } else if (s[0] == '(') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[1] == '1') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[2] == ')') {
+ c = UINT32_C(0x2474);
+ goto conv3;
+ } else if ('0' <= s[2] && s[2] <= '9') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[3] != ')')
+ goto no_match;
+ c = UINT32_C(0x247D) + (unsigned)(s[2] - '0');
+ goto conv4;
+ } else {
+ goto no_match;
+ }
+ } else if (s[1] == '2') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[2] == ')') {
+ c = UINT32_C(0x2475);
+ goto conv3;
+ } else if (s[2] == '0') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[3] != ')')
+ goto no_match;
+ c = UINT32_C(0x2487);
+ goto conv4;
+ } else {
+ goto no_match;
+ }
+ } else if ('3' <= s[1] && s[1] <= '9') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[2] != ')')
+ goto no_match;
+ c = UINT32_C(0x2474) + (unsigned)(s[1] - '0');
+ goto conv3;
+ } else if ('a' <= s[1] && s[1] <= 'z') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[2] != ')')
+ goto no_match;
+ c = UINT32_C(0x249C) + (unsigned)(s[1] - 'a');
+ goto conv3;
+ } else if ('A' <= s[1] && s[1] <= 'Z') {
+ if (!slen--)
+ goto indeterminate;
+ if (s[2] != ')')
+ goto no_match;
+ c = UINT32_C(0x1F110) + (unsigned)(s[1] - 'A');
+ goto conv3;
+ } else {
+ goto no_match;
+ }
+ } else {
+ no_match:
+ *n += 1u;
+ break;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+indeterminate:
+ if (*n)
+ goto no_conv;
+ return LIBCHARCONV_INDETERMINATE;
+
+conv2:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 2u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+
+conv3:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 3u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+
+conv4:
+ if (*n)
+ goto no_conv;
+ if (*ncp)
+ *cp = c;
+ *n += 4u;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}