blob: ac70e44ba71309da34ec86981a8f53b02d7e1e42 [file] [log] [blame]
Guido van Rossumbe0e9421993-12-24 10:32:00 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumbe0e9421993-12-24 10:32:00 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumbe0e9421993-12-24 10:32:00 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumbe0e9421993-12-24 10:32:00 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumbe0e9421993-12-24 10:32:00 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumbe0e9421993-12-24 10:32:00 +000029
30******************************************************************/
31
Guido van Rossum1924a061998-12-18 22:02:37 +000032#include "Python.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000033
Guido van Rossume32d1531998-07-07 21:32:53 +000034#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
35#define _SGI_MP_SOURCE
36#endif
37
Guido van Rossum7f7f2741995-02-10 17:01:56 +000038/* 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
45
Guido van Rossumb6775db1994-08-01 11:34:53 +000046/* strtol and strtoul, renamed to avoid conflicts */
47
Guido van Rossumbe0e9421993-12-24 10:32:00 +000048/*
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.
60*/
61
62#include <ctype.h>
Guido van Rossum2571cc81999-04-07 16:07:23 +000063#ifndef DONT_HAVE_ERRNO_H
Guido van Rossumbe0e9421993-12-24 10:32:00 +000064#include <errno.h>
Guido van Rossum2571cc81999-04-07 16:07:23 +000065#endif
Guido van Rossumbe0e9421993-12-24 10:32:00 +000066
67unsigned long
Guido van Rossumee2373b1997-05-07 23:51:07 +000068PyOS_strtoul(str, ptr, base)
Guido van Rossumbe0e9421993-12-24 10:32:00 +000069register char * str;
70char ** ptr;
71int base;
72{
73 register unsigned long result; /* return value of the function */
74 register int c; /* current input character */
75 register unsigned long temp; /* used in overflow testing */
76 int ovf; /* true if overflow occurred */
77
78 result = 0;
79 ovf = 0;
80
81/* catch silly bases */
82 if (base != 0 && (base < 2 || base > 36))
83 {
84 if (ptr)
85 *ptr = str;
86 return 0;
87 }
88
89/* skip leading white space */
Guido van Rossum7f7f2741995-02-10 17:01:56 +000090 while (*str && isspace(Py_CHARMASK(*str)))
Guido van Rossumbe0e9421993-12-24 10:32:00 +000091 str++;
92
93/* check for leading 0 or 0x for auto-base or base 16 */
94 switch (base)
95 {
96 case 0: /* look for leading 0, 0x or 0X */
97 if (*str == '0')
98 {
99 str++;
100 if (*str == 'x' || *str == 'X')
101 {
102 str++;
103 base = 16;
104 }
105 else
106 base = 8;
107 }
108 else
109 base = 10;
110 break;
111
112 case 16: /* skip leading 0x or 0X */
113 if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
114 str += 2;
115 break;
116 }
117
118/* do the conversion */
Guido van Rossum80bb9651996-12-05 23:27:02 +0000119 while ((c = Py_CHARMASK(*str)) != '\0')
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000120 {
121 if (isdigit(c) && c - '0' < base)
122 c -= '0';
123 else
124 {
125 if (isupper(c))
126 c = tolower(c);
127 if (c >= 'a' && c <= 'z')
128 c -= 'a' - 10;
129 else /* non-"digit" character */
130 break;
131 if (c >= base) /* non-"digit" character */
132 break;
133 }
134 temp = result;
135 result = result * base + c;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000136#ifndef MPW
Guido van Rossum330aafb1997-12-15 17:27:35 +0000137 if(base == 10) {
Guido van Rossum39b0f891998-04-10 21:52:06 +0000138 if(((long)(result - c) / base != (long)temp)) /* overflow */
Guido van Rossum330aafb1997-12-15 17:27:35 +0000139 ovf = 1;
140 }
141 else {
142 if ((result - c) / base != temp) /* overflow */
143 ovf = 1;
144 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000145#endif
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000146 str++;
147 }
148
149/* set pointer to point to the last character scanned */
150 if (ptr)
151 *ptr = str;
152 if (ovf)
153 {
Guido van Rossum644a12b1997-04-09 19:24:53 +0000154 result = (unsigned long) ~0L;
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000155 errno = ERANGE;
156 }
157 return result;
158}
159
160long
Guido van Rossumee2373b1997-05-07 23:51:07 +0000161PyOS_strtol(str, ptr, base)
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000162char * str;
163char ** ptr;
164int base;
165{
166 long result;
167 char sign;
168
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000169 while (*str && isspace(Py_CHARMASK(*str)))
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000170 str++;
171
172 sign = *str;
173 if (sign == '+' || sign == '-')
174 str++;
175
Guido van Rossumee2373b1997-05-07 23:51:07 +0000176 result = (long) PyOS_strtoul(str, ptr, base);
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000177
178 /* Signal overflow if the result appears negative,
179 except for the largest negative integer */
180 if (result < 0 && !(sign == '-' && result == -result)) {
181 errno = ERANGE;
182 result = 0x7fffffff;
183 }
184
185 if (sign == '-')
186 result = -result;
187
188 return result;
189}