1 #include <stdlib.h>
2 #include <limits.h>
3 #include <errno.h>
4
5 long
strtol(const char * nptr,char ** endptr,int base)6 strtol(const char *nptr, char **endptr, int base)
7 {
8 const char *p;
9 long n, nn;
10 int c, ovfl, v, neg, ndig;
11
12 p = 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 p += 2;
51 base = 16;
52 }
53 }
54 }else if(base==16 && *p=='0'){
55 if(p[1]=='x' || p[1]=='X')
56 p += 2;
57 }else if(base<0 || 36<base)
58 goto Return;
59
60 /*
61 * Non-empty sequence of digits
62 */
63 for(;; p++,ndig++){
64 c = *p;
65 v = base;
66 if('0'<=c && c<='9')
67 v = c - '0';
68 else if('a'<=c && c<='z')
69 v = c - 'a' + 10;
70 else if('A'<=c && c<='Z')
71 v = c - 'A' + 10;
72 if(v >= base)
73 break;
74 nn = n*base + v;
75 if(nn < n)
76 ovfl = 1;
77 n = nn;
78 }
79
80 Return:
81 if(ndig == 0)
82 p = nptr;
83 if(endptr)
84 *endptr = (char *)p;
85 if(ovfl){
86 errno = ERANGE;
87 if(neg)
88 return LONG_MIN;
89 return LONG_MAX;
90 }
91 if(neg)
92 return -n;
93 return n;
94 }
95