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