scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 14293d43ec4d596e274d79f3ccc62860a40237c4
parent 48b33264a0393fa640f1341ee6f4658b12dbb867
Author: Quentin Rameau <quinq@fifth.space>
Date:   Sun, 23 Dec 2018 17:41:39 +0100

[libc] Add strtoul

Diffstat:
Msrc/libc/stdlib/Makefile | 1+
Asrc/libc/stdlib/strtoul.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/src/libc/stdlib/Makefile b/src/libc/stdlib/Makefile @@ -19,6 +19,7 @@ OBJS = abort.o\ qsort.o\ rand.o\ realloc.o\ + strtoul.o\ strtoull.o\ all: $(OBJS) diff --git a/src/libc/stdlib/strtoul.c b/src/libc/stdlib/strtoul.c @@ -0,0 +1,64 @@ +#include <ctype.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +#undef strtoul + +unsigned long +strtoul(const char *s, char **end, int base) +{ + int d, sign = 1; + unsigned long n; + static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *t, *p; + + while (isspace(*s)) + ++s; + + switch (*s) { + case '-': + sign = -1; + case '+': + ++s; + } + + if (base == 0) { + if (*s == '0' && toupper(s[1]) == 'X') + base = 16; + else if (*s == '0') + base = 8; + else + base = 10; + } + + if (base == 16 && *s == '0' && toupper(s[1]) == 'X') + s += 2; + + n = 0; + for (t = s; p = strchr(digits, toupper(*t)); ++t) { + if ((d = p - digits) >= base) + break; + if (n > ULONG_MAX/base) + goto overflow; + n *= base; + if (d > ULONG_MAX - n) + goto overflow; + n += d; + } + + + if (end) + *end = t; + if (n == 0 && s == t) + errno = EINVAL; + return n*sign; + +overflow: + if (end) + *end = t; + errno = ERANGE; + + return ULONG_MAX; +}