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