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