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