1 #include <u.h> 2 #include <libc.h> 3 4 #define UVLONG_MAX (1LL<<63) 5 6 uvlong 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