| /* |
| * strntoumax.c |
| * |
| * The strntoumax() function and associated |
| */ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <ctype.h> |
| |
| static inline int digitval(int ch) |
| { |
| if ( ch >= '0' && ch <= '9' ) { |
| return ch-'0'; |
| } else if ( ch >= 'A' && ch <= 'Z' ) { |
| return ch-'A'+10; |
| } else if ( ch >= 'a' && ch <= 'z' ) { |
| return ch-'a'+10; |
| } else { |
| return -1; |
| } |
| } |
| |
| uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) |
| { |
| int minus = 0; |
| uintmax_t v = 0; |
| int d; |
| |
| while ( n && isspace((unsigned char)*nptr) ) { |
| nptr++; |
| n--; |
| } |
| |
| /* Single optional + or - */ |
| if ( n && *nptr == '-' ) { |
| minus = 1; |
| nptr++; |
| n--; |
| } else if ( n && *nptr == '+' ) { |
| nptr++; |
| } |
| |
| if ( base == 0 ) { |
| if ( n >= 2 && nptr[0] == '0' && |
| (nptr[1] == 'x' || nptr[1] == 'X') ) { |
| n -= 2; |
| nptr += 2; |
| base = 16; |
| } else if ( n >= 1 && nptr[0] == '0' ) { |
| n--; |
| nptr++; |
| base = 8; |
| } else { |
| base = 10; |
| } |
| } else if ( base == 16 ) { |
| if ( n >= 2 && nptr[0] == '0' && |
| (nptr[1] == 'x' || nptr[1] == 'X') ) { |
| n -= 2; |
| nptr += 2; |
| } |
| } |
| |
| while ( n && (d = digitval(*nptr)) >= 0 && d < base ) { |
| v = v*base + d; |
| n--; |
| nptr++; |
| } |
| |
| if ( endptr ) |
| *endptr = (char *)nptr; |
| |
| return minus ? -v : v; |
| } |