2 This source code was extracted from the Q8 package created and
3 placed in the PUBLIC DOMAIN by Doug Gwyn <gwyn@arl.mil>
4 last edit: 1999/11/05 gwyn@arl.mil
6 Implements subclause 7.8.2 of ISO/IEC 9899:1999 (E).
8 This particular implementation requires the matching <inttypes.h>.
9 It also assumes that character codes for A..Z and a..z are in
10 contiguous ascending order; this is true for ASCII but not EBCDIC.
19 /* convert digit character to number, in any base */
20 #define ToNumber(c) (isdigit(c) ? (c) - '0' : \
21 isupper(c) ? (c) - 'A' + 10 : \
22 islower(c) ? (c) - 'a' + 10 : \
23 -1 /* "invalid" flag */ \
25 /* validate converted digit character for specific base */
26 #define valid(n, b) ((n) >= 0 && (n) < (b))
29 strtoumax(nptr, endptr, base)
30 register const char * __restrict__ nptr;
31 char ** __restrict__ endptr;
34 register uintmax_t accum; /* accumulates converted value */
35 register uintmax_t next; /* for computing next value of accum */
36 register int n; /* numeral from digit character */
37 int minus; /* set iff minus sign seen (yes!) */
38 int toobig; /* set iff value overflows */
41 *endptr = (char *)nptr; /* in case no conversion's performed */
43 if ( base < 0 || base == 1 || base > 36 )
46 return 0; /* unspecified behavior */
49 /* skip initial, possibly empty sequence of white-space characters */
51 while ( isspace(*nptr) )
54 /* process subject sequence: */
56 /* optional sign (yes!) */
58 if ( (minus = *nptr == '-') || *nptr == '+' )
65 if ( nptr[1] == 'X' || nptr[1] == 'x' )
74 /* optional "0x" or "0X" for base 16 */
76 if ( base == 16 && *nptr == '0' && (nptr[1] == 'X' || nptr[1] == 'x') )
77 nptr += 2; /* skip past this prefix */
79 /* check whether there is at least one valid digit */
84 if ( !valid(n, base) )
85 return 0; /* subject seq. not of expected form */
89 for ( toobig = 0; n = ToNumber(*nptr), valid(n, base); ++nptr )
90 if ( accum > UINTMAX_MAX / base + 1 /* major wrap-around */
91 || (next = base * accum + n) < accum /* minor wrap-around */
93 toobig = 1; /* but keep scanning */
98 *endptr = (char *)nptr; /* points to first not-valid-digit */
106 return minus ? -accum : accum; /* (yes!) */
109 unsigned long long __attribute__ ((alias ("strtoumax")))
110 strtoull (const char* __restrict__ nptr, char ** __restrict__ endptr, int base);