diff options
Diffstat (limited to 'mdk-stage1/dietlibc/lib/strtoul.c')
-rw-r--r-- | mdk-stage1/dietlibc/lib/strtoul.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/mdk-stage1/dietlibc/lib/strtoul.c b/mdk-stage1/dietlibc/lib/strtoul.c index 3f93962a9..e9c09fb59 100644 --- a/mdk-stage1/dietlibc/lib/strtoul.c +++ b/mdk-stage1/dietlibc/lib/strtoul.c @@ -1,32 +1,44 @@ #include <ctype.h> - -/* static char *num="0123456789abcdefghijklmnopqrstuvwxyz"; */ +#include "dietfeatures.h" +#include <errno.h> +#include <limits.h> +#include <stdlib.h> unsigned long int strtoul(const char *nptr, char **endptr, int base) { - long int v=0; + int neg = 0; + unsigned long int v=0; while(isspace(*nptr)) ++nptr; - + if (*nptr == '-') { neg=1; nptr++; } if (*nptr == '+') ++nptr; + if (base==16 && nptr[0]=='0') goto skip0x; if (!base) { if (*nptr=='0') { base=8; - if ((*(nptr+1)=='x')||(*(nptr+1)=='X')) { +skip0x: + if (nptr[1]=='x'||nptr[1]=='X') { nptr+=2; base=16; } - } - else + } else base=10; } while(*nptr) { register unsigned char c=*nptr; - c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c-'0'); + c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c<='9'?c-'0':0xff); if (c>=base) break; - v=v*base+c; + { + register unsigned long int w=v*base; + if (w<v) { + errno=ERANGE; + return ULONG_MAX; + } + v=w+c; + } ++nptr; } if (endptr) *endptr=(char *)nptr; - return v; + errno=0; /* in case v==ULONG_MAX, ugh! */ + return (neg?-v:v); } |