blob: ed0e52648d6be8b8e32f03dbe196e3d7b514a8e4 [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 Rossumb6775db1994-08-01 11:34:53 +000032#include "config.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000033
Guido van Rossum7f7f2741995-02-10 17:01:56 +000034/* Convert a possibly signed character to a nonnegative int */
35/* XXX This assumes characters are 8 bits wide */
36#ifdef __CHAR_UNSIGNED__
37#define Py_CHARMASK(c) (c)
38#else
39#define Py_CHARMASK(c) ((c) & 0xff)
40#endif
41
Guido van Rossum5c2306c1995-01-17 16:31:21 +000042#include "rename2.h"
43
Guido van Rossumb6775db1994-08-01 11:34:53 +000044/* strtol and strtoul, renamed to avoid conflicts */
45
Guido van Rossumbe0e9421993-12-24 10:32:00 +000046/*
47** strtoul
48** This is a general purpose routine for converting
49** an ascii string to an integer in an arbitrary base.
50** Leading white space is ignored. If 'base' is zero
51** it looks for a leading 0, 0x or 0X to tell which
52** base. If these are absent it defaults to 10.
53** Base must be 0 or between 2 and 36 (inclusive).
54** If 'ptr' is non-NULL it will contain a pointer to
55** the end of the scan.
56** Errors due to bad pointers will probably result in
57** exceptions - we don't check for them.
58*/
59
60#include <ctype.h>
61#include <errno.h>
62
63unsigned long
Guido van Rossumb6775db1994-08-01 11:34:53 +000064mystrtoul(str, ptr, base)
Guido van Rossumbe0e9421993-12-24 10:32:00 +000065register char * str;
66char ** ptr;
67int base;
68{
69 register unsigned long result; /* return value of the function */
70 register int c; /* current input character */
71 register unsigned long temp; /* used in overflow testing */
72 int ovf; /* true if overflow occurred */
73
74 result = 0;
75 ovf = 0;
76
77/* catch silly bases */
78 if (base != 0 && (base < 2 || base > 36))
79 {
80 if (ptr)
81 *ptr = str;
82 return 0;
83 }
84
85/* skip leading white space */
Guido van Rossum7f7f2741995-02-10 17:01:56 +000086 while (*str && isspace(Py_CHARMASK(*str)))
Guido van Rossumbe0e9421993-12-24 10:32:00 +000087 str++;
88
89/* check for leading 0 or 0x for auto-base or base 16 */
90 switch (base)
91 {
92 case 0: /* look for leading 0, 0x or 0X */
93 if (*str == '0')
94 {
95 str++;
96 if (*str == 'x' || *str == 'X')
97 {
98 str++;
99 base = 16;
100 }
101 else
102 base = 8;
103 }
104 else
105 base = 10;
106 break;
107
108 case 16: /* skip leading 0x or 0X */
109 if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
110 str += 2;
111 break;
112 }
113
114/* do the conversion */
Guido van Rossum80bb9651996-12-05 23:27:02 +0000115 while ((c = Py_CHARMASK(*str)) != '\0')
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000116 {
117 if (isdigit(c) && c - '0' < base)
118 c -= '0';
119 else
120 {
121 if (isupper(c))
122 c = tolower(c);
123 if (c >= 'a' && c <= 'z')
124 c -= 'a' - 10;
125 else /* non-"digit" character */
126 break;
127 if (c >= base) /* non-"digit" character */
128 break;
129 }
130 temp = result;
131 result = result * base + c;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000132#ifndef MPW
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000133 if ((result - c) / base != temp) /* overflow */
134 ovf = 1;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000135#endif
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000136 str++;
137 }
138
139/* set pointer to point to the last character scanned */
140 if (ptr)
141 *ptr = str;
142 if (ovf)
143 {
Guido van Rossum644a12b1997-04-09 19:24:53 +0000144 result = (unsigned long) ~0L;
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000145 errno = ERANGE;
146 }
147 return result;
148}
149
150long
Guido van Rossumb6775db1994-08-01 11:34:53 +0000151mystrtol(str, ptr, base)
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000152char * str;
153char ** ptr;
154int base;
155{
156 long result;
157 char sign;
158
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000159 while (*str && isspace(Py_CHARMASK(*str)))
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000160 str++;
161
162 sign = *str;
163 if (sign == '+' || sign == '-')
164 str++;
165
Guido van Rossumb6775db1994-08-01 11:34:53 +0000166 result = (long) mystrtoul(str, ptr, base);
Guido van Rossumbe0e9421993-12-24 10:32:00 +0000167
168 /* Signal overflow if the result appears negative,
169 except for the largest negative integer */
170 if (result < 0 && !(sign == '-' && result == -result)) {
171 errno = ERANGE;
172 result = 0x7fffffff;
173 }
174
175 if (sign == '-')
176 result = -result;
177
178 return result;
179}