Kaydet (Commit) da53afa1 authored tarafından Tim Peters's avatar Tim Peters

A new table to help string->integer conversion was added yesterday to

both mystrtoul.c and longobject.c.  Share the table instead.  Also
cut its size by 64 entries (they had been used for an inscrutable
trick originally, but the code no longer tries to use that trick).
üst e68955cf
...@@ -25,6 +25,7 @@ PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); ...@@ -25,6 +25,7 @@ PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *);
PyAPI_FUNC(Py_ssize_t) _PyLong_AsSsize_t(PyObject *); PyAPI_FUNC(Py_ssize_t) _PyLong_AsSsize_t(PyObject *);
PyAPI_FUNC(PyObject *) _PyLong_FromSize_t(size_t); PyAPI_FUNC(PyObject *) _PyLong_FromSize_t(size_t);
PyAPI_FUNC(PyObject *) _PyLong_FromSsize_t(Py_ssize_t); PyAPI_FUNC(PyObject *) _PyLong_FromSsize_t(Py_ssize_t);
PyAPI_DATA(int) _PyLong_DigitValue[256];
/* _PyLong_AsScaledDouble returns a double x and an exponent e such that /* _PyLong_AsScaledDouble returns a double x and an exponent e such that
the true value is approximately equal to x * 2**(SHIFT*e). e is >= 0. the true value is approximately equal to x * 2**(SHIFT*e). e is >= 0.
......
...@@ -1304,7 +1304,14 @@ long_format(PyObject *aa, int base, int addL) ...@@ -1304,7 +1304,14 @@ long_format(PyObject *aa, int base, int addL)
return (PyObject *)str; return (PyObject *)str;
} }
static int digval[] = { /* Table of digit values for 8-bit string -> integer conversion.
* '0' maps to 0, ..., '9' maps to 9.
* 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.
* All other indices map to 37.
* Note that when converting a base B string, a char c is a legitimate
* base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B.
*/
int _PyLong_DigitValue[256] = {
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
...@@ -1321,14 +1328,6 @@ static int digval[] = { ...@@ -1321,14 +1328,6 @@ static int digval[] = {
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37
}; };
/* *str points to the first digit in a string of base `base` digits. base /* *str points to the first digit in a string of base `base` digits. base
...@@ -1355,7 +1354,7 @@ long_from_binary_base(char **str, int base) ...@@ -1355,7 +1354,7 @@ long_from_binary_base(char **str, int base)
n >>= 1; n >>= 1;
/* n <- total # of bits needed, while setting p to end-of-string */ /* n <- total # of bits needed, while setting p to end-of-string */
n = 0; n = 0;
while (digval[Py_CHARMASK(*p)] < base) while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
++p; ++p;
*str = p; *str = p;
n = (p - start) * bits_per_char; n = (p - start) * bits_per_char;
...@@ -1376,7 +1375,7 @@ long_from_binary_base(char **str, int base) ...@@ -1376,7 +1375,7 @@ long_from_binary_base(char **str, int base)
bits_in_accum = 0; bits_in_accum = 0;
pdigit = z->ob_digit; pdigit = z->ob_digit;
while (--p >= start) { while (--p >= start) {
int k = digval[Py_CHARMASK(*p)]; int k = _PyLong_DigitValue[Py_CHARMASK(*p)];
assert(k >= 0 && k < base); assert(k >= 0 && k < base);
accum |= (twodigits)(k << bits_in_accum); accum |= (twodigits)(k << bits_in_accum);
bits_in_accum += bits_per_char; bits_in_accum += bits_per_char;
...@@ -1503,7 +1502,7 @@ where B = convmultmax_base[base]. ...@@ -1503,7 +1502,7 @@ where B = convmultmax_base[base].
/* Find length of the string of numeric characters. */ /* Find length of the string of numeric characters. */
scan = str; scan = str;
while (digval[Py_CHARMASK(*scan)] < base) while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)
++scan; ++scan;
/* Create a long object that can contain the largest possible /* Create a long object that can contain the largest possible
...@@ -1527,10 +1526,10 @@ where B = convmultmax_base[base]. ...@@ -1527,10 +1526,10 @@ where B = convmultmax_base[base].
/* Work ;-) */ /* Work ;-) */
while (str < scan) { while (str < scan) {
/* grab up to convwidth digits from the input string */ /* grab up to convwidth digits from the input string */
c = (digit)digval[Py_CHARMASK(*str++)]; c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];
for (i = 1; i < convwidth && str != scan; ++i, ++str) { for (i = 1; i < convwidth && str != scan; ++i, ++str) {
c = (twodigits)(c * base + c = (twodigits)(c * base +
digval[Py_CHARMASK(*str)]); _PyLong_DigitValue[Py_CHARMASK(*str)]);
assert(c < BASE); assert(c < BASE);
} }
......
...@@ -75,34 +75,6 @@ static int digitlimit[] = { ...@@ -75,34 +75,6 @@ static int digitlimit[] = {
7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */ 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */
6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */ 6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */
/* char-to-digit conversion for bases 2-36; all non-digits are 37 */
static int digitlookup[] = {
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37,
37, 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, 37, 37, 37, 37, 37,
37, 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, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37
};
/* /*
** strtoul ** strtoul
** This is a general purpose routine for converting ** This is a general purpose routine for converting
...@@ -167,7 +139,7 @@ PyOS_strtoul(register char *str, char **ptr, int base) ...@@ -167,7 +139,7 @@ PyOS_strtoul(register char *str, char **ptr, int base)
ovlimit = digitlimit[base]; ovlimit = digitlimit[base];
/* do the conversion until non-digit character encountered */ /* do the conversion until non-digit character encountered */
while ((c = digitlookup[Py_CHARMASK(*str)]) < base) { while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
if (ovlimit > 0) /* no overflow check required */ if (ovlimit > 0) /* no overflow check required */
result = result * base + c; result = result * base + c;
else { /* requires overflow check */ else { /* requires overflow check */
...@@ -204,7 +176,7 @@ PyOS_strtoul(register char *str, char **ptr, int base) ...@@ -204,7 +176,7 @@ PyOS_strtoul(register char *str, char **ptr, int base)
overflowed: overflowed:
if (ptr) { if (ptr) {
/* spool through remaining digit characters */ /* spool through remaining digit characters */
while (digitlookup[Py_CHARMASK(*str)] < base) while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
++str; ++str;
*ptr = str; *ptr = str;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment