1 /* Convert string representation of a number into an integer value.
2
3 Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2005
4 Free Software Foundation, Inc.
5
6 NOTE: The canonical source of this file is maintained with the GNU C
7 Library. Bugs can be reported to bug-glibc@gnu.org.
8
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
22 #include <sys/cdefs.h>
23 __RCSID("$NetBSD: strtol.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
24
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #ifdef _LIBC
31 # define USE_NUMBER_GROUPING
32 #endif
33
34 #include <ctype.h>
35 #include <errno.h>
36 #ifndef errno
37 extern int errno;
38 #endif
39 #ifndef __set_errno
40 # define __set_errno(Val) errno = (Val)
41 #endif
42
43 #include <limits.h>
44 #include <stddef.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 #ifdef USE_NUMBER_GROUPING
49 # include "../locale/localeinfo.h"
50 #endif
51
52 /* Nonzero if we are defining `strtoul' or `strtoull', operating on
53 unsigned integers. */
54 #ifndef UNSIGNED
55 # define UNSIGNED 0
56 # define INT LONG int
57 #else
58 # define INT unsigned LONG int
59 #endif
60
61 /* Determine the name. */
62 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
63 # if UNSIGNED
64 # ifdef USE_WIDE_CHAR
65 # ifdef QUAD
66 # define strtol __wcstoull_l
67 # else
68 # define strtol __wcstoul_l
69 # endif
70 # else
71 # ifdef QUAD
72 # define strtol __strtoull_l
73 # else
74 # define strtol __strtoul_l
75 # endif
76 # endif
77 # else
78 # ifdef USE_WIDE_CHAR
79 # ifdef QUAD
80 # define strtol __wcstoll_l
81 # else
82 # define strtol __wcstol_l
83 # endif
84 # else
85 # ifdef QUAD
86 # define strtol __strtoll_l
87 # else
88 # define strtol __strtol_l
89 # endif
90 # endif
91 # endif
92 #else
93 # if UNSIGNED
94 # ifdef USE_WIDE_CHAR
95 # ifdef QUAD
96 # define strtol wcstoull
97 # else
98 # define strtol wcstoul
99 # endif
100 # else
101 # ifdef QUAD
102 # define strtol strtoull
103 # else
104 # define strtol strtoul
105 # endif
106 # endif
107 # else
108 # ifdef USE_WIDE_CHAR
109 # ifdef QUAD
110 # define strtol wcstoll
111 # else
112 # define strtol wcstol
113 # endif
114 # else
115 # ifdef QUAD
116 # define strtol strtoll
117 # endif
118 # endif
119 # endif
120 #endif
121
122 /* If QUAD is defined, we are defining `strtoll' or `strtoull',
123 operating on `long long int's. */
124 #ifdef QUAD
125 # define LONG long long
126 # define STRTOL_LONG_MIN LONG_LONG_MIN
127 # define STRTOL_LONG_MAX LONG_LONG_MAX
128 # define STRTOL_ULONG_MAX ULONG_LONG_MAX
129
130 /* The extra casts in the following macros work around compiler bugs,
131 e.g., in Cray C 5.0.3.0. */
132
133 /* True if negative values of the signed integer type T use two's
134 complement, ones' complement, or signed magnitude representation,
135 respectively. Much GNU code assumes two's complement, but some
136 people like to be portable to all possible C hosts. */
137 # define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
138 # define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
139 # define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
140
141 /* True if the arithmetic type T is signed. */
142 # define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
143
144 /* The maximum and minimum values for the integer type T. These
145 macros have undefined behavior if T is signed and has padding bits.
146 If this is a problem for you, please let us know how to fix it for
147 your host. */
148 # define TYPE_MINIMUM(t) \
149 ((t) (! TYPE_SIGNED (t) \
150 ? (t) 0 \
151 : TYPE_SIGNED_MAGNITUDE (t) \
152 ? ~ (t) 0 \
153 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
154 # define TYPE_MAXIMUM(t) \
155 ((t) (! TYPE_SIGNED (t) \
156 ? (t) -1 \
157 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
158
159 # ifndef ULONG_LONG_MAX
160 # define ULONG_LONG_MAX TYPE_MAXIMUM (unsigned long long)
161 # endif
162 # ifndef LONG_LONG_MAX
163 # define LONG_LONG_MAX TYPE_MAXIMUM (long long int)
164 # endif
165 # ifndef LONG_LONG_MIN
166 # define LONG_LONG_MIN TYPE_MINIMUM (long long int)
167 # endif
168
169 # if __GNUC__ == 2 && __GNUC_MINOR__ < 7
170 /* Work around gcc bug with using this constant. */
171 static const unsigned long long int maxquad = ULONG_LONG_MAX;
172 # undef STRTOL_ULONG_MAX
173 # define STRTOL_ULONG_MAX maxquad
174 # endif
175 #else
176 # define LONG long
177 # define STRTOL_LONG_MIN LONG_MIN
178 # define STRTOL_LONG_MAX LONG_MAX
179 # define STRTOL_ULONG_MAX ULONG_MAX
180 #endif
181
182
183 /* We use this code also for the extended locale handling where the
184 function gets as an additional argument the locale which has to be
185 used. To access the values we have to redefine the _NL_CURRENT
186 macro. */
187 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
188 # undef _NL_CURRENT
189 # define _NL_CURRENT(category, item) \
190 (current->values[_NL_ITEM_INDEX (item)].string)
191 # define LOCALE_PARAM , loc
192 # define LOCALE_PARAM_PROTO , __locale_t loc
193 #else
194 # define LOCALE_PARAM
195 # define LOCALE_PARAM_PROTO
196 #endif
197
198 #if defined _LIBC || defined HAVE_WCHAR_H
199 # include <wchar.h>
200 #endif
201
202 #ifdef USE_WIDE_CHAR
203 # include <wctype.h>
204 # define L_(Ch) L##Ch
205 # define UCHAR_TYPE wint_t
206 # define STRING_TYPE wchar_t
207 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
208 # define ISSPACE(Ch) __iswspace_l ((Ch), loc)
209 # define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
210 # define TOUPPER(Ch) __towupper_l ((Ch), loc)
211 # else
212 # define ISSPACE(Ch) iswspace (Ch)
213 # define ISALPHA(Ch) iswalpha (Ch)
214 # define TOUPPER(Ch) towupper (Ch)
215 # endif
216 #else
217 # if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
218 # define IN_CTYPE_DOMAIN(c) 1
219 # else
220 # define IN_CTYPE_DOMAIN(c) isascii(c)
221 # endif
222 # define L_(Ch) Ch
223 # define UCHAR_TYPE unsigned char
224 # define STRING_TYPE char
225 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
226 # define ISSPACE(Ch) __isspace_l ((Ch), loc)
227 # define ISALPHA(Ch) __isalpha_l ((Ch), loc)
228 # define TOUPPER(Ch) __toupper_l ((Ch), loc)
229 # else
230 # define ISSPACE(Ch) (IN_CTYPE_DOMAIN (Ch) && isspace (Ch))
231 # define ISALPHA(Ch) (IN_CTYPE_DOMAIN (Ch) && isalpha (Ch))
232 # define TOUPPER(Ch) (IN_CTYPE_DOMAIN (Ch) ? toupper (Ch) : (Ch))
233 # endif
234 #endif
235
236 #define INTERNAL(X) INTERNAL1(X)
237 #define INTERNAL1(X) __##X##_internal
238 #define WEAKNAME(X) WEAKNAME1(X)
239
240 #ifdef USE_NUMBER_GROUPING
241 /* This file defines a function to check for correct grouping. */
242 # include "grouping.h"
243 #endif
244
245
246
247 /* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
248 If BASE is 0 the base is determined by the presence of a leading
249 zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
250 If BASE is < 2 or > 36, it is reset to 10.
251 If ENDPTR is not NULL, a pointer to the character after the last
252 one converted is stored in *ENDPTR. */
253
254 INT
INTERNAL(strtol)255 INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr,
256 int base, int group LOCALE_PARAM_PROTO)
257 {
258 int negative;
259 register unsigned LONG int cutoff;
260 register unsigned int cutlim;
261 register unsigned LONG int i;
262 register const STRING_TYPE *s;
263 register UCHAR_TYPE c;
264 const STRING_TYPE *save, *end;
265 int overflow;
266
267 #ifdef USE_NUMBER_GROUPING
268 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
269 struct locale_data *current = loc->__locales[LC_NUMERIC];
270 # endif
271 /* The thousands character of the current locale. */
272 wchar_t thousands = L'\0';
273 /* The numeric grouping specification of the current locale,
274 in the format described in <locale.h>. */
275 const char *grouping;
276
277 if (group)
278 {
279 grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
280 if (*grouping <= 0 || *grouping == CHAR_MAX)
281 grouping = NULL;
282 else
283 {
284 /* Figure out the thousands separator character. */
285 # if defined _LIBC || defined _HAVE_BTOWC
286 thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP));
287 if (thousands == WEOF)
288 thousands = L'\0';
289 # endif
290 if (thousands == L'\0')
291 grouping = NULL;
292 }
293 }
294 else
295 grouping = NULL;
296 #endif
297
298 if (base < 0 || base == 1 || base > 36)
299 {
300 __set_errno (EINVAL);
301 return 0;
302 }
303
304 save = s = nptr;
305
306 /* Skip white space. */
307 while (ISSPACE (*s))
308 ++s;
309 if (*s == L_('\0'))
310 goto noconv;
311
312 /* Check for a sign. */
313 if (*s == L_('-'))
314 {
315 negative = 1;
316 ++s;
317 }
318 else if (*s == L_('+'))
319 {
320 negative = 0;
321 ++s;
322 }
323 else
324 negative = 0;
325
326 /* Recognize number prefix and if BASE is zero, figure it out ourselves. */
327 if (*s == L_('0'))
328 {
329 if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
330 {
331 s += 2;
332 base = 16;
333 }
334 else if (base == 0)
335 base = 8;
336 }
337 else if (base == 0)
338 base = 10;
339
340 /* Save the pointer so we can check later if anything happened. */
341 save = s;
342
343 #ifdef USE_NUMBER_GROUPING
344 if (group)
345 {
346 /* Find the end of the digit string and check its grouping. */
347 end = s;
348 for (c = *end; c != L_('\0'); c = *++end)
349 if ((wchar_t) c != thousands
350 && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
351 && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base))
352 break;
353 if (*s == thousands)
354 end = s;
355 else
356 end = correctly_grouped_prefix (s, end, thousands, grouping);
357 }
358 else
359 #endif
360 end = NULL;
361
362 cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
363 cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
364
365 overflow = 0;
366 i = 0;
367 for (c = *s; c != L_('\0'); c = *++s)
368 {
369 if (s == end)
370 break;
371 if (c >= L_('0') && c <= L_('9'))
372 c -= L_('0');
373 else if (ISALPHA (c))
374 c = TOUPPER (c) - L_('A') + 10;
375 else
376 break;
377 if ((int) c >= base)
378 break;
379 /* Check for overflow. */
380 if (i > cutoff || (i == cutoff && c > cutlim))
381 overflow = 1;
382 else
383 {
384 i *= (unsigned LONG int) base;
385 i += c;
386 }
387 }
388
389 /* Check if anything actually happened. */
390 if (s == save)
391 goto noconv;
392
393 /* Store in ENDPTR the address of one character
394 past the last character we converted. */
395 if (endptr != NULL)
396 *endptr = (STRING_TYPE *) s;
397
398 #if !UNSIGNED
399 /* Check for a value that is within the range of
400 `unsigned LONG int', but outside the range of `LONG int'. */
401 if (overflow == 0
402 && i > (negative
403 ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
404 : (unsigned LONG int) STRTOL_LONG_MAX))
405 overflow = 1;
406 #endif
407
408 if (overflow)
409 {
410 __set_errno (ERANGE);
411 #if UNSIGNED
412 return STRTOL_ULONG_MAX;
413 #else
414 return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
415 #endif
416 }
417
418 /* Return the result of the appropriate sign. */
419 return negative ? -i : i;
420
421 noconv:
422 /* We must handle a special case here: the base is 0 or 16 and the
423 first two characters are '0' and 'x', but the rest are no
424 hexadecimal digits. This is no error case. We return 0 and
425 ENDPTR points to the `x`. */
426 if (endptr != NULL)
427 {
428 if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
429 && save[-2] == L_('0'))
430 *endptr = (STRING_TYPE *) &save[-1];
431 else
432 /* There was no number to convert. */
433 *endptr = (STRING_TYPE *) nptr;
434 }
435
436 return 0L;
437 }
438
439 /* External user entry point. */
440
441
442 INT
443 #ifdef weak_function
444 weak_function
445 #endif
strtol(const STRING_TYPE * nptr,STRING_TYPE ** endptr,int base LOCALE_PARAM_PROTO)446 strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr,
447 int base LOCALE_PARAM_PROTO)
448 {
449 return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
450 }
451