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