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