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