diff options
author | dzwdz | 2023-06-08 19:52:43 +0200 |
---|---|---|
committer | dzwdz | 2023-06-08 19:52:43 +0200 |
commit | 668655053911072741883fd258c23e9d0668a853 (patch) | |
tree | 182d76120ba9a31926614f190237c5eac998b3a6 /src/user/lib | |
parent | 8c1d2e29b9ef3472b46d6997ffde5ca38afdb5f3 (diff) |
libc: move the strto* functions to stdlib.h, where they "belong"
Diffstat (limited to 'src/user/lib')
-rw-r--r-- | src/user/lib/include/stdlib.h | 5 | ||||
-rw-r--r-- | src/user/lib/include/string.h | 5 | ||||
-rw-r--r-- | src/user/lib/stdlib.c | 69 | ||||
-rw-r--r-- | src/user/lib/string/string.c | 68 |
4 files changed, 74 insertions, 73 deletions
diff --git a/src/user/lib/include/stdlib.h b/src/user/lib/include/stdlib.h index 4a44bf6..08362b1 100644 --- a/src/user/lib/include/stdlib.h +++ b/src/user/lib/include/stdlib.h @@ -24,3 +24,8 @@ int abs(int i); int atoi(const char *s); double atof(const char *s); + +long strtol(const char *restrict s, char **restrict end, int base); +unsigned long strtoul(const char *restrict s, char **restrict end, int base); +unsigned long long strtoull(const char *restrict s, char **restrict end, int base); +double strtod(const char *restrict s, char **restrict end); diff --git a/src/user/lib/include/string.h b/src/user/lib/include/string.h index 7a5400c..343664d 100644 --- a/src/user/lib/include/string.h +++ b/src/user/lib/include/string.h @@ -1,11 +1,6 @@ #pragma once #include <shared/mem.h> -// TODO move strto* to stdlib.h -long strtol(const char *restrict s, char **restrict end, int base); -unsigned long strtoul(const char *restrict s, char **restrict end, int base); -unsigned long long strtoull(const char *restrict s, char **restrict end, int base); -double strtod(const char *restrict s, char **restrict end); char *strchr(const char *s, int c); char *strrchr(const char *s, int c); diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c index 2d1f224..994521f 100644 --- a/src/user/lib/stdlib.c +++ b/src/user/lib/stdlib.c @@ -1,9 +1,10 @@ #include <_proc.h> +#include <bits/panic.h> #include <camellia.h> #include <camellia/syscalls.h> +#include <ctype.h> #include <errno.h> #include <string.h> -#include <bits/panic.h> _Noreturn void abort(void) { _sys_exit(1); @@ -66,3 +67,69 @@ double atof(const char *s) { (void)s; __libc_panic("unimplemented"); } + +static unsigned long long +strton(const char *restrict s, char **restrict end, int base, int *sign) +{ + long res = 0; + + while (isspace(*s)) s++; + + if (sign) *sign = 1; + if (*s == '+') { + s++; + } else if (*s == '-') { + s++; + if (sign) *sign = -1; + } + + if (base == 0) { + if (*s == '0') { + s++; + if (*s == 'x' || *s == 'X') { + s++; + base = 16; + } else { + base = 8; + } + } else { + base = 10; + } + } + + for (;;) { + unsigned char digit = *s; + if ('0' <= digit && digit <= '9') digit -= '0'; + else if ('a' <= digit && digit <= 'z') digit -= 'a' - 10; + else if ('A' <= digit && digit <= 'Z') digit -= 'A' - 10; + else break; + + if (digit >= base) break; + // TODO overflow check + res *= base; + res += digit; + + s++; + } + if (end) *end = (void*)s; + return res; +} + +long strtol(const char *restrict s, char **restrict end, int base) { + int sign; + long n = strton(s, end, base, &sign); + return n * sign; +} + +unsigned long strtoul(const char *restrict s, char **restrict end, int base) { + return strton(s, end, base, NULL); +} + +unsigned long long strtoull(const char *restrict s, char **restrict end, int base) { + return strton(s, end, base, NULL); +} + +double strtod(const char *restrict s, char **restrict end) { + (void)s; (void)end; + __libc_panic("unimplemented"); +} diff --git a/src/user/lib/string/string.c b/src/user/lib/string/string.c index 7058573..28ab523 100644 --- a/src/user/lib/string/string.c +++ b/src/user/lib/string/string.c @@ -1,75 +1,9 @@ #include <ctype.h> #include <errno.h> +#include <stdlib.h> #include <string.h> #include <strings.h> -static unsigned long long -strton(const char *restrict s, char **restrict end, int base, int *sign) -{ - long res = 0; - - while (isspace(*s)) s++; - - if (sign) *sign = 1; - if (*s == '+') { - s++; - } else if (*s == '-') { - s++; - if (sign) *sign = -1; - } - - if (base == 0) { - if (*s == '0') { - s++; - if (*s == 'x' || *s == 'X') { - s++; - base = 16; - } else { - base = 8; - } - } else { - base = 10; - } - } - - for (;;) { - unsigned char digit = *s; - if ('0' <= digit && digit <= '9') digit -= '0'; - else if ('a' <= digit && digit <= 'z') digit -= 'a' - 10; - else if ('A' <= digit && digit <= 'Z') digit -= 'A' - 10; - else break; - - if (digit >= base) break; - // TODO overflow check - res *= base; - res += digit; - - s++; - } - if (end) *end = (void*)s; - return res; -} - -long strtol(const char *restrict s, char **restrict end, int base) { - int sign; - long n = strton(s, end, base, &sign); - return n * sign; -} - -unsigned long strtoul(const char *restrict s, char **restrict end, int base) { - return strton(s, end, base, NULL); -} - -unsigned long long strtoull(const char *restrict s, char **restrict end, int base) { - return strton(s, end, base, NULL); -} - -#include <bits/panic.h> -double strtod(const char *restrict s, char **restrict end) { - (void)s; (void)end; - __libc_panic("unimplemented"); -} - char *strchr(const char *s, int c) { for (; *s; s++) { if (*s == c) return (char *)s; |