]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/generic/strtol.c
Update to LGPL v2.1.
[thirdparty/glibc.git] / sysdeps / generic / strtol.c
1 /* Convert string representation of a number into an integer value.
2 Copyright (C) 1991,92,94,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #ifdef _LIBC
25 # define USE_NUMBER_GROUPING
26 # define STDC_HEADERS
27 # define HAVE_LIMITS_H
28 #endif
29
30 #include <ctype.h>
31 #include <errno.h>
32 #ifndef errno
33 extern int errno;
34 #endif
35 #ifndef __set_errno
36 # define __set_errno(Val) errno = (Val)
37 #endif
38
39 #ifdef HAVE_LIMITS_H
40 # include <limits.h>
41 #endif
42
43 #ifdef STDC_HEADERS
44 # include <stddef.h>
45 # include <stdlib.h>
46 # include <string.h>
47 # include <locale.h>
48 #else
49 # ifndef NULL
50 # define NULL 0
51 # endif
52 #endif
53
54 #ifdef USE_NUMBER_GROUPING
55 # include "../locale/localeinfo.h"
56 #endif
57
58 /* Nonzero if we are defining `strtoul' or `strtoull', operating on
59 unsigned integers. */
60 #ifndef UNSIGNED
61 # define UNSIGNED 0
62 # define INT LONG int
63 #else
64 # define INT unsigned LONG int
65 #endif
66
67 /* Determine the name. */
68 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
69 # if UNSIGNED
70 # ifdef USE_WIDE_CHAR
71 # ifdef QUAD
72 # define strtol __wcstoull_l
73 # else
74 # define strtol __wcstoul_l
75 # endif
76 # else
77 # ifdef QUAD
78 # define strtol __strtoull_l
79 # else
80 # define strtol __strtoul_l
81 # endif
82 # endif
83 # else
84 # ifdef USE_WIDE_CHAR
85 # ifdef QUAD
86 # define strtol __wcstoll_l
87 # else
88 # define strtol __wcstol_l
89 # endif
90 # else
91 # ifdef QUAD
92 # define strtol __strtoll_l
93 # else
94 # define strtol __strtol_l
95 # endif
96 # endif
97 # endif
98 #else
99 # if UNSIGNED
100 # ifdef USE_WIDE_CHAR
101 # ifdef QUAD
102 # define strtol wcstoull
103 # else
104 # define strtol wcstoul
105 # endif
106 # else
107 # ifdef QUAD
108 # define strtol strtoull
109 # else
110 # define strtol strtoul
111 # endif
112 # endif
113 # else
114 # ifdef USE_WIDE_CHAR
115 # ifdef QUAD
116 # define strtol wcstoll
117 # else
118 # define strtol wcstol
119 # endif
120 # else
121 # ifdef QUAD
122 # define strtol strtoll
123 # endif
124 # endif
125 # endif
126 #endif
127
128 /* If QUAD is defined, we are defining `strtoll' or `strtoull',
129 operating on `long long int's. */
130 #ifdef QUAD
131 # define LONG long long
132 # define STRTOL_LONG_MIN LONG_LONG_MIN
133 # define STRTOL_LONG_MAX LONG_LONG_MAX
134 # define STRTOL_ULONG_MAX ULONG_LONG_MAX
135 # if __GNUC__ == 2 && __GNUC_MINOR__ < 7
136 /* Work around gcc bug with using this constant. */
137 static const unsigned long long int maxquad = ULONG_LONG_MAX;
138 # undef STRTOL_ULONG_MAX
139 # define STRTOL_ULONG_MAX maxquad
140 # endif
141 #else
142 # define LONG long
143
144 # ifndef ULONG_MAX
145 # define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
146 # endif
147 # ifndef LONG_MAX
148 # define LONG_MAX ((long int) (ULONG_MAX >> 1))
149 # endif
150 # define STRTOL_LONG_MIN LONG_MIN
151 # define STRTOL_LONG_MAX LONG_MAX
152 # define STRTOL_ULONG_MAX ULONG_MAX
153 #endif
154
155
156 /* We use this code also for the extended locale handling where the
157 function gets as an additional argument the locale which has to be
158 used. To access the values we have to redefine the _NL_CURRENT
159 macro. */
160 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
161 # undef _NL_CURRENT
162 # define _NL_CURRENT(category, item) \
163 (current->values[_NL_ITEM_INDEX (item)].string)
164 # define LOCALE_PARAM , loc
165 # define LOCALE_PARAM_DECL __locale_t loc;
166 #else
167 # define LOCALE_PARAM
168 # define LOCALE_PARAM_DECL
169 #endif
170
171 #if defined _LIBC || defined HAVE_WCHAR_H
172 # include <wchar.h>
173 #endif
174
175 #ifdef USE_WIDE_CHAR
176 # include <wctype.h>
177 # define L_(Ch) L##Ch
178 # define UCHAR_TYPE wint_t
179 # define STRING_TYPE wchar_t
180 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
181 # define ISSPACE(Ch) __iswspace_l ((Ch), loc)
182 # define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
183 # define TOUPPER(Ch) __towupper_l ((Ch), loc)
184 # else
185 # define ISSPACE(Ch) iswspace (Ch)
186 # define ISALPHA(Ch) iswalpha (Ch)
187 # define TOUPPER(Ch) towupper (Ch)
188 # endif
189 # else
190 # if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
191 # define IN_CTYPE_DOMAIN(c) 1
192 # else
193 # define IN_CTYPE_DOMAIN(c) isascii(c)
194 # endif
195 # define L_(Ch) Ch
196 # define UCHAR_TYPE unsigned char
197 # define STRING_TYPE char
198 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
199 # define ISSPACE(Ch) __isspace_l ((Ch), loc)
200 # define ISALPHA(Ch) __isalpha_l ((Ch), loc)
201 # define TOUPPER(Ch) __toupper_l ((Ch), loc)
202 # else
203 # define ISSPACE(Ch) (IN_CTYPE_DOMAIN (Ch) && isspace (Ch))
204 # define ISALPHA(Ch) (IN_CTYPE_DOMAIN (Ch) && isalpha (Ch))
205 # define TOUPPER(Ch) (IN_CTYPE_DOMAIN (Ch) ? toupper (Ch) : (Ch))
206 # endif
207 #endif
208
209 #ifdef __STDC__
210 # define INTERNAL(X) INTERNAL1(X)
211 # define INTERNAL1(X) __##X##_internal
212 # define WEAKNAME(X) WEAKNAME1(X)
213 #else
214 # define INTERNAL(X) __/**/X/**/_internal
215 #endif
216
217 #ifdef USE_NUMBER_GROUPING
218 /* This file defines a function to check for correct grouping. */
219 # include "grouping.h"
220 #endif
221
222
223
224 /* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
225 If BASE is 0 the base is determined by the presence of a leading
226 zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
227 If BASE is < 2 or > 36, it is reset to 10.
228 If ENDPTR is not NULL, a pointer to the character after the last
229 one converted is stored in *ENDPTR. */
230
231 INT
232 INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
233 const STRING_TYPE *nptr;
234 STRING_TYPE **endptr;
235 int base;
236 int group;
237 LOCALE_PARAM_DECL
238 {
239 int negative;
240 register unsigned LONG int cutoff;
241 register unsigned int cutlim;
242 register unsigned LONG int i;
243 register const STRING_TYPE *s;
244 register UCHAR_TYPE c;
245 const STRING_TYPE *save, *end;
246 int overflow;
247 #ifndef USE_WIDE_CHAR
248 size_t cnt;
249 #endif
250
251 #ifdef USE_NUMBER_GROUPING
252 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
253 struct locale_data *current = loc->__locales[LC_NUMERIC];
254 # endif
255 /* The thousands character of the current locale. */
256 # ifdef USE_WIDE_CHAR
257 wchar_t thousands = L'\0';
258 # else
259 const char *thousands = NULL;
260 size_t thousands_len = 0;
261 # endif
262 /* The numeric grouping specification of the current locale,
263 in the format described in <locale.h>. */
264 const char *grouping;
265
266 if (group)
267 {
268 grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
269 if (*grouping <= 0 || *grouping == CHAR_MAX)
270 grouping = NULL;
271 else
272 {
273 /* Figure out the thousands separator character. */
274 # ifdef USE_WIDE_CHAR
275 # ifdef _LIBC
276 thousands = _NL_CURRENT_WORD (LC_NUMERIC,
277 _NL_NUMERIC_THOUSANDS_SEP_WC);
278 # endif
279 if (thousands == L'\0')
280 grouping = NULL;
281 # else
282 # ifdef _LIBC
283 thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
284 # endif
285 if (*thousands == '\0')
286 {
287 thousands = NULL;
288 grouping = NULL;
289 }
290 # endif
291 }
292 }
293 else
294 grouping = NULL;
295 #endif
296
297 if (base < 0 || base == 1 || base > 36)
298 {
299 __set_errno (EINVAL);
300 return 0;
301 }
302
303 save = s = nptr;
304
305 /* Skip white space. */
306 while (ISSPACE (*s))
307 ++s;
308 if (*s == L_('\0'))
309 goto noconv;
310
311 /* Check for a sign. */
312 if (*s == L_('-'))
313 {
314 negative = 1;
315 ++s;
316 }
317 else if (*s == L_('+'))
318 {
319 negative = 0;
320 ++s;
321 }
322 else
323 negative = 0;
324
325 /* Recognize number prefix and if BASE is zero, figure it out ourselves. */
326 if (*s == L_('0'))
327 {
328 if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
329 {
330 s += 2;
331 base = 16;
332 }
333 else if (base == 0)
334 base = 8;
335 }
336 else if (base == 0)
337 base = 10;
338
339 /* Save the pointer so we can check later if anything happened. */
340 save = s;
341
342 #ifdef USE_NUMBER_GROUPING
343 if (base != 10)
344 grouping = NULL;
345
346 if (grouping)
347 {
348 # ifndef USE_WIDE_CHAR
349 thousands_len = strlen (thousands);
350 # endif
351
352 /* Find the end of the digit string and check its grouping. */
353 end = s;
354 if (
355 # ifdef USE_WIDE_CHAR
356 *s != thousands
357 # else
358 ({ for (cnt = 0; cnt < thousands_len; ++cnt)
359 if (thousands[cnt] != end[cnt])
360 break;
361 cnt < thousands_len; })
362 # endif
363 )
364 {
365 for (c = *end; c != L_('\0'); c = *++end)
366 if (((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
367 # ifdef USE_WIDE_CHAR
368 && c != thousands
369 # else
370 && ({ for (cnt = 0; cnt < thousands_len; ++cnt)
371 if (thousands[cnt] != end[cnt])
372 break;
373 cnt < thousands_len; })
374 # endif
375 && (!ISALPHA (c)
376 || (int) (TOUPPER (c) - L_('A') + 10) >= base))
377 break;
378
379 end = correctly_grouped_prefix (s, end, thousands, grouping);
380 }
381 }
382 else
383 #endif
384 end = NULL;
385
386 cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
387 cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
388
389 overflow = 0;
390 i = 0;
391 c = *s;
392 if (sizeof (long int) != sizeof (LONG int))
393 {
394 unsigned long int j = 0;
395 unsigned long int jmax = ULONG_MAX / base;
396
397 for (;c != L_('\0'); c = *++s)
398 {
399 if (s == end)
400 break;
401 if (c >= L_('0') && c <= L_('9'))
402 c -= L_('0');
403 #ifdef USE_NUMBER_GROUPING
404 # ifdef USE_WIDE_CHAR
405 else if (grouping && c == thousands)
406 continue;
407 # else
408 else if (thousands_len)
409 {
410 for (cnt = 0; cnt < thousands_len; ++cnt)
411 if (thousands[cnt] != s[cnt])
412 break;
413 if (cnt == thousands_len)
414 {
415 s += thousands_len - 1;
416 continue;
417 }
418 if (ISALPHA (c))
419 c = TOUPPER (c) - L_('A') + 10;
420 else
421 break;
422 }
423 # endif
424 #endif
425 else if (ISALPHA (c))
426 c = TOUPPER (c) - L_('A') + 10;
427 else
428 break;
429 if ((int) c >= base)
430 break;
431 /* Note that we never can have an overflow. */
432 else if (j >= jmax)
433 {
434 /* We have an overflow. Now use the long representation. */
435 i = (unsigned LONG int) j;
436 goto use_long;
437 }
438 else
439 j = j * (unsigned long int) base + c;
440 }
441
442 i = (unsigned LONG int) j;
443 }
444 else
445 for (;c != L_('\0'); c = *++s)
446 {
447 if (s == end)
448 break;
449 if (c >= L_('0') && c <= L_('9'))
450 c -= L_('0');
451 #ifdef USE_NUMBER_GROUPING
452 # ifdef USE_WIDE_CHAR
453 else if (grouping && c == thousands)
454 continue;
455 # else
456 else if (thousands_len)
457 {
458 for (cnt = 0; cnt < thousands_len; ++cnt)
459 if (thousands[cnt] != s[cnt])
460 break;
461 if (cnt == thousands_len)
462 {
463 s += thousands_len - 1;
464 continue;
465 }
466 if (ISALPHA (c))
467 c = TOUPPER (c) - L_('A') + 10;
468 else
469 break;
470 }
471 # endif
472 #endif
473 else if (ISALPHA (c))
474 c = TOUPPER (c) - L_('A') + 10;
475 else
476 break;
477 if ((int) c >= base)
478 break;
479 /* Check for overflow. */
480 if (i > cutoff || (i == cutoff && c > cutlim))
481 overflow = 1;
482 else
483 {
484 use_long:
485 i *= (unsigned LONG int) base;
486 i += c;
487 }
488 }
489
490 /* Check if anything actually happened. */
491 if (s == save)
492 goto noconv;
493
494 /* Store in ENDPTR the address of one character
495 past the last character we converted. */
496 if (endptr != NULL)
497 *endptr = (STRING_TYPE *) s;
498
499 #if !UNSIGNED
500 /* Check for a value that is within the range of
501 `unsigned LONG int', but outside the range of `LONG int'. */
502 if (overflow == 0
503 && i > (negative
504 ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
505 : (unsigned LONG int) STRTOL_LONG_MAX))
506 overflow = 1;
507 #endif
508
509 if (overflow)
510 {
511 __set_errno (ERANGE);
512 #if UNSIGNED
513 return STRTOL_ULONG_MAX;
514 #else
515 return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
516 #endif
517 }
518
519 /* Return the result of the appropriate sign. */
520 return negative ? -i : i;
521
522 noconv:
523 /* We must handle a special case here: the base is 0 or 16 and the
524 first two characters are '0' and 'x', but the rest are no
525 hexadecimal digits. This is no error case. We return 0 and
526 ENDPTR points to the `x`. */
527 if (endptr != NULL)
528 {
529 if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
530 && save[-2] == L_('0'))
531 *endptr = (STRING_TYPE *) &save[-1];
532 else
533 /* There was no number to convert. */
534 *endptr = (STRING_TYPE *) nptr;
535 }
536
537 return 0L;
538 }
539 \f
540 /* External user entry point. */
541
542 #if _LIBC - 0 == 0
543 # undef PARAMS
544 # if defined (__STDC__) && __STDC__
545 # define PARAMS(Args) Args
546 # else
547 # define PARAMS(Args) ()
548 # endif
549
550 /* Prototype. */
551 INT strtol PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, int base));
552 #endif
553
554
555 INT
556 #ifdef weak_function
557 weak_function
558 #endif
559 strtol (nptr, endptr, base LOCALE_PARAM)
560 const STRING_TYPE *nptr;
561 STRING_TYPE **endptr;
562 int base;
563 LOCALE_PARAM_DECL
564 {
565 return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
566 }