Prepare new maemo release
[maemo-rb.git] / apps / plugins / lua / strtoul.c
blob74d9b4bb09ae940da52768123ae0943f95d77585
1 #include "rocklibc.h"
3 unsigned long int strtoul(const char *ptr, char **endptr, int base)
5 int neg = 0, overflow = 0;
6 unsigned long int v=0;
7 const char* orig;
8 const char* nptr=ptr;
10 while(isspace(*nptr)) ++nptr;
12 if (*nptr == '-') { neg=1; nptr++; }
13 else if (*nptr == '+') ++nptr;
14 orig=nptr;
15 if (base==16 && nptr[0]=='0') goto skip0x;
16 if (base) {
17 register unsigned int b=base-2;
18 if (__unlikely(b>34)) { errno=EINVAL; return 0; }
19 } else {
20 if (*nptr=='0') {
21 base=8;
22 skip0x:
23 if ((nptr[1]=='x'||nptr[1]=='X') && isxdigit(nptr[2])) {
24 nptr+=2;
25 base=16;
27 } else
28 base=10;
30 while(__likely(*nptr)) {
31 register unsigned char c=*nptr;
32 c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c<='9'?c-'0':0xff);
33 if (__unlikely(c>=base)) break; /* out of base */
35 register unsigned long x=(v&0xff)*base+c;
36 register unsigned long w=(v>>8)*base+(x>>8);
37 if (w>(ULONG_MAX>>8)) overflow=1;
38 v=(w<<8)+(x&0xff);
40 ++nptr;
42 if (__unlikely(nptr==orig)) { /* no conversion done */
43 nptr=ptr;
44 errno=EINVAL;
45 v=0;
47 if (endptr) *endptr=(char *)nptr;
48 if (overflow) {
49 errno=ERANGE;
50 return ULONG_MAX;
52 return (neg?-v:v);