|
1 /* |
|
2 FUNCTION |
|
3 <<strtol>>---string to long |
|
4 <<strtoul>>---string to unsigned long |
|
5 |
|
6 INDEX |
|
7 strtol |
|
8 INDEX |
|
9 _strtol_r |
|
10 |
|
11 ANSI_SYNOPSIS |
|
12 #include <stdlib.h> |
|
13 long strtol(const char *<[s]>, char **<[ptr]>,int <[base]>); |
|
14 unsigned long strtoul(const char *<[s]>, char **<[ptr]>, |
|
15 int <[base]>); |
|
16 |
|
17 DESCRIPTION |
|
18 The function <<strtol>> converts the string <<*<[s]>>> to |
|
19 a <<long>>. First, it breaks down the string into three parts: |
|
20 leading whitespace, which is ignored; a subject string consisting |
|
21 of characters resembling an integer in the radix specified by <[base]>; |
|
22 and a trailing portion consisting of zero or more unparseable characters, |
|
23 and always including the terminating null character. Then, it attempts |
|
24 to convert the subject string into a <<long>> and returns the |
|
25 result. |
|
26 |
|
27 If the value of <[base]> is 0, the subject string is expected to look |
|
28 like a normal C integer constant: an optional sign, a possible `<<0x>>' |
|
29 indicating a hexadecimal base, and a number. If <[base]> is between |
|
30 2 and 36, the expected form of the subject is a sequence of letters |
|
31 and digits representing an integer in the radix specified by <[base]>, |
|
32 with an optional plus or minus sign. The letters <<a>>--<<z>> (or, |
|
33 equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35; |
|
34 only letters whose ascribed values are less than <[base]> are |
|
35 permitted. If <[base]> is 16, a leading <<0x>> is permitted. |
|
36 |
|
37 The subject sequence is the longest initial sequence of the input |
|
38 string that has the expected form, starting with the first |
|
39 non-whitespace character. If the string is empty or consists entirely |
|
40 of whitespace, or if the first non-whitespace character is not a |
|
41 permissible letter or digit, the subject string is empty. |
|
42 |
|
43 If the subject string is acceptable, and the value of <[base]> is zero, |
|
44 <<strtol>> attempts to determine the radix from the input string. A |
|
45 string with a leading <<0x>> is treated as a hexadecimal value; a string with |
|
46 a leading 0 and no <<x>> is treated as octal; all other strings are |
|
47 treated as decimal. If <[base]> is between 2 and 36, it is used as the |
|
48 conversion radix, as described above. If the subject string begins with |
|
49 a minus sign, the value is negated. Finally, a pointer to the first |
|
50 character past the converted subject string is stored in <[ptr]>, if |
|
51 <[ptr]> is not <<NULL>>. |
|
52 |
|
53 If the subject string is empty (or not in acceptable form), no conversion |
|
54 is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is |
|
55 not <<NULL>>). |
|
56 |
|
57 The alternate function <<_strtol_r>> is a reentrant version. The |
|
58 extra argument <[reent]> is a pointer to a reentrancy structure. |
|
59 |
|
60 The function <<strtoul>> is similar but does not permit an optional sign |
|
61 and returns an <<unsigned long>>. |
|
62 |
|
63 RETURNS |
|
64 <<strtol>> returns the converted value, if any. If no conversion was |
|
65 made, 0 is returned. |
|
66 |
|
67 <<strtol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of |
|
68 the converted value is too large, and sets <<errno>> to <<ERANGE>>. |
|
69 |
|
70 <<strtoul>> returns <<ULONG_MAX>> if the magnitude of the converted |
|
71 value is too large, and sets <<errno>> to <<ERANGE>>. |
|
72 |
|
73 PORTABILITY |
|
74 <<strtol>> and <<strtoul>> are both ANSI. |
|
75 |
|
76 No supporting OS subroutines are required. |
|
77 */ |
|
78 |
|
79 /*- |
|
80 * Copyright (c) 1990 The Regents of the University of California. |
|
81 * All rights reserved. |
|
82 * |
|
83 * Redistribution and use in source and binary forms, with or without |
|
84 * modification, are permitted provided that the following conditions |
|
85 * are met: |
|
86 * 1. Redistributions of source code must retain the above copyright |
|
87 * notice, this list of conditions and the following disclaimer. |
|
88 * 2. Redistributions in binary form must reproduce the above copyright |
|
89 * notice, this list of conditions and the following disclaimer in the |
|
90 * documentation and/or other materials provided with the distribution. |
|
91 * 3. All advertising materials mentioning features or use of this software |
|
92 * must display the following acknowledgement: |
|
93 * This product includes software developed by the University of |
|
94 * California, Berkeley and its contributors. |
|
95 * 4. Neither the name of the University nor the names of its contributors |
|
96 * may be used to endorse or promote products derived from this software |
|
97 * without specific prior written permission. |
|
98 * |
|
99 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
100 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
101 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
102 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
103 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
104 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
105 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
106 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
107 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
108 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
109 * SUCH DAMAGE. |
|
110 */ |
|
111 |
|
112 |
|
113 #include <_ansi.h> |
|
114 #include <limits.h> |
|
115 #include <ctype.h> |
|
116 #include <errno.h> |
|
117 #include <stdlib.h> |
|
118 #include <reent.h> |
|
119 |
|
120 /* |
|
121 * Convert a string to a long integer. |
|
122 * |
|
123 * Ignores `locale' stuff. Assumes that the upper and lower case |
|
124 * alphabets and digits are each contiguous. |
|
125 */ |
|
126 static unsigned long _do_strtoX (const char *nptr, char **endptr, int base, int issigned) |
|
127 { |
|
128 register const char *s = nptr; |
|
129 register unsigned long acc; |
|
130 register int c; |
|
131 register unsigned long cutoff; |
|
132 register int neg = 0, any, cutlim; |
|
133 register const unsigned long long_min = (unsigned long)LONG_MIN; |
|
134 |
|
135 /* |
|
136 * Skip white space and pick up leading +/- sign if any. |
|
137 * If base is 0, allow 0x for hex and 0 for octal, else |
|
138 * assume decimal; if base is already 16, allow 0x. |
|
139 */ |
|
140 do { |
|
141 c = *s++; |
|
142 } while (isspace(c)); |
|
143 |
|
144 if ((c == '-')||(c == '+')) { |
|
145 issigned = 1; |
|
146 } |
|
147 |
|
148 if (issigned) { |
|
149 if (c == '-') { |
|
150 neg = 1; |
|
151 c = *s++; |
|
152 } else if (c == '+') |
|
153 c = *s++; |
|
154 } |
|
155 if ((base == 0 || base == 16) && |
|
156 c == '0' && (*s == 'x' || *s == 'X')) { |
|
157 c = s[1]; |
|
158 s += 2; |
|
159 base = 16; |
|
160 } |
|
161 if (base == 0) |
|
162 base = c == '0' ? 8 : 10; |
|
163 |
|
164 /* |
|
165 * Compute the cutoff value between legal numbers and illegal |
|
166 * numbers. That is the largest legal value, divided by the |
|
167 * base. An input number that is greater than this value, if |
|
168 * followed by a legal input character, is too big. One that |
|
169 * is equal to this value may be valid or not; the limit |
|
170 * between valid and invalid numbers is then based on the last |
|
171 * digit. For instance, if the range for longs is |
|
172 * [-2147483648..2147483647] and the input base is 10, |
|
173 * cutoff will be set to 214748364 and cutlim to either |
|
174 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated |
|
175 * a value > 214748364, or equal but the next digit is > 7 (or 8), |
|
176 * the number is too big, and we will return a range error. |
|
177 * |
|
178 * Set any if any `digits' consumed; make it negative to indicate |
|
179 * overflow. |
|
180 */ |
|
181 if (issigned) |
|
182 cutoff = neg ? long_min : LONG_MAX; |
|
183 else |
|
184 cutoff = ULONG_MAX; |
|
185 cutlim = cutoff % (unsigned long)base; |
|
186 cutoff = cutoff / (unsigned long)base; |
|
187 for (acc = 0, any = 0;; c = *s++) { |
|
188 if (isdigit(c)) |
|
189 c -= '0'; |
|
190 else if (isalpha(c)) |
|
191 c -= isupper(c) ? 'A' - 10 : 'a' - 10; |
|
192 else |
|
193 break; |
|
194 if (c >= base) |
|
195 break; |
|
196 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) |
|
197 any = -1; |
|
198 else { |
|
199 any = 1; |
|
200 acc *= base; |
|
201 acc += c; |
|
202 } |
|
203 } |
|
204 if (any < 0) { |
|
205 if (issigned) |
|
206 acc = neg ? LONG_MIN : LONG_MAX; |
|
207 else |
|
208 acc = ULONG_MAX; |
|
209 errno = ERANGE; |
|
210 } else if (neg) |
|
211 acc = (unsigned long)(-(long)acc); |
|
212 if (endptr != 0) |
|
213 *endptr = (char *) (any ? s - 1 : nptr); |
|
214 return (acc); |
|
215 } |
|
216 |
|
217 /** |
|
218 Convert string to unsigned long integer. |
|
219 Parses string interpreting its content as an integer value |
|
220 until a character that can not be interpreted is found, |
|
221 and returns an unsigned long value. |
|
222 @return The converted unsigned long value from the input string. |
|
223 If an error occurs or no conversion can be made 0 is returned. |
|
224 @param s String representing an integer number. |
|
225 @param ptr Address of a pointer. |
|
226 This is filled by the function with the address where scan has ended. |
|
227 Serves to determine where there is the first non-numerical character in the string. |
|
228 @param base Numeral radix in which the number to be interpreted. |
|
229 Must be 0 or be between 2 and 36. If it is 0 the radix of the string is determined |
|
230 by the initial characters of the string: |
|
231 */ |
|
232 EXPORT_C unsigned long strtoul (const char *s, char **ptr, int base) |
|
233 { |
|
234 return _do_strtoX (s, ptr, base, 0); |
|
235 } |
|
236 |
|
237 /** |
|
238 Convert string to long integer. |
|
239 @return The converted long int value from the input string. |
|
240 If an error occurs or no conversion can be made 0 is returned. |
|
241 @param s String representing an integer number. |
|
242 @param ptr Address of a pointer. |
|
243 This is filled by the function with the address where scan has ended. |
|
244 @param base Numeral radix in which the number to be interpreted. |
|
245 Must be 0 or be between 2 and 36. If it is 0 the radix of the string |
|
246 is determined by the initial characters of the string |
|
247 */ |
|
248 EXPORT_C long strtol (const char *s, char **ptr, int base) |
|
249 { |
|
250 return (long)_do_strtoX (s, ptr, base, 1); |
|
251 } |
|
252 |
|
253 /** |
|
254 Convert string to integer. |
|
255 Parses string interpreting its content as a number and returns an int value. |
|
256 @return The converted integer value of the input string. |
|
257 On overflow the result is undefined. |
|
258 If an error occurs 0 is returned. |
|
259 @param s String representing an integer number. |
|
260 */ |
|
261 EXPORT_C int atoi (const char *s) |
|
262 { |
|
263 return (int) _do_strtoX (s, NULL, 10, 1); |
|
264 } |