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