From 4e09bca9e34c226b6d7e34b4fa11248405fd988e Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Sun, 22 Oct 2023 19:50:38 +0200 Subject: Move everything into a new repo. --- userland/libc/stdlib/strtol.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 userland/libc/stdlib/strtol.c (limited to 'userland/libc/stdlib/strtol.c') diff --git a/userland/libc/stdlib/strtol.c b/userland/libc/stdlib/strtol.c new file mode 100644 index 0000000..7aa7760 --- /dev/null +++ b/userland/libc/stdlib/strtol.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +extern int errno; +extern int get_value(char c, long base); + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html +long strtol(const char *str, char **restrict endptr, int base) { + long ret_value = 0; + if (endptr) + *endptr = str; + // Ignore inital white-space sequence + for (; *str && isspace(*str); str++) + ; + if (!*str) + return ret_value; + + int sign = 0; + if ('-' == *str) { + // FIXME + sign = 1; + str++; + assert(0); + } else if ('+' == *str) { + str++; + } + + if (0 == base) { + // FIXME + assert(0); + } + + if (2 <= base && 36 >= base) { + for (; *str; str++) { + ret_value *= base; + int val = get_value(*str, base); + if (ret_value > LONG_MAX - val) { + errno = ERANGE; + return 0; + } + ret_value += val; + } + } else { + errno = EINVAL; + return 0; + } + if (endptr) + *endptr = str; + return ret_value; +} -- cgit v1.2.3