]> granicus.if.org Git - python/commitdiff
A new table to help string->integer conversion was added yesterday to
authorTim Peters <tim.peters@gmail.com>
Thu, 25 May 2006 17:34:03 +0000 (17:34 +0000)
committerTim Peters <tim.peters@gmail.com>
Thu, 25 May 2006 17:34:03 +0000 (17:34 +0000)
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).

Include/longobject.h
Objects/longobject.c
Python/mystrtoul.c

index 77544ef158b159ba6b5b657e4d0a2c3a93fe3e59..eef4e9b4bcb893d5a0faba393a7a075177b0ceb4 100644 (file)
@@ -25,6 +25,7 @@ PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *);
 PyAPI_FUNC(Py_ssize_t) _PyLong_AsSsize_t(PyObject *);
 PyAPI_FUNC(PyObject *) _PyLong_FromSize_t(size_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
    the true value is approximately equal to x * 2**(SHIFT*e).  e is >= 0.
index dc2311a435b700fe97b30a84760f9f29c92352a9..9b1a0b977726dfbebf783fb0ceb65615dff8a70b 100644 (file)
@@ -1304,7 +1304,14 @@ long_format(PyObject *aa, int base, int addL)
        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,
@@ -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
 };
 
 /* *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)
                n >>= 1;
        /* n <- total # of bits needed, while setting p to end-of-string */
        n = 0;
-       while (digval[Py_CHARMASK(*p)] < base)
+       while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
                ++p;
        *str = p;
        n = (p - start) * bits_per_char;
@@ -1376,7 +1375,7 @@ long_from_binary_base(char **str, int base)
        bits_in_accum = 0;
        pdigit = z->ob_digit;
        while (--p >= start) {
-               int k = digval[Py_CHARMASK(*p)];
+               int k = _PyLong_DigitValue[Py_CHARMASK(*p)];
                assert(k >= 0 && k < base);
                accum |= (twodigits)(k << bits_in_accum);
                bits_in_accum += bits_per_char;
@@ -1503,7 +1502,7 @@ where B = convmultmax_base[base].
 
                /* Find length of the string of numeric characters. */
                scan = str;
-               while (digval[Py_CHARMASK(*scan)] < base)
+               while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)
                        ++scan;
 
                /* Create a long object that can contain the largest possible
@@ -1527,10 +1526,10 @@ where B = convmultmax_base[base].
                /* Work ;-) */
                while (str < scan) {
                        /* 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) {
                                c = (twodigits)(c *  base +
-                                       digval[Py_CHARMASK(*str)]);
+                                       _PyLong_DigitValue[Py_CHARMASK(*str)]);
                                assert(c < BASE);
                        }
 
index 272f827c8cf482a4d505b0f43b14750355e7fc9a..380b37da90330f813e4435e8e05150308499bff2 100644 (file)
@@ -75,34 +75,6 @@ static int digitlimit[] = {
        7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  /* 20 - 29 */
        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
 **             This is a general purpose routine for converting
@@ -167,7 +139,7 @@ PyOS_strtoul(register char *str, char **ptr, int base)
        ovlimit = digitlimit[base];
 
        /* 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 */
                        result = result * base + c;
                else { /* requires overflow check */
@@ -204,7 +176,7 @@ PyOS_strtoul(register char *str, char **ptr, int base)
 overflowed:
        if (ptr) {
                /* spool through remaining digit characters */
-               while (digitlookup[Py_CHARMASK(*str)] < base)
+               while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
                        ++str;
                *ptr = str;
        }