#include "tclInt.h"
#include "tclPort.h"
static char cvtIn[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
100, 100, 100, 100, 100, 100, 100,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35,
100, 100, 100, 100, 100, 100,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35};
unsigned long int
strtoul(string, endPtr, base)
CONST char *string;
char **endPtr;
int base;
{
register CONST char *p;
register unsigned long int result = 0;
register unsigned digit;
int anyDigits = 0;
int negative=0;
int overflow=0;
p = string;
while (isspace(UCHAR(*p))) {
p += 1;
}
if (*p == '-') {
negative = 1;
p += 1;
} else {
if (*p == '+') {
p += 1;
}
}
if (base == 0)
{
if (*p == '0') {
p += 1;
if ((*p == 'x') || (*p == 'X')) {
p += 1;
base = 16;
} else {
anyDigits = 1;
base = 8;
}
}
else base = 10;
} else if (base == 16) {
if ((p[0] == '0') && ((p[1] == 'x') || (p[1] == 'X'))) {
p += 2;
}
}
if (base == 8) {
unsigned long maxres = ULONG_MAX >> 3;
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > 7) {
break;
}
if (result > maxres) { overflow = 1; }
result = (result << 3);
if (digit > (ULONG_MAX - result)) { overflow = 1; }
result += digit;
anyDigits = 1;
}
} else if (base == 10) {
unsigned long maxres = ULONG_MAX / 10;
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > 9) {
break;
}
if (result > maxres) { overflow = 1; }
result *= 10;
if (digit > (ULONG_MAX - result)) { overflow = 1; }
result += digit;
anyDigits = 1;
}
} else if (base == 16) {
unsigned long maxres = ULONG_MAX >> 4;
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > ('z' - '0')) {
break;
}
digit = cvtIn[digit];
if (digit > 15) {
break;
}
if (result > maxres) { overflow = 1; }
result = (result << 4);
if (digit > (ULONG_MAX - result)) { overflow = 1; }
result += digit;
anyDigits = 1;
}
} else if ( base >= 2 && base <= 36 ) {
unsigned long maxres = ULONG_MAX / base;
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > ('z' - '0')) {
break;
}
digit = cvtIn[digit];
if (digit >= ( (unsigned) base )) {
break;
}
if (result > maxres) { overflow = 1; }
result *= base;
if (digit > (ULONG_MAX - result)) { overflow = 1; }
result += digit;
anyDigits = 1;
}
}
if (!anyDigits) {
p = string;
}
if (endPtr != 0) {
*endPtr = (char *) p;
}
if (overflow) {
errno = ERANGE;
return ULONG_MAX;
}
if (negative) {
return -result;
}
return result;
}