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