#if defined(_KERNEL)
#include <sys/null.h>
#endif
#if defined(_KERNEL) && !defined(_BOOT)
#include <sys/errno.h>
#else
#if !defined(_BOOT) && !defined(_KMDB) && !defined(_STANDALONE)
#include "lint.h"
#endif
#if defined(_STANDALONE)
#include <sys/cdefs.h>
#include <stand.h>
#include <limits.h>
#else
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
#endif
#endif
#include "strtolctype.h"
#include <sys/types.h>
#if defined(_KERNEL) && !defined(_BOOT)
int
ddi_strtol(const char *str, char **nptr, int base, long *result)
#else
long
strtol(const char *str, char **nptr, int base)
#endif
{
long val;
int c;
int xx;
int neg = 0;
long multmin;
long limit;
const char **ptr = (const char **)nptr;
const unsigned char *ustr = (const unsigned char *)str;
if (ptr != NULL)
*ptr = (char *)ustr;
if (base < 0 || base > MBASE || base == 1) {
#if defined(_KERNEL) && !defined(_BOOT)
return (EINVAL);
#else
errno = EINVAL;
return (0);
#endif
}
if (!isalnum(c = *ustr)) {
while (isspace(c))
c = *++ustr;
switch (c) {
case '-':
neg++;
case '+':
c = *++ustr;
}
}
if (base == 0) {
if (c != '0')
base = 10;
else if (ustr[1] == 'x' || ustr[1] == 'X')
base = 16;
else
base = 8;
}
if (!lisalnum(c) || (xx = DIGIT(c)) >= base) {
#if defined(_KERNEL) && !defined(_BOOT)
return (EINVAL);
#else
errno = EINVAL;
return (0);
#endif
}
if (base == 16 && c == '0' && (ustr[1] == 'x' || ustr[1] == 'X') &&
isxdigit(ustr[2]))
c = *(ustr += 2);
if (neg)
limit = LONG_MIN;
else
limit = -LONG_MAX;
multmin = limit / (long)base;
val = -DIGIT(c);
for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; ) {
if (val < multmin)
goto overflow;
val *= base;
if (val < limit + xx)
goto overflow;
val -= xx;
c = *++ustr;
}
if (ptr != NULL)
*ptr = (char *)ustr;
#if defined(_KERNEL) && !defined(_BOOT)
*result = neg ? val : -val;
return (0);
#else
return (neg ? val : -val);
#endif
overflow:
for (c = *++ustr; lisalnum(c) && (xx = DIGIT(c)) < base; (c = *++ustr))
;
if (ptr != NULL)
*ptr = (char *)ustr;
#if defined(_KERNEL) && !defined(_BOOT)
return (ERANGE);
#else
errno = ERANGE;
return (neg ? LONG_MIN : LONG_MAX);
#endif
}