1 #include <lib9.h> 2 3 #define LONG_MAX 2147483647L 4 #define LONG_MIN -2147483648L 5 6 long 7 strtol(char *nptr, char **endptr, int base) 8 { 9 char *p; 10 long n, nn; 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 if(*p != '0') 47 base = 10; 48 else{ 49 base = 8; 50 if(p[1]=='x' || p[1]=='X'){ 51 p += 2; 52 base = 16; 53 } 54 } 55 }else if(base==16 && *p=='0'){ 56 if(p[1]=='x' || p[1]=='X') 57 p += 2; 58 }else if(base<0 || 36<base) 59 goto Return; 60 61 /* 62 * Non-empty sequence of digits 63 */ 64 for(;; p++,ndig++){ 65 c = *p; 66 v = base; 67 if('0'<=c && c<='9') 68 v = c - '0'; 69 else if('a'<=c && c<='z') 70 v = c - 'a' + 10; 71 else if('A'<=c && c<='Z') 72 v = c - 'A' + 10; 73 if(v >= base) 74 break; 75 nn = n*base + v; 76 if(nn < n) 77 ovfl = 1; 78 n = nn; 79 } 80 81 Return: 82 if(ndig == 0) 83 p = nptr; 84 if(endptr) 85 *endptr = p; 86 if(ovfl){ 87 if(neg) 88 return LONG_MIN; 89 return LONG_MAX; 90 } 91 if(neg) 92 return -n; 93 return n; 94 } 95