#include "uucp.h"
#include <ctype.h>
#include <errno.h>
#if HAVE_LIMITS_H
#include <limits.h>
#else
#define ULONG_MAX 4294967295
#define LONG_MIN (- LONG_MAX - 1)
#define LONG_MAX 2147483647
#endif
#ifndef UNSIGNED
#define UNSIGNED 0
#endif
#if UNSIGNED
unsigned long int
#define strtol strtoul
#else
long int
#endif
strtol (nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
int negative;
register unsigned long int cutoff;
register unsigned int cutlim;
register unsigned long int i;
register const char *s;
register unsigned int c;
const char *save;
int overflow;
if (base < 0 || base == 1 || base > 36)
base = 10;
s = nptr;
while (isspace(BUCHAR (*s)))
++s;
if (*s == '\0')
goto noconv;
if (*s == '-')
{
negative = 1;
++s;
}
else if (*s == '+')
{
negative = 0;
++s;
}
else
negative = 0;
if (base == 16
&& s[0] == '0'
&& (s[1] == 'x' || s[1] == 'X'))
s += 2;
if (base == 0)
if (*s == '0')
{
if (s[1] == 'x' || s[1] == 'X')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
save = s;
cutoff = ULONG_MAX / (unsigned long int) base;
cutlim = ULONG_MAX % (unsigned long int) base;
overflow = 0;
i = 0;
for (c = BUCHAR (*s); c != '\0'; c = BUCHAR (*++s))
{
if (isdigit(c))
c -= '0';
else if (islower(c))
c = c - 'a' + 10;
else if (isupper(c))
c = c - 'A' + 10;
else
break;
if (c >= base)
break;
if (i > cutoff || (i == cutoff && c > cutlim))
overflow = 1;
else
{
i *= (unsigned long int) base;
i += c;
}
}
if (s == save)
goto noconv;
if (endptr != NULL)
*endptr = (char *) s;
#if !UNSIGNED
if (i > (negative ?
- (unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
overflow = 1;
#endif
if (overflow)
{
errno = ERANGE;
#if UNSIGNED
return ULONG_MAX;
#else
return negative ? LONG_MIN : LONG_MAX;
#endif
}
return (negative ? - i : i);
noconv:
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}