8 unsigned long __fastcall__ strtoul (const char* nptr, char** endptr, int base)
9 /* Convert a string to a long unsigned int */
11 register const char* S = nptr;
12 unsigned long Val = 0;
13 unsigned char Minus = 0;
14 unsigned char Ovf = 0;
15 unsigned CvtCount = 0;
16 unsigned char DigitVal;
18 unsigned char MaxDigit;
21 /* Skip white space */
22 while (isspace (*S)) {
26 /* Check for leading + or - sign */
35 /* If base is zero, we may have a 0 or 0x prefix. If base is 16, we may
41 if (*S == 'x' || *S == 'X') {
50 } else if (base == 16 && *S == '0' && (S[1] == 'x' || S[1] == 'X')) {
54 /* Determine the maximum valid number and (if the number is equal to this
55 * value) the maximum valid digit.
57 MaxDigit = ULONG_MAX % base;
58 MaxVal = ULONG_MAX / base;
60 /* Convert the number */
63 /* Convert the digit into a numeric value */
66 } else if (isupper (*S)) {
67 DigitVal = *S - ('A' - 10);
68 } else if (islower (*S)) {
69 DigitVal = *S - ('a' - 10);
71 /* Unknown character */
75 /* Don't accept a character that doesn't match base */
76 if (DigitVal >= base) {
80 /* Don't accept anything that makes the final value invalid */
81 if (Val > MaxVal || (Val == MaxVal && DigitVal > MaxDigit)) {
85 /* Calculate the next value if digit is not invalid */
87 Val = (Val * base) + DigitVal;
91 /* Next character from input */
95 /* Store the end pointer. If no conversion was performed, the value of
96 * nptr is returned in endptr.
100 *endptr = (char*) S - 1;
102 *endptr = (char*) nptr;
106 /* Handle overflow */
112 /* Return the result */
114 return (unsigned long) -(long)Val;