1 #include <lib9.h>
2
3 #define ULONG_MAX 4294967295UL
4
5 ulong
strtoul(char * nptr,char ** endptr,int base)6 strtoul(char *nptr, char **endptr, int base)
7 {
8 char *p;
9 ulong n, nn, m;
10 int c, ovfl, neg, v, ndig;
11
12 p = (char*)nptr;
13 neg = 0;
14 n = 0;
15 ndig = 0;
16 ovfl = 0;
17
18 /*
19 * White space
20 */
21 for(;;p++){
22 switch(*p){
23 case ' ':
24 case '\t':
25 case '\n':
26 case '\f':
27 case '\r':
28 case '\v':
29 continue;
30 }
31 break;
32 }
33
34 /*
35 * Sign
36 */
37 if(*p=='-' || *p=='+')
38 if(*p++ == '-')
39 neg = 1;
40
41 /*
42 * Base
43 */
44 if(base==0){
45 if(*p != '0')
46 base = 10;
47 else{
48 base = 8;
49 if(p[1]=='x' || p[1]=='X')
50 base = 16;
51 }
52 }
53 if(base<2 || 36<base)
54 goto Return;
55 if(base==16 && *p=='0'){
56 if(p[1]=='x' || p[1]=='X')
57 if(('0' <= p[2] && p[2] <= '9')
58 ||('a' <= p[2] && p[2] <= 'f')
59 ||('A' <= p[2] && p[2] <= 'F'))
60 p += 2;
61 }
62 /*
63 * Non-empty sequence of digits
64 */
65 n = 0;
66 m = ULONG_MAX/base;
67 for(;; p++,ndig++){
68 c = *p;
69 v = base;
70 if('0'<=c && c<='9')
71 v = c - '0';
72 else if('a'<=c && c<='z')
73 v = c - 'a' + 10;
74 else if('A'<=c && c<='Z')
75 v = c - 'A' + 10;
76 if(v >= base)
77 break;
78 if(n > m)
79 ovfl = 1;
80 nn = n*base + v;
81 if(nn < n)
82 ovfl = 1;
83 n = nn;
84 }
85
86 Return:
87 if(ndig == 0)
88 p = nptr;
89 if(endptr)
90 *endptr = p;
91 if(ovfl)
92 return ULONG_MAX;
93 if(neg)
94 return -n;
95 return n;
96 }
97