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