1 2 3 4 5 6 7 8 9 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#include "Python.h"
#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
#define _SGI_MP_SOURCE
#endif
/* 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.
*/
#include <ctype.h>
#ifndef DONT_HAVE_ERRNO_H
#include <errno.h>
#endif
unsigned long
PyOS_strtoul(register char *str, char **ptr, int base)
{
register unsigned long result; /* return value of the function */
register int c; /* current input character */
register unsigned long temp; /* used in overflow testing */
int ovf; /* true if overflow occurred */
result = 0;
ovf = 0;
/* catch silly bases */
if (base != 0 && (base < 2 || base > 36))
{
if (ptr)
*ptr = str;
return 0;
}
/* 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+1) == 'x' || *(str+1) == 'X'))
str += 2;
break;
}
/* do the conversion */
while ((c = Py_CHARMASK(*str)) != '\0')
{
if (isdigit(c) && c - '0' < base)
c -= '0';
else
{
if (isupper(c))
c = tolower(c);
if (c >= 'a' && c <= 'z')
c -= 'a' - 10;
else /* non-"digit" character */
break;
if (c >= base) /* non-"digit" character */
break;
}
temp = result;
result = result * base + c;
#ifndef MPW
if(base == 10) {
if(((long)(result - c) / base != (long)temp)) /* overflow */
ovf = 1;
}
else {
if ((result - c) / base != temp) /* overflow */
ovf = 1;
}
#endif
str++;
}
/* set pointer to point to the last character scanned */
if (ptr)
*ptr = str;
if (ovf)
{
result = (unsigned long) ~0L;
errno = ERANGE;
}
return result;
}
long
PyOS_strtol(char *str, char **ptr, int base)
{
long result;
char sign;
while (*str && isspace(Py_CHARMASK(*str)))
str++;
sign = *str;
if (sign == '+' || sign == '-')
str++;
result = (long) PyOS_strtoul(str, ptr, base);
/* Signal overflow if the result appears negative,
except for the largest negative integer */
if (result < 0 && !(sign == '-' && result == -result)) {
errno = ERANGE;
result = 0x7fffffff;
}
if (sign == '-')
result = -result;
return result;
}
|