strtoimax.c (996B)
1 #include <ctype.h> 2 #include <errno.h> 3 #include <inttypes.h> 4 #include <limits.h> 5 #include <stdlib.h> 6 7 #include "../libc.h" 8 9 #undef strtoimax 10 11 intmax_t 12 strtoimax(const char * restrict ptr, char ** restrict end, int base) 13 { 14 int d, sign = -1; 15 intmax_t 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 /* Compute n as a negative number to avoid overflow on LONG_MIN */ 42 for (t = s; (d = _dtoi(*t)) < base; ++t) { 43 if (n < INTMAX_MIN/base) 44 goto overflow; 45 n *= base; 46 if (-d < INTMAX_MIN - n) 47 goto overflow; 48 n -= d; 49 if (n == INTMAX_MIN && sign < 0) 50 goto overflow; 51 } 52 53 if (end && t != s) 54 *end = t; 55 56 return n*sign; 57 58 overflow: 59 if (end) 60 *end = t; 61 errno = ERANGE; 62 63 return sign < 0 ? INTMAX_MAX : INTMAX_MIN; 64 }