Fix an amazing number of typos & malformed sentences reported by Detlef
[python/dscho.git] / Python / mystrtoul.c
blobb5ea751068be2c514a179d2869683f7abbeb9d71
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 #include "Python.h"
34 #if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
35 #define _SGI_MP_SOURCE
36 #endif
38 /* Convert a possibly signed character to a nonnegative int */
39 /* XXX This assumes characters are 8 bits wide */
40 #ifdef __CHAR_UNSIGNED__
41 #define Py_CHARMASK(c) (c)
42 #else
43 #define Py_CHARMASK(c) ((c) & 0xff)
44 #endif
46 /* strtol and strtoul, renamed to avoid conflicts */
49 ** strtoul
50 ** This is a general purpose routine for converting
51 ** an ascii string to an integer in an arbitrary base.
52 ** Leading white space is ignored. If 'base' is zero
53 ** it looks for a leading 0, 0x or 0X to tell which
54 ** base. If these are absent it defaults to 10.
55 ** Base must be 0 or between 2 and 36 (inclusive).
56 ** If 'ptr' is non-NULL it will contain a pointer to
57 ** the end of the scan.
58 ** Errors due to bad pointers will probably result in
59 ** exceptions - we don't check for them.
62 #include <ctype.h>
63 #include <errno.h>
65 unsigned long
66 PyOS_strtoul(str, ptr, base)
67 register char * str;
68 char ** ptr;
69 int base;
71 register unsigned long result; /* return value of the function */
72 register int c; /* current input character */
73 register unsigned long temp; /* used in overflow testing */
74 int ovf; /* true if overflow occurred */
76 result = 0;
77 ovf = 0;
79 /* catch silly bases */
80 if (base != 0 && (base < 2 || base > 36))
82 if (ptr)
83 *ptr = str;
84 return 0;
87 /* skip leading white space */
88 while (*str && isspace(Py_CHARMASK(*str)))
89 str++;
91 /* check for leading 0 or 0x for auto-base or base 16 */
92 switch (base)
94 case 0: /* look for leading 0, 0x or 0X */
95 if (*str == '0')
97 str++;
98 if (*str == 'x' || *str == 'X')
100 str++;
101 base = 16;
103 else
104 base = 8;
106 else
107 base = 10;
108 break;
110 case 16: /* skip leading 0x or 0X */
111 if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
112 str += 2;
113 break;
116 /* do the conversion */
117 while ((c = Py_CHARMASK(*str)) != '\0')
119 if (isdigit(c) && c - '0' < base)
120 c -= '0';
121 else
123 if (isupper(c))
124 c = tolower(c);
125 if (c >= 'a' && c <= 'z')
126 c -= 'a' - 10;
127 else /* non-"digit" character */
128 break;
129 if (c >= base) /* non-"digit" character */
130 break;
132 temp = result;
133 result = result * base + c;
134 #ifndef MPW
135 if(base == 10) {
136 if(((long)(result - c) / base != (long)temp)) /* overflow */
137 ovf = 1;
139 else {
140 if ((result - c) / base != temp) /* overflow */
141 ovf = 1;
143 #endif
144 str++;
147 /* set pointer to point to the last character scanned */
148 if (ptr)
149 *ptr = str;
150 if (ovf)
152 result = (unsigned long) ~0L;
153 errno = ERANGE;
155 return result;
158 long
159 PyOS_strtol(str, ptr, base)
160 char * str;
161 char ** ptr;
162 int base;
164 long result;
165 char sign;
167 while (*str && isspace(Py_CHARMASK(*str)))
168 str++;
170 sign = *str;
171 if (sign == '+' || sign == '-')
172 str++;
174 result = (long) PyOS_strtoul(str, ptr, base);
176 /* Signal overflow if the result appears negative,
177 except for the largest negative integer */
178 if (result < 0 && !(sign == '-' && result == -result)) {
179 errno = ERANGE;
180 result = 0x7fffffff;
183 if (sign == '-')
184 result = -result;
186 return result;