2 This source code was extracted from the Q8 package created and
3 placed in the PUBLIC DOMAIN by Doug Gwyn <gwyn@arl.mil>
5 last edit: 1999/11/05 gwyn@arl.mil
7 Implements subclause 7.8.2 of ISO/IEC 9899:1999 (E).
9 This particular implementation requires the matching <inttypes.h>.
10 It also assumes that character codes for A..Z and a..z are in
11 contiguous ascending order; this is true for ASCII but not EBCDIC.
19 /* convert digit wide character to number, in any base */
21 #define ToWNumber(c) (iswdigit(c) ? (c) - L'0' : \
22 iswupper(c) ? (c) - L'A' + 10 : \
23 iswlower(c) ? (c) - L'a' + 10 : \
24 -1 /* "invalid" flag */ \
27 /* validate converted digit character for specific base */
28 #define valid(n, b) ((n) >= 0 && (n) < (b))
31 wcstoimax(nptr, endptr, base)
32 register const wchar_t * __restrict__ nptr;
33 wchar_t ** __restrict__ endptr;
36 register uintmax_t accum; /* accumulates converted value */
37 register int n; /* numeral from digit character */
38 int minus; /* set iff minus sign seen */
39 int toobig; /* set iff value overflows */
42 *endptr = (wchar_t *)nptr; /* in case no conv performed */
44 if ( base < 0 || base == 1 || base > 36 )
47 return 0; /* unspecified behavior */
50 /* skip initial, possibly empty sequence of white-space w.characters */
52 while ( iswspace(*nptr) )
55 /* process subject sequence: */
59 if ( (minus = *nptr == L'-') || *nptr == L'+' )
66 if ( nptr[1] == L'X' || nptr[1] == L'x' )
74 /* optional "0x" or "0X" for base 16 */
76 if ( base == 16 && *nptr == L'0'
77 && (nptr[1] == L'X' || nptr[1] == L'x')
79 nptr += 2; /* skip past this prefix */
81 /* check whether there is at least one valid digit */
86 if ( !valid(n, base) )
87 return 0; /* subject seq. not of expected form */
91 for ( toobig = 0; n = ToWNumber(*nptr), valid(n, base); ++nptr )
92 if ( accum > (uintmax_t)(INTMAX_MAX / base + 2) ) /* major wrap-around */
93 toobig = 1; /* but keep scanning */
95 accum = base * accum + n;
98 *endptr = (wchar_t *)nptr; /* -> first not-valid-digit */
102 if ( accum > (uintmax_t)INTMAX_MAX + 1 )
106 if ( accum > (uintmax_t)INTMAX_MAX )
112 return minus ? INTMAX_MIN : INTMAX_MAX;
115 return (intmax_t)(minus ? -accum : accum);
118 long long __attribute__ ((alias ("wcstoimax")))
119 wcstoll (const wchar_t* __restrict__ nptr, wchar_t ** __restrict__ endptr, int base);