libroot_debug: Merge guarded heap into libroot_debug.
[haiku.git] / src / system / libroot / posix / glibc / stdlib / strtol.c
blobeb8602f63742808c261a4f4c378bf4ba0029eab9
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.
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.
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.
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. */
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #ifdef _LIBC
25 # define USE_NUMBER_GROUPING
26 # define STDC_HEADERS
27 # define HAVE_LIMITS_H
28 #endif
30 #include <ctype.h>
31 #include <errno.h>
33 #ifdef HAVE_LIMITS_H
34 # include <limits.h>
35 #endif
37 #ifdef STDC_HEADERS
38 # include <stddef.h>
39 # include <stdlib.h>
40 # include <string.h>
41 # include <locale.h>
42 #else
43 # ifndef NULL
44 # define NULL 0
45 # endif
46 #endif
48 #ifdef USE_NUMBER_GROUPING
49 # include "../locale/localeinfo.h"
50 #endif
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
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
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 # if __GNUC__ == 2 && __GNUC_MINOR__ < 7
130 /* Work around gcc bug with using this constant. */
131 static const unsigned long long int maxquad = ULONG_LONG_MAX;
132 # undef STRTOL_ULONG_MAX
133 # define STRTOL_ULONG_MAX maxquad
134 # endif
135 #else
136 # define LONG long
138 # ifndef ULONG_MAX
139 # define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
140 # endif
141 # ifndef LONG_MAX
142 # define LONG_MAX ((long int) (ULONG_MAX >> 1))
143 # endif
144 # define STRTOL_LONG_MIN LONG_MIN
145 # define STRTOL_LONG_MAX LONG_MAX
146 # define STRTOL_ULONG_MAX ULONG_MAX
147 #endif
150 /* We use this code also for the extended locale handling where the
151 function gets as an additional argument the locale which has to be
152 used. To access the values we have to redefine the _NL_CURRENT
153 macro. */
154 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
155 # undef _NL_CURRENT
156 # define _NL_CURRENT(category, item) \
157 (current->values[_NL_ITEM_INDEX (item)].string)
158 # define LOCALE_PARAM , loc
159 # define LOCALE_PARAM_DECL __locale_t loc;
160 #else
161 # define LOCALE_PARAM
162 # define LOCALE_PARAM_DECL
163 #endif
165 #if defined _LIBC || defined HAVE_WCHAR_H
166 # include <wchar.h>
167 #endif
169 #ifdef USE_WIDE_CHAR
170 # include <wctype.h>
171 # define L_(Ch) L##Ch
172 # define UCHAR_TYPE wint_t
173 # define STRING_TYPE wchar_t
174 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
175 # define ISSPACE(Ch) __iswspace_l ((Ch), loc)
176 # define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
177 # define TOUPPER(Ch) __towupper_l ((Ch), loc)
178 # else
179 # define ISSPACE(Ch) iswspace (Ch)
180 # define ISALPHA(Ch) iswalpha (Ch)
181 # define TOUPPER(Ch) towupper (Ch)
182 # endif
183 # else
184 # if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
185 # define IN_CTYPE_DOMAIN(c) 1
186 # else
187 # define IN_CTYPE_DOMAIN(c) isascii(c)
188 # endif
189 # define L_(Ch) Ch
190 # define UCHAR_TYPE unsigned char
191 # define STRING_TYPE char
192 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
193 # define ISSPACE(Ch) __isspace_l ((Ch), loc)
194 # define ISALPHA(Ch) __isalpha_l ((Ch), loc)
195 # define TOUPPER(Ch) __toupper_l ((Ch), loc)
196 # else
197 # define ISSPACE(Ch) (IN_CTYPE_DOMAIN (Ch) && isspace (Ch))
198 # define ISALPHA(Ch) (IN_CTYPE_DOMAIN (Ch) && isalpha (Ch))
199 # define TOUPPER(Ch) (IN_CTYPE_DOMAIN (Ch) ? toupper (Ch) : (Ch))
200 # endif
201 #endif
203 #ifdef __STDC__
204 # define INTERNAL(X) INTERNAL1(X)
205 # define INTERNAL1(X) __##X##_internal
206 # define WEAKNAME(X) WEAKNAME1(X)
207 #else
208 # define INTERNAL(X) __/**/X/**/_internal
209 #endif
211 #ifdef USE_NUMBER_GROUPING
212 /* This file defines a function to check for correct grouping. */
213 # include "grouping.h"
214 #endif
218 /* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
219 If BASE is 0 the base is determined by the presence of a leading
220 zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
221 If BASE is < 2 or > 36, it is reset to 10.
222 If ENDPTR is not NULL, a pointer to the character after the last
223 one converted is stored in *ENDPTR. */
226 INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
227 const STRING_TYPE *nptr;
228 STRING_TYPE **endptr;
229 int base;
230 int group;
231 LOCALE_PARAM_DECL
233 int negative;
234 register unsigned LONG int cutoff;
235 register unsigned int cutlim;
236 register unsigned LONG int i;
237 register const STRING_TYPE *s;
238 register UCHAR_TYPE c;
239 const STRING_TYPE *save, *end;
240 int overflow;
241 #ifndef USE_WIDE_CHAR
242 size_t cnt;
243 #endif
245 #ifdef USE_NUMBER_GROUPING
246 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
247 struct locale_data *current = loc->__locales[LC_NUMERIC];
248 # endif
249 /* The thousands character of the current locale. */
250 # ifdef USE_WIDE_CHAR
251 wchar_t thousands = L'\0';
252 # else
253 const char *thousands = NULL;
254 size_t thousands_len = 0;
255 # endif
256 /* The numeric grouping specification of the current locale,
257 in the format described in <locale.h>. */
258 const char *grouping;
260 if (__builtin_expect (group, 0))
262 grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
263 if (*grouping <= 0 || *grouping == CHAR_MAX)
264 grouping = NULL;
265 else
267 /* Figure out the thousands separator character. */
268 # ifdef USE_WIDE_CHAR
269 # ifdef _LIBC
270 thousands = _NL_CURRENT_WORD (LC_NUMERIC,
271 _NL_NUMERIC_THOUSANDS_SEP_WC);
272 # endif
273 if (thousands == L'\0')
274 grouping = NULL;
275 # else
276 # ifdef _LIBC
277 thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
278 # endif
279 if (*thousands == '\0')
281 thousands = NULL;
282 grouping = NULL;
284 # endif
287 else
288 grouping = NULL;
289 #endif
291 if (base < 0 || base == 1 || base > 36)
293 __set_errno (EINVAL);
294 return 0;
297 save = s = nptr;
299 /* Skip white space. */
300 while (ISSPACE (*s))
301 ++s;
302 if (__builtin_expect (*s == L_('\0'), 0))
303 goto noconv;
305 /* Check for a sign. */
306 negative = 0;
307 if (*s == L_('-'))
309 negative = 1;
310 ++s;
312 else if (*s == L_('+'))
313 ++s;
315 /* Recognize number prefix and if BASE is zero, figure it out ourselves. */
316 if (*s == L_('0'))
318 if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
320 s += 2;
321 base = 16;
323 else if (base == 0)
324 base = 8;
326 else if (base == 0)
327 base = 10;
329 /* Save the pointer so we can check later if anything happened. */
330 save = s;
332 #ifdef USE_NUMBER_GROUPING
333 if (base != 10)
334 grouping = NULL;
336 if (__builtin_expect (grouping != NULL, 0))
338 # ifndef USE_WIDE_CHAR
339 thousands_len = strlen (thousands);
340 # endif
342 /* Find the end of the digit string and check its grouping. */
343 end = s;
344 if (
345 # ifdef USE_WIDE_CHAR
346 *s != thousands
347 # else
348 ({ for (cnt = 0; cnt < thousands_len; ++cnt)
349 if (thousands[cnt] != end[cnt])
350 break;
351 cnt < thousands_len; })
352 # endif
355 for (c = *end; c != L_('\0'); c = *++end)
356 if (((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
357 # ifdef USE_WIDE_CHAR
358 && c != thousands
359 # else
360 && ({ for (cnt = 0; cnt < thousands_len; ++cnt)
361 if (thousands[cnt] != end[cnt])
362 break;
363 cnt < thousands_len; })
364 # endif
365 && (!ISALPHA (c)
366 || (int) (TOUPPER (c) - L_('A') + 10) >= base))
367 break;
369 end = correctly_grouped_prefix (s, end, thousands, grouping);
372 else
373 #endif
374 end = NULL;
376 cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
377 cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
379 overflow = 0;
380 i = 0;
381 c = *s;
382 if (sizeof (long int) != sizeof (LONG int))
384 unsigned long int j = 0;
385 unsigned long int jmax = ULONG_MAX / base;
387 for (;c != L_('\0'); c = *++s)
389 if (s == end)
390 break;
391 if (c >= L_('0') && c <= L_('9'))
392 c -= L_('0');
393 #ifdef USE_NUMBER_GROUPING
394 # ifdef USE_WIDE_CHAR
395 else if (grouping && c == thousands)
396 continue;
397 # else
398 else if (thousands_len)
400 for (cnt = 0; cnt < thousands_len; ++cnt)
401 if (thousands[cnt] != s[cnt])
402 break;
403 if (cnt == thousands_len)
405 s += thousands_len - 1;
406 continue;
408 if (ISALPHA (c))
409 c = TOUPPER (c) - L_('A') + 10;
410 else
411 break;
413 # endif
414 #endif
415 else if (ISALPHA (c))
416 c = TOUPPER (c) - L_('A') + 10;
417 else
418 break;
419 if ((int) c >= base)
420 break;
421 /* Note that we never can have an overflow. */
422 else if (j >= jmax)
424 /* We have an overflow. Now use the long representation. */
425 i = (unsigned LONG int) j;
426 goto use_long;
428 else
429 j = j * (unsigned long int) base + c;
432 i = (unsigned LONG int) j;
434 else
435 for (;c != L_('\0'); c = *++s)
437 if (s == end)
438 break;
439 if (c >= L_('0') && c <= L_('9'))
440 c -= L_('0');
441 #ifdef USE_NUMBER_GROUPING
442 # ifdef USE_WIDE_CHAR
443 else if (grouping && c == thousands)
444 continue;
445 # else
446 else if (thousands_len)
448 for (cnt = 0; cnt < thousands_len; ++cnt)
449 if (thousands[cnt] != s[cnt])
450 break;
451 if (cnt == thousands_len)
453 s += thousands_len - 1;
454 continue;
456 if (ISALPHA (c))
457 c = TOUPPER (c) - L_('A') + 10;
458 else
459 break;
461 # endif
462 #endif
463 else if (ISALPHA (c))
464 c = TOUPPER (c) - L_('A') + 10;
465 else
466 break;
467 if ((int) c >= base)
468 break;
469 /* Check for overflow. */
470 if (i > cutoff || (i == cutoff && c > cutlim))
471 overflow = 1;
472 else
474 use_long:
475 i *= (unsigned LONG int) base;
476 i += c;
480 /* Check if anything actually happened. */
481 if (s == save)
482 goto noconv;
484 /* Store in ENDPTR the address of one character
485 past the last character we converted. */
486 if (endptr != NULL)
487 *endptr = (STRING_TYPE *) s;
489 #if !UNSIGNED
490 /* Check for a value that is within the range of
491 `unsigned LONG int', but outside the range of `LONG int'. */
492 if (overflow == 0
493 && i > (negative
494 ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
495 : (unsigned LONG int) STRTOL_LONG_MAX))
496 overflow = 1;
497 #endif
499 if (__builtin_expect (overflow, 0))
501 __set_errno (ERANGE);
502 #if UNSIGNED
503 return STRTOL_ULONG_MAX;
504 #else
505 return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
506 #endif
509 /* Return the result of the appropriate sign. */
510 return negative ? -i : i;
512 noconv:
513 /* We must handle a special case here: the base is 0 or 16 and the
514 first two characters are '0' and 'x', but the rest are no
515 hexadecimal digits. This is no error case. We return 0 and
516 ENDPTR points to the `x`. */
517 if (endptr != NULL)
519 if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
520 && save[-2] == L_('0'))
521 *endptr = (STRING_TYPE *) &save[-1];
522 else
523 /* There was no number to convert. */
524 *endptr = (STRING_TYPE *) nptr;
527 return 0L;
530 /* External user entry point. */
532 #if _LIBC - 0 == 0
533 # undef PARAMS
534 # if defined (__STDC__) && __STDC__
535 # define PARAMS(Args) Args
536 # else
537 # define PARAMS(Args) ()
538 # endif
540 /* Prototype. */
541 INT strtol PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, int base));
542 #endif
546 #ifdef weak_function
547 weak_function
548 #endif
549 strtol (nptr, endptr, base LOCALE_PARAM)
550 const STRING_TYPE *nptr;
551 STRING_TYPE **endptr;
552 int base;
553 LOCALE_PARAM_DECL
555 return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);