1 2 #include "Python.h" 3 4 #if defined(__sgi) && !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 const 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 const 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 const 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 0b, 0o or 0x to tell which 87 ** base. If these are absent it defaults to 10. 88 ** 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(const char *str, char **ptr, int base) 96 { 97 unsigned long result = 0; /* return value of the function */ 98 int c; /* current input character */ 99 int ovlimit; /* required digits to overflow */ 100 101 /* skip leading white space */ 102 while (*str && Py_ISSPACE(Py_CHARMASK(*str))) 103 ++str; 104 105 /* check for leading 0b, 0o or 0x for auto-base or base 16 */ 106 switch (base) { 107 case 0: /* look for leading 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 = (char *)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 = (char *)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 = (char *)str; 133 return 0; 134 } 135 ++str; 136 base = 2; 137 } else { 138 /* skip all zeroes... */ 139 while (*str == '0') 140 ++str; 141 while (Py_ISSPACE(Py_CHARMASK(*str))) 142 ++str; 143 if (ptr) 144 *ptr = (char *)str; 145 return 0; 146 } 147 } 148 else 149 base = 10; 150 break; 151 152 /* even with explicit base, skip leading 0? prefix */ 153 case 16: 154 if (*str == '0') { 155 ++str; 156 if (*str == 'x' || *str == 'X') { 157 /* there must be at least one digit after 0x */ 158 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) { 159 if (ptr) 160 *ptr = (char *)str; 161 return 0; 162 } 163 ++str; 164 } 165 } 166 break; 167 case 8: 168 if (*str == '0') { 169 ++str; 170 if (*str == 'o' || *str == 'O') { 171 /* there must be at least one digit after 0o */ 172 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) { 173 if (ptr) 174 *ptr = (char *)str; 175 return 0; 176 } 177 ++str; 178 } 179 } 180 break; 181 case 2: 182 if(*str == '0') { 183 ++str; 184 if (*str == 'b' || *str == 'B') { 185 /* there must be at least one digit after 0b */ 186 if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) { 187 if (ptr) 188 *ptr = (char *)str; 189 return 0; 190 } 191 ++str; 192 } 193 } 194 break; 195 } 196 197 /* catch silly bases */ 198 if (base < 2 || base > 36) { 199 if (ptr) 200 *ptr = (char *)str; 201 return 0; 202 } 203 204 /* skip leading zeroes */ 205 while (*str == '0') 206 ++str; 207 208 /* base is guaranteed to be in [2, 36] at this point */ 209 ovlimit = digitlimit[base]; 210 211 /* do the conversion until non-digit character encountered */ 212 while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) { 213 if (ovlimit > 0) /* no overflow check required */ 214 result = result * base + c; 215 else { /* requires overflow check */ 216 unsigned long temp_result; 217 218 if (ovlimit < 0) /* guaranteed overflow */ 219 goto overflowed; 220 221 /* there could be an overflow */ 222 /* check overflow just from shifting */ 223 if (result > smallmax[base]) 224 goto overflowed; 225 226 result *= base; 227 228 /* check overflow from the digit's value */ 229 temp_result = result + c; 230 if (temp_result < result) 231 goto overflowed; 232 233 result = temp_result; 234 } 235 236 ++str; 237 --ovlimit; 238 } 239 240 /* set pointer to point to the last character scanned */ 241 if (ptr) 242 *ptr = (char *)str; 243 244 return result; 245 246 overflowed: 247 if (ptr) { 248 /* spool through remaining digit characters */ 249 while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base) 250 ++str; 251 *ptr = (char *)str; 252 } 253 errno = ERANGE; 254 return (unsigned long)-1; 255 } 256 257 /* Checking for overflow in PyOS_strtol is a PITA; see comments 258 * about PY_ABS_LONG_MIN in longobject.c. 259 */ 260 #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) 261 262 long 263 PyOS_strtol(const char *str, char **ptr, int base) 264 { 265 long result; 266 unsigned long uresult; 267 char sign; 268 269 while (*str && Py_ISSPACE(Py_CHARMASK(*str))) 270 str++; 271 272 sign = *str; 273 if (sign == '+' || sign == '-') 274 str++; 275 276 uresult = PyOS_strtoul(str, ptr, base); 277 278 if (uresult <= (unsigned long)LONG_MAX) { 279 result = (long)uresult; 280 if (sign == '-') 281 result = -result; 282 } 283 else if (sign == '-' && uresult == PY_ABS_LONG_MIN) { 284 result = LONG_MIN; 285 } 286 else { 287 errno = ERANGE; 288 result = LONG_MAX; 289 } 290 return result; 291 } 292