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