xref: /haiku/src/system/libroot/posix/glibc/stdlib/strtol.c (revision 579f1dbca962a2a03df54f69fdc6e9423f91f20e)
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 
33 #ifdef HAVE_LIMITS_H
34 # include <limits.h>
35 #endif
36 
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
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 # 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
137 
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
148 
149 
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
164 
165 #if defined _LIBC || defined HAVE_WCHAR_H
166 # include <wchar.h>
167 #endif
168 
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
202 
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
210 
211 #ifdef USE_NUMBER_GROUPING
212 /* This file defines a function to check for correct grouping.  */
213 # include "grouping.h"
214 #endif
215 
216 
217 
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.  */
224 
225 INT
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
232 {
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
244 
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;
259 
260   if (__builtin_expect (group, 0))
261     {
262       grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
263       if (*grouping <= 0 || *grouping == CHAR_MAX)
264 	grouping = NULL;
265       else
266 	{
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')
280 	    {
281 	      thousands = NULL;
282 	      grouping = NULL;
283 	    }
284 # endif
285 	}
286     }
287   else
288     grouping = NULL;
289 #endif
290 
291   if (base < 0 || base == 1 || base > 36)
292     {
293       __set_errno (EINVAL);
294       return 0;
295     }
296 
297   save = s = nptr;
298 
299   /* Skip white space.  */
300   while (ISSPACE (*s))
301     ++s;
302   if (__builtin_expect (*s == L_('\0'), 0))
303     goto noconv;
304 
305   /* Check for a sign.  */
306   negative = 0;
307   if (*s == L_('-'))
308     {
309       negative = 1;
310       ++s;
311     }
312   else if (*s == L_('+'))
313     ++s;
314 
315   /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
316   if (*s == L_('0'))
317     {
318       if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
319 	{
320 	  s += 2;
321 	  base = 16;
322 	}
323       else if (base == 0)
324 	base = 8;
325     }
326   else if (base == 0)
327     base = 10;
328 
329   /* Save the pointer so we can check later if anything happened.  */
330   save = s;
331 
332 #ifdef USE_NUMBER_GROUPING
333   if (base != 10)
334     grouping = NULL;
335 
336   if (__builtin_expect (grouping != NULL, 0))
337     {
338 # ifndef USE_WIDE_CHAR
339       thousands_len = strlen (thousands);
340 # endif
341 
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
353 	  )
354 	{
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;
368 
369 	  end = correctly_grouped_prefix (s, end, thousands, grouping);
370 	}
371     }
372   else
373 #endif
374     end = NULL;
375 
376   cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
377   cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
378 
379   overflow = 0;
380   i = 0;
381   c = *s;
382   if (sizeof (long int) != sizeof (LONG int))
383     {
384       unsigned long int j = 0;
385       unsigned long int jmax = ULONG_MAX / base;
386 
387       for (;c != L_('\0'); c = *++s)
388 	{
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)
399 	    {
400 	      for (cnt = 0; cnt < thousands_len; ++cnt)
401 		if (thousands[cnt] != s[cnt])
402 		  break;
403 	      if (cnt == thousands_len)
404 		{
405 		  s += thousands_len - 1;
406 		  continue;
407 		}
408 	      if (ISALPHA (c))
409 		c = TOUPPER (c) - L_('A') + 10;
410 	      else
411 		break;
412 	    }
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)
423 	    {
424 	      /* We have an overflow.  Now use the long representation.  */
425 	      i = (unsigned LONG int) j;
426 	      goto use_long;
427 	    }
428 	  else
429 	    j = j * (unsigned long int) base + c;
430 	}
431 
432       i = (unsigned LONG int) j;
433     }
434   else
435     for (;c != L_('\0'); c = *++s)
436       {
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)
447 	  {
448 	    for (cnt = 0; cnt < thousands_len; ++cnt)
449 	      if (thousands[cnt] != s[cnt])
450 		break;
451 	    if (cnt == thousands_len)
452 	      {
453 		s += thousands_len - 1;
454 		continue;
455 	      }
456 	    if (ISALPHA (c))
457 	      c = TOUPPER (c) - L_('A') + 10;
458 	    else
459 	      break;
460 	  }
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
473 	  {
474 	  use_long:
475 	    i *= (unsigned LONG int) base;
476 	    i += c;
477 	  }
478       }
479 
480   /* Check if anything actually happened.  */
481   if (s == save)
482     goto noconv;
483 
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;
488 
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
498 
499   if (__builtin_expect (overflow, 0))
500     {
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
507     }
508 
509   /* Return the result of the appropriate sign.  */
510   return negative ? -i : i;
511 
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)
518     {
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;
525     }
526 
527   return 0L;
528 }
529 
530 /* External user entry point.  */
531 
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
539 
540 /* Prototype.  */
541 INT strtol PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, int base));
542 #endif
543 
544 
545 INT
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
554 {
555   return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
556 }
557