summaryrefslogtreecommitdiffstats
path: root/Python/mystrtoul.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1993-12-24 10:32:00 (GMT)
committerGuido van Rossum <guido@python.org>1993-12-24 10:32:00 (GMT)
commitbe0e9420a1673b7b3991d7eec843d75219a84f34 (patch)
tree8044f57b7dbcea72fb2f695c3f0cb0a005faa461 /Python/mystrtoul.c
parent2e1d433e4357a5a980a96f15b3802138a064fb64 (diff)
downloadcpython-be0e9420a1673b7b3991d7eec843d75219a84f34.zip
cpython-be0e9420a1673b7b3991d7eec843d75219a84f34.tar.gz
cpython-be0e9420a1673b7b3991d7eec843d75219a84f34.tar.bz2
New files.
Diffstat (limited to 'Python/mystrtoul.c')
-rw-r--r--Python/mystrtoul.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/Python/mystrtoul.c b/Python/mystrtoul.c
new file mode 100644
index 0000000..965421b
--- /dev/null
+++ b/Python/mystrtoul.c
@@ -0,0 +1,156 @@
+/***********************************************************
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/*
+** strtoul
+** This is a general purpose routine for converting
+** an ascii string to an integer in an arbitrary base.
+** Leading white space is ignored. If 'base' is zero
+** it looks for a leading 0, 0x or 0X to tell which
+** base. If these are absent it defaults to 10.
+** Base must be 0 or between 2 and 36 (inclusive).
+** If 'ptr' is non-NULL it will contain a pointer to
+** the end of the scan.
+** Errors due to bad pointers will probably result in
+** exceptions - we don't check for them.
+*/
+
+#include <ctype.h>
+#include <errno.h>
+
+unsigned long
+strtoul(str, ptr, base)
+register char * str;
+char ** ptr;
+int base;
+{
+ register unsigned long result; /* return value of the function */
+ register int c; /* current input character */
+ register unsigned long temp; /* used in overflow testing */
+ int ovf; /* true if overflow occurred */
+
+ result = 0;
+ ovf = 0;
+
+/* catch silly bases */
+ if (base != 0 && (base < 2 || base > 36))
+ {
+ if (ptr)
+ *ptr = str;
+ return 0;
+ }
+
+/* skip leading white space */
+ while (*str && isspace(*str))
+ str++;
+
+/* check for leading 0 or 0x for auto-base or base 16 */
+ switch (base)
+ {
+ case 0: /* look for leading 0, 0x or 0X */
+ if (*str == '0')
+ {
+ str++;
+ if (*str == 'x' || *str == 'X')
+ {
+ str++;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ break;
+
+ case 16: /* skip leading 0x or 0X */
+ if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
+ str += 2;
+ break;
+ }
+
+/* do the conversion */
+ while (c = *str)
+ {
+ if (isdigit(c) && c - '0' < base)
+ c -= '0';
+ else
+ {
+ if (isupper(c))
+ c = tolower(c);
+ if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else /* non-"digit" character */
+ break;
+ if (c >= base) /* non-"digit" character */
+ break;
+ }
+ temp = result;
+ result = result * base + c;
+ if ((result - c) / base != temp) /* overflow */
+ ovf = 1;
+ str++;
+ }
+
+/* set pointer to point to the last character scanned */
+ if (ptr)
+ *ptr = str;
+ if (ovf)
+ {
+ result = ~0;
+ errno = ERANGE;
+ }
+ return result;
+}
+
+long
+strtol(str, ptr, base)
+char * str;
+char ** ptr;
+int base;
+{
+ long result;
+ char sign;
+
+ while (*str && isspace(*str))
+ str++;
+
+ sign = *str;
+ if (sign == '+' || sign == '-')
+ str++;
+
+ result = (long) strtoul(str, ptr, base);
+
+ /* Signal overflow if the result appears negative,
+ except for the largest negative integer */
+ if (result < 0 && !(sign == '-' && result == -result)) {
+ errno = ERANGE;
+ result = 0x7fffffff;
+ }
+
+ if (sign == '-')
+ result = -result;
+
+ return result;
+}