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