1 2 #include "Python.h" 3 4 #if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) 5 #define _SGI_MP_SOURCE 6 #endif 7 8 /* strtol and strtoul, renamed to avoid conflicts */ 9 10 11 #include <ctype.h> 12 #ifdef HAVE_ERRNO_H 13 #include <errno.h> 14 #endif 15 16 /* Static overflow check values for bases 2 through 36. 17 * smallmax[base] is the largest unsigned long i such that 18 * i * base doesn't overflow unsigned long. 19 */ 20 static unsigned long smallmax[] = { 21 0, /* bases 0 and 1 are invalid */ 22 0, 23 ULONG_MAX / 2, 24 ULONG_MAX / 3, 25 ULONG_MAX / 4, 26 ULONG_MAX / 5, 27 ULONG_MAX / 6, 28 ULONG_MAX / 7, 29 ULONG_MAX / 8, 30 ULONG_MAX / 9, 31 ULONG_MAX / 10, 32 ULONG_MAX / 11, 33 ULONG_MAX / 12, 34 ULONG_MAX / 13, 35 ULONG_MAX / 14, 36 ULONG_MAX / 15, 37 ULONG_MAX / 16, 38 ULONG_MAX / 17, 39 ULONG_MAX / 18, 40 ULONG_MAX / 19, 41 ULONG_MAX / 20, 42 ULONG_MAX / 21, 43 ULONG_MAX / 22, 44 ULONG_MAX / 23, 45 ULONG_MAX / 24, 46 ULONG_MAX / 25, 47 ULONG_MAX / 26, 48 ULONG_MAX / 27, 49 ULONG_MAX / 28, 50 ULONG_MAX / 29, 51 ULONG_MAX / 30, 52 ULONG_MAX / 31, 53 ULONG_MAX / 32, 54 ULONG_MAX / 33, 55 ULONG_MAX / 34, 56 ULONG_MAX / 35, 57 ULONG_MAX / 36, 58 }; 59 60 /* maximum digits that can't ever overflow for bases 2 through 36, 61 * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)]. 62 * Note that this is pessimistic if sizeof(long) > 4. 63 */ 64 #if SIZEOF_LONG == 4 65 static int digitlimit[] = { 66 0, 0, 32, 20, 16, 13, 12, 11, 10, 10, /* 0 - 9 */ 67 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, /* 10 - 19 */ 68 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */ 69 6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */ 70 #elif SIZEOF_LONG == 8 71 /* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */ 72 static int digitlimit[] = { 73 0, 0, 64, 40, 32, 27, 24, 22, 21, 20, /* 0 - 9 */ 74 19, 18, 17, 17, 16, 16, 16, 15, 15, 15, /* 10 - 19 */ 75 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */ 76 13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */ 77 #else 78 #error "Need table for SIZEOF_LONG" 79 #endif 80 81 /* 82 ** strtoul 83 ** This is a general purpose routine for converting 84 ** an ascii string to an integer in an arbitrary base. 85 ** Leading white space is ignored. If 'base' is zero 86 ** it looks for a leading 0, 0b, 0B, 0o, 0O, 0x or 0X 87 ** to tell which base. If these are absent it defaults 88 ** to 10. Base must be 0 or between 2 and 36 (inclusive). 89 ** If 'ptr' is non-NULL it will contain a pointer to 90 ** the end of the scan. 91 ** Errors due to bad pointers will probably result in 92 ** exceptions - we don't check for them. 93 */ 94 unsigned long 95 PyOS_strtoul(register char *str, char **ptr, int base) 96 { 97 register unsigned long result = 0; /* return value of the function */ 98 register int c; /* current input character */ 99 register int ovlimit; /* required digits to overflow */ 100 101 /* skip leading white space */ 102 while (*str && isspace(Py_CHARMASK(*str))) 103 ++str; 104 105 /* check for leading 0 or 0x for auto-base or base 16 */ 106 switch (base) { 107 case 0: /* look for leading 0, 0b, 0o or 0x */ 108 if (*str == '0') { 109 ++str; 110 if (*str == 'x' || *str == 'X') { 111 /* there must be at least one digit after 0x */ 112 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { 113 if (ptr) 114 *ptr = str; 115 return 0; 116 } 117 ++str; 118 base = 16; 119 } else if (*str == 'o' || *str == 'O') { 120 /* there must be at least one digit after 0o */ 121 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { 122 if (ptr) 123 *ptr = str; 124 return 0; 125 } 126 ++str; 127 base = 8; 128 } else if (*str == 'b' || *str == 'B') { 129 /* there must be at least one digit after 0b */ 130 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { 131 if (ptr) 132 *ptr = str; 133 return 0; 134 } 135 ++str; 136 base = 2; 137 } else { 138 base = 8; 139 } 140 } 141 else 142 base = 10; 143 break; 144 145 case 2: /* skip leading 0b or 0B */ 146 if (*str == '0') { 147 ++str; 148 if (*str == 'b' || *str == 'B') { 149 /* there must be at least one digit after 0b */ 150 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { 151 if (ptr) 152 *ptr = str; 153 return 0; 154 } 155 ++str; 156 } 157 } 158 break; 159 160 case 8: /* skip leading 0o or 0O */ 161 if (*str == '0') { 162 ++str; 163 if (*str == 'o' || *str == 'O') { 164 /* there must be at least one digit after 0o */ 165 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { 166 if (ptr) 167 *ptr = str; 168 return 0; 169 } 170 ++str; 171 } 172 } 173 break; 174 175 case 16: /* skip leading 0x or 0X */ 176 if (*str == '0') { 177 ++str; 178 if (*str == 'x' || *str == 'X') { 179 /* there must be at least one digit after 0x */ 180 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { 181 if (ptr) 182 *ptr = str; 183 return 0; 184 } 185 ++str; 186 } 187 } 188 break; 189 } 190 191 /* catch silly bases */ 192 if (base < 2 || base > 36) { 193 if (ptr) 194 *ptr = str; 195 return 0; 196 } 197 198 /* skip leading zeroes */ 199 while (*str == '0') 200 ++str; 201 202 /* base is guaranteed to be in [2, 36] at this point */ 203 ovlimit = digitlimit[base]; 204 205 /* do the conversion until non-digit character encountered */ 206 while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) { 207 if (ovlimit > 0) /* no overflow check required */ 208 result = result * base + c; 209 else { /* requires overflow check */ 210 register unsigned long temp_result; 211 212 if (ovlimit < 0) /* guaranteed overflow */ 213 goto overflowed; 214 215 /* there could be an overflow */ 216 /* check overflow just from shifting */ 217 if (result > smallmax[base]) 218 goto overflowed; 219 220 result *= base; 221 222 /* check overflow from the digit's value */ 223 temp_result = result + c; 224 if (temp_result < result) 225 goto overflowed; 226 227 result = temp_result; 228 } 229 230 ++str; 231 --ovlimit; 232 } 233 234 /* set pointer to point to the last character scanned */ 235 if (ptr) 236 *ptr = str; 237 238 return result; 239 240 overflowed: 241 if (ptr) { 242 /* spool through remaining digit characters */ 243 while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base) 244 ++str; 245 *ptr = str; 246 } 247 errno = ERANGE; 248 return (unsigned long)-1; 249 } 250 251 /* Checking for overflow in PyOS_strtol is a PITA; see comments 252 * about PY_ABS_LONG_MIN in longobject.c. 253 */ 254 #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) 255 256 long 257 PyOS_strtol(char *str, char **ptr, int base) 258 { 259 long result; 260 unsigned long uresult; 261 char sign; 262 263 while (*str && isspace(Py_CHARMASK(*str))) 264 str++; 265 266 sign = *str; 267 if (sign == '+' || sign == '-') 268 str++; 269 270 uresult = PyOS_strtoul(str, ptr, base); 271 272 if (uresult <= (unsigned long)LONG_MAX) { 273 result = (long)uresult; 274 if (sign == '-') 275 result = -result; 276 } 277 else if (sign == '-' && uresult == PY_ABS_LONG_MIN) { 278 result = LONG_MIN; 279 } 280 else { 281 errno = ERANGE; 282 result = LONG_MAX; 283 } 284 return result; 285 } 286