]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.10/Python/mystrtoul.c
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 1/5.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Python / mystrtoul.c
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Python/mystrtoul.c b/AppPkg/Applications/Python/Python-2.7.10/Python/mystrtoul.c
new file mode 100644 (file)
index 0000000..096eb16
--- /dev/null
@@ -0,0 +1,285 @@
+\r
+#include "Python.h"\r
+\r
+#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)\r
+#define _SGI_MP_SOURCE\r
+#endif\r
+\r
+/* strtol and strtoul, renamed to avoid conflicts */\r
+\r
+\r
+#include <ctype.h>\r
+#ifdef HAVE_ERRNO_H\r
+#include <errno.h>\r
+#endif\r
+\r
+/* Static overflow check values for bases 2 through 36.\r
+ * smallmax[base] is the largest unsigned long i such that\r
+ * i * base doesn't overflow unsigned long.\r
+ */\r
+static unsigned long smallmax[] = {\r
+    0, /* bases 0 and 1 are invalid */\r
+    0,\r
+    ULONG_MAX / 2,\r
+    ULONG_MAX / 3,\r
+    ULONG_MAX / 4,\r
+    ULONG_MAX / 5,\r
+    ULONG_MAX / 6,\r
+    ULONG_MAX / 7,\r
+    ULONG_MAX / 8,\r
+    ULONG_MAX / 9,\r
+    ULONG_MAX / 10,\r
+    ULONG_MAX / 11,\r
+    ULONG_MAX / 12,\r
+    ULONG_MAX / 13,\r
+    ULONG_MAX / 14,\r
+    ULONG_MAX / 15,\r
+    ULONG_MAX / 16,\r
+    ULONG_MAX / 17,\r
+    ULONG_MAX / 18,\r
+    ULONG_MAX / 19,\r
+    ULONG_MAX / 20,\r
+    ULONG_MAX / 21,\r
+    ULONG_MAX / 22,\r
+    ULONG_MAX / 23,\r
+    ULONG_MAX / 24,\r
+    ULONG_MAX / 25,\r
+    ULONG_MAX / 26,\r
+    ULONG_MAX / 27,\r
+    ULONG_MAX / 28,\r
+    ULONG_MAX / 29,\r
+    ULONG_MAX / 30,\r
+    ULONG_MAX / 31,\r
+    ULONG_MAX / 32,\r
+    ULONG_MAX / 33,\r
+    ULONG_MAX / 34,\r
+    ULONG_MAX / 35,\r
+    ULONG_MAX / 36,\r
+};\r
+\r
+/* maximum digits that can't ever overflow for bases 2 through 36,\r
+ * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)].\r
+ * Note that this is pessimistic if sizeof(long) > 4.\r
+ */\r
+#if SIZEOF_LONG == 4\r
+static int digitlimit[] = {\r
+    0,  0, 32, 20, 16, 13, 12, 11, 10, 10,  /*  0 -  9 */\r
+    9,  9,  8,  8,  8,  8,  8,  7,  7,  7,  /* 10 - 19 */\r
+    7,  7,  7,  7,  6,  6,  6,  6,  6,  6,  /* 20 - 29 */\r
+    6,  6,  6,  6,  6,  6,  6};             /* 30 - 36 */\r
+#elif SIZEOF_LONG == 8\r
+/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */\r
+static int digitlimit[] = {\r
+         0,   0, 64, 40, 32, 27, 24, 22, 21, 20,  /*  0 -  9 */\r
+    19,  18, 17, 17, 16, 16, 16, 15, 15, 15,  /* 10 - 19 */\r
+    14,  14, 14, 14, 13, 13, 13, 13, 13, 13,  /* 20 - 29 */\r
+    13,  12, 12, 12, 12, 12, 12};             /* 30 - 36 */\r
+#else\r
+#error "Need table for SIZEOF_LONG"\r
+#endif\r
+\r
+/*\r
+**      strtoul\r
+**              This is a general purpose routine for converting\r
+**              an ascii string to an integer in an arbitrary base.\r
+**              Leading white space is ignored.  If 'base' is zero\r
+**              it looks for a leading 0, 0b, 0B, 0o, 0O, 0x or 0X\r
+**              to tell which base.  If these are absent it defaults\r
+**              to 10. Base must be 0 or between 2 and 36 (inclusive).\r
+**              If 'ptr' is non-NULL it will contain a pointer to\r
+**              the end of the scan.\r
+**              Errors due to bad pointers will probably result in\r
+**              exceptions - we don't check for them.\r
+*/\r
+unsigned long\r
+PyOS_strtoul(register char *str, char **ptr, int base)\r
+{\r
+    register unsigned long result = 0; /* return value of the function */\r
+    register int c;             /* current input character */\r
+    register int ovlimit;       /* required digits to overflow */\r
+\r
+    /* skip leading white space */\r
+    while (*str && isspace(Py_CHARMASK(*str)))\r
+        ++str;\r
+\r
+    /* check for leading 0 or 0x for auto-base or base 16 */\r
+    switch (base) {\r
+    case 0:             /* look for leading 0, 0b, 0o or 0x */\r
+        if (*str == '0') {\r
+            ++str;\r
+            if (*str == 'x' || *str == 'X') {\r
+                /* there must be at least one digit after 0x */\r
+                if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {\r
+                    if (ptr)\r
+                        *ptr = str;\r
+                    return 0;\r
+                }\r
+                ++str;\r
+                base = 16;\r
+            } else if (*str == 'o' || *str == 'O') {\r
+                /* there must be at least one digit after 0o */\r
+                if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {\r
+                    if (ptr)\r
+                        *ptr = str;\r
+                    return 0;\r
+                }\r
+                ++str;\r
+                base = 8;\r
+            } else if (*str == 'b' || *str == 'B') {\r
+                /* there must be at least one digit after 0b */\r
+                if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {\r
+                    if (ptr)\r
+                        *ptr = str;\r
+                    return 0;\r
+                }\r
+                ++str;\r
+                base = 2;\r
+            } else {\r
+                base = 8;\r
+            }\r
+        }\r
+        else\r
+            base = 10;\r
+        break;\r
+\r
+    case 2:     /* skip leading 0b or 0B */\r
+        if (*str == '0') {\r
+            ++str;\r
+            if (*str == 'b' || *str == 'B') {\r
+                /* there must be at least one digit after 0b */\r
+                if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {\r
+                    if (ptr)\r
+                        *ptr = str;\r
+                    return 0;\r
+                }\r
+                ++str;\r
+            }\r
+        }\r
+        break;\r
+\r
+    case 8:     /* skip leading 0o or 0O */\r
+        if (*str == '0') {\r
+            ++str;\r
+            if (*str == 'o' || *str == 'O') {\r
+                /* there must be at least one digit after 0o */\r
+                if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {\r
+                    if (ptr)\r
+                        *ptr = str;\r
+                    return 0;\r
+                }\r
+                ++str;\r
+            }\r
+        }\r
+        break;\r
+\r
+    case 16:            /* skip leading 0x or 0X */\r
+        if (*str == '0') {\r
+            ++str;\r
+            if (*str == 'x' || *str == 'X') {\r
+                /* there must be at least one digit after 0x */\r
+                if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {\r
+                    if (ptr)\r
+                        *ptr = str;\r
+                    return 0;\r
+                }\r
+                ++str;\r
+            }\r
+        }\r
+        break;\r
+    }\r
+\r
+    /* catch silly bases */\r
+    if (base < 2 || base > 36) {\r
+        if (ptr)\r
+            *ptr = str;\r
+        return 0;\r
+    }\r
+\r
+    /* skip leading zeroes */\r
+    while (*str == '0')\r
+        ++str;\r
+\r
+    /* base is guaranteed to be in [2, 36] at this point */\r
+    ovlimit = digitlimit[base];\r
+\r
+    /* do the conversion until non-digit character encountered */\r
+    while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {\r
+        if (ovlimit > 0) /* no overflow check required */\r
+            result = result * base + c;\r
+        else { /* requires overflow check */\r
+            register unsigned long temp_result;\r
+\r
+            if (ovlimit < 0) /* guaranteed overflow */\r
+                goto overflowed;\r
+\r
+            /* there could be an overflow */\r
+            /* check overflow just from shifting */\r
+            if (result > smallmax[base])\r
+                goto overflowed;\r
+\r
+            result *= base;\r
+\r
+            /* check overflow from the digit's value */\r
+            temp_result = result + c;\r
+            if (temp_result < result)\r
+                goto overflowed;\r
+\r
+            result = temp_result;\r
+        }\r
+\r
+        ++str;\r
+        --ovlimit;\r
+    }\r
+\r
+    /* set pointer to point to the last character scanned */\r
+    if (ptr)\r
+        *ptr = str;\r
+\r
+    return result;\r
+\r
+overflowed:\r
+    if (ptr) {\r
+        /* spool through remaining digit characters */\r
+        while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)\r
+            ++str;\r
+        *ptr = str;\r
+    }\r
+    errno = ERANGE;\r
+    return (unsigned long)-1;\r
+}\r
+\r
+/* Checking for overflow in PyOS_strtol is a PITA; see comments\r
+ * about PY_ABS_LONG_MIN in longobject.c.\r
+ */\r
+#define PY_ABS_LONG_MIN         (0-(unsigned long)LONG_MIN)\r
+\r
+long\r
+PyOS_strtol(char *str, char **ptr, int base)\r
+{\r
+    long result;\r
+    unsigned long uresult;\r
+    char sign;\r
+\r
+    while (*str && isspace(Py_CHARMASK(*str)))\r
+        str++;\r
+\r
+    sign = *str;\r
+    if (sign == '+' || sign == '-')\r
+        str++;\r
+\r
+    uresult = PyOS_strtoul(str, ptr, base);\r
+\r
+    if (uresult <= (unsigned long)LONG_MAX) {\r
+        result = (long)uresult;\r
+        if (sign == '-')\r
+            result = -result;\r
+    }\r
+    else if (sign == '-' && uresult == PY_ABS_LONG_MIN) {\r
+        result = LONG_MIN;\r
+    }\r
+    else {\r
+        errno = ERANGE;\r
+        result = LONG_MAX;\r
+    }\r
+    return result;\r
+}\r