/* Convert a possibly signed character to a nonnegative int */
/* XXX This assumes characters are 8 bits wide */
#ifdef __CHAR_UNSIGNED__
#define Py_CHARMASK(c) (c)
#else
#define Py_CHARMASK(c) ((c) & 0xff)
#endif
/* strtol and strtoul, renamed to avoid conflicts */
/*
** strtoul
** This is a general purpose routine for converting
** an ascii string to an integer in an arbitrary base.
** Leading white space is ignored. If 'base' is zero
** it looks for a leading 0, 0x or 0X to tell which
** base. If these are absent it defaults to 10.
** Base must be 0 or between 2 and 36 (inclusive).
** If 'ptr' is non-NULL it will contain a pointer to
** the end of the scan.
** Errors due to bad pointers will probably result in
** exceptions - we don't check for them.
*/
unsigned long
PyOS_strtoul(register char *str, char **ptr, int base)
{
register unsigned long result = 0; /* return value of the function */
register int c; /* current input character */
register int ovlimit; /* required digits to overflow */
/* skip leading white space */
while (*str && isspace(Py_CHARMASK(*str)))
++str;
/* check for leading 0 or 0x for auto-base or base 16 */
switch (base) {
case 0: /* look for leading 0, 0x or 0X */
if (*str == '0') {
++str;
if (*str == 'x' || *str == 'X') {
++str;
base = 16;
}
else
base = 8;
}
else
base = 10;
break;
case 16: /* skip leading 0x or 0X */
if (*str == '0') {
++str;
if (*str == 'x' || *str == 'X')
++str;
}
break;
}
/* catch silly bases */
if (base < 2 || base > 36) {
if (ptr)
*ptr = str;
return 0;
}
/* skip leading zeroes */
while (*str == '0')
++str;
/* base is guaranteed to be in [2, 36] at this point */
ovlimit = digitlimit[base];
/* do the conversion until non-digit character encountered */
while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
if (ovlimit > 0) /* no overflow check required */
result = result * base + c;
else { /* requires overflow check */
register unsigned long temp_result;
if (ovlimit < 0) /* guaranteed overflow */
goto overflowed;
/* there could be an overflow */
/* check overflow just from shifting */
if (result > smallmax[base])
goto overflowed;
result *= base;
/* check overflow from the digit's value */
temp_result = result + c;
if (temp_result < result)
goto overflowed;
result = temp_result;
}
++str;
--ovlimit;
}
/* set pointer to point to the last character scanned */
if (ptr)
*ptr = str;
return result;
overflowed:
if (ptr) {
/* spool through remaining digit characters */
while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
++str;
*ptr = str;
}
errno = ERANGE;
return (unsigned long)-1;
}
/* Checking for overflow in PyOS_strtol is a PITA; see comments
* about PY_ABS_LONG_MIN in longobject.c.
*/
#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
long
PyOS_strtol(char *str, char **ptr, int base)
{
long result;
unsigned long uresult;
char sign;