diff options
author | dzwdz | 2022-08-03 11:21:20 +0200 |
---|---|---|
committer | dzwdz | 2022-08-03 11:21:20 +0200 |
commit | 028cefb9b30240fa0bba6ff030076bd2158a66f4 (patch) | |
tree | 82e1b9ccc2146dd94a48796dfb978b66172d199c /src/user/lib | |
parent | a2a1e4bbfcda8c1314b592c8c940e96e95cb68d4 (diff) |
user/libc: isspace, strtol
Diffstat (limited to 'src/user/lib')
-rw-r--r-- | src/user/lib/include/string.h | 5 | ||||
-rw-r--r-- | src/user/lib/string.c | 51 |
2 files changed, 56 insertions, 0 deletions
diff --git a/src/user/lib/include/string.h b/src/user/lib/include/string.h index e5c0255..8930bee 100644 --- a/src/user/lib/include/string.h +++ b/src/user/lib/include/string.h @@ -1 +1,6 @@ +#pragma once #include <shared/mem.h> + +int isspace(char c); + +long strtol(const char *restrict s, char **restrict end, int base); diff --git a/src/user/lib/string.c b/src/user/lib/string.c new file mode 100644 index 0000000..77b996c --- /dev/null +++ b/src/user/lib/string.c @@ -0,0 +1,51 @@ +#include <errno.h> +#include <string.h> + +int isspace(char c) { + return c == ' ' || c == '\t' || c == '\n'; +} + +long strtol(const char *restrict s, char **restrict end, int base) { + long res = 0; + int sign = 1; + + while (isspace(*s)) s++; + + if (*s == '+') { + s++; + } else if (*s == '-') { + s++; + 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 * sign; +} |