aboutsummaryrefslogtreecommitdiffstats
path: root/libcharconv_clock_faces.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-01-24 23:09:46 +0100
committerMattias Andrée <m@maandree.se>2026-01-24 23:09:46 +0100
commitac73d14281056314aa8e1b0d3c6ade0a527aad0a (patch)
tree7e2c78b8322c00aa11a01e8ea27a15dd04106454 /libcharconv_clock_faces.c
parentAdd domino tiles (diff)
downloadcharconv-ac73d14281056314aa8e1b0d3c6ade0a527aad0a.tar.gz
charconv-ac73d14281056314aa8e1b0d3c6ade0a527aad0a.tar.bz2
charconv-ac73d14281056314aa8e1b0d3c6ade0a527aad0a.tar.xz
Add clock faces
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libcharconv_clock_faces.c')
-rw-r--r--libcharconv_clock_faces.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/libcharconv_clock_faces.c b/libcharconv_clock_faces.c
new file mode 100644
index 0000000..cd49b53
--- /dev/null
+++ b/libcharconv_clock_faces.c
@@ -0,0 +1,65 @@
+/* See LICENSE file for copyright and license details. */
+#include "lib-common.h"
+
+
+enum libcharconv_result
+libcharconv_clock_faces(const char *s, size_t slen, size_t *n, uint_least32_t *cp, size_t *ncp)
+{
+ int num, thirty;
+ *n = 0;
+ for (; slen--; s++) {
+ if ('0' <= s[0] && s[0] <= '9') {
+ if (*n)
+ goto no_conv;
+ num = (int)(s[0] - '0');
+ if (!slen--)
+ goto indeterminate;
+ *n = 2u;
+ if (s[1] == ':')
+ goto conv;
+ if ('0' > s[1] || s[1] > '9')
+ goto no_conv;
+ num *= 10;
+ num += (int)(s[1] - '0');
+ if (!slen--)
+ goto indeterminate;
+ if (num > 24)
+ goto no_conv;
+ *n = 3u;
+ if (s[2] == ':')
+ goto conv;
+ goto no_conv;
+ } else {
+ *n += 1u;
+ }
+ }
+no_conv:
+ return LIBCHARCONV_NO_CONVERT;
+
+indeterminate:
+ return LIBCHARCONV_INDETERMINATE;
+
+conv:
+ if (!slen--)
+ goto indeterminate;
+ if (s[*n] == '3')
+ thirty = 1;
+ else if (s[*n] == '0')
+ thirty = 0;
+ else
+ goto no_conv;
+ if (!slen--)
+ goto indeterminate;
+ if (s[*n + 1u] != '0')
+ goto no_conv;
+ *n += 2u;
+ if (num > (thirty ? 23 : 34))
+ goto no_conv;
+ num %= 12;
+ num = (!num ? 12 : num) - 1;
+ num += 12 * thirty;
+ if (*ncp)
+ *cp = UINT32_C(0x1F550) + (uint_least32_t)num;
+ *ncp = 1u;
+ return LIBCHARCONV_CONVERTED;
+}