summaryrefslogtreecommitdiff
path: root/kernel/lib/strtox.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-08 10:39:48 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-08 10:39:48 -0400
commit8a19547957a86bed3f58c9abc1ac218d04698faf (patch)
treeed7ccc6f3a8902915dfe6c9bf763fc45d752b3c4 /kernel/lib/strtox.c
parentfmt (diff)
downloadcomus-8a19547957a86bed3f58c9abc1ac218d04698faf.tar.gz
comus-8a19547957a86bed3f58c9abc1ac218d04698faf.tar.bz2
comus-8a19547957a86bed3f58c9abc1ac218d04698faf.zip
break apart c libaray
Diffstat (limited to 'kernel/lib/strtox.c')
-rw-r--r--kernel/lib/strtox.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/kernel/lib/strtox.c b/kernel/lib/strtox.c
new file mode 100644
index 0000000..620b8d3
--- /dev/null
+++ b/kernel/lib/strtox.c
@@ -0,0 +1,52 @@
+#include <lib.h>
+
+#define STRTOX(name, type) \
+ type name(const char *restrict s, char **restrict endptr, int radix) \
+ { \
+ const char *s_start = s; \
+ for (; isspace(*s); s++) \
+ ; \
+ \
+ int sign = 0; \
+ switch (*s) { \
+ case '-': \
+ sign = 1; /* fallthrough */ \
+ case '+': \
+ s++; \
+ break; \
+ } \
+ \
+ if ((radix == 0 || radix == 16) && \
+ (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))) { \
+ radix = 16; \
+ s += 2; \
+ } else if (radix == 0) { \
+ if (*s == '0') { \
+ radix = 8; \
+ s++; \
+ } else { \
+ radix = 10; \
+ } \
+ } \
+ \
+ type num = 0; \
+ int has_digit = 0; \
+ \
+ while (1) { \
+ int n = ctoi(*s++); \
+ if (n < 0 || n >= radix) \
+ break; \
+ has_digit = 1; \
+ num = num * radix + n; \
+ } \
+ \
+ if (endptr != NULL) { \
+ *endptr = has_digit ? (char *)(s - 1) : (char *)s_start; \
+ } \
+ \
+ return sign ? -num : num; \
+ }
+
+STRTOX(strtoi, int)
+STRTOX(strtol, long int)
+STRTOX(strtoll, long long int)