summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/lib/strtoul.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/lib/strtoul.c')
-rw-r--r--mdk-stage1/dietlibc/lib/strtoul.c32
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);
}