strtoul.c (851B)
1 #include <ctype.h> 2 #include <errno.h> 3 #include <limits.h> 4 #include <stdlib.h> 5 #include <string.h> 6 7 #include "../libc.h" 8 9 #undef strtoul 10 11 unsigned long 12 strtoul(const char * restrict ptr, char ** restrict end, int base) 13 { 14 int d, sign = 1; 15 unsigned long n; 16 char *t, *s = (char *) ptr; 17 18 if (end) 19 *end = s; 20 21 while (isspace(*s)) 22 ++s; 23 24 switch (*s) { 25 case '-': 26 sign = -1; 27 case '+': 28 ++s; 29 } 30 31 if (base == 0) { 32 if (*s == '0') 33 base = toupper(s[1]) == 'X' ? 16 : 8; 34 else 35 base = 10; 36 } 37 if (base == 16 && *s == '0' && toupper(s[1]) == 'X') 38 s += 2; 39 40 n = 0; 41 for (t = s; (d = _dtoi(*t)) < base; ++t) { 42 if (n > ULONG_MAX/base) 43 goto overflow; 44 n *= base; 45 if (d > ULONG_MAX - n) 46 goto overflow; 47 n += d; 48 } 49 50 if (end && t != s) 51 *end = t; 52 53 return n*sign; 54 55 overflow: 56 if (end) 57 *end = t; 58 errno = ERANGE; 59 60 return ULONG_MAX; 61 }