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