xref: /haiku/src/system/libroot/posix/glibc/stdlib/strtol.c (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
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 (__builtin_expect (group, 0))
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 (__builtin_expect (*s == L_('\0'), 0))
309     goto noconv;
310 
311   /* Check for a sign.  */
312   negative = 0;
313   if (*s == L_('-'))
314     {
315       negative = 1;
316       ++s;
317     }
318   else if (*s == L_('+'))
319     ++s;
320 
321   /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
322   if (*s == L_('0'))
323     {
324       if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
325 	{
326 	  s += 2;
327 	  base = 16;
328 	}
329       else if (base == 0)
330 	base = 8;
331     }
332   else if (base == 0)
333     base = 10;
334 
335   /* Save the pointer so we can check later if anything happened.  */
336   save = s;
337 
338 #ifdef USE_NUMBER_GROUPING
339   if (base != 10)
340     grouping = NULL;
341 
342   if (__builtin_expect (grouping != NULL, 0))
343     {
344 # ifndef USE_WIDE_CHAR
345       thousands_len = strlen (thousands);
346 # endif
347 
348       /* Find the end of the digit string and check its grouping.  */
349       end = s;
350       if (
351 # ifdef USE_WIDE_CHAR
352 	  *s != thousands
353 # else
354 	  ({ for (cnt = 0; cnt < thousands_len; ++cnt)
355 	       if (thousands[cnt] != end[cnt])
356 		 break;
357 	     cnt < thousands_len; })
358 # endif
359 	  )
360 	{
361 	  for (c = *end; c != L_('\0'); c = *++end)
362 	    if (((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
363 # ifdef USE_WIDE_CHAR
364 		&& c != thousands
365 # else
366 		&& ({ for (cnt = 0; cnt < thousands_len; ++cnt)
367 		      if (thousands[cnt] != end[cnt])
368 			break;
369 		      cnt < thousands_len; })
370 # endif
371 		&& (!ISALPHA (c)
372 		    || (int) (TOUPPER (c) - L_('A') + 10) >= base))
373 	      break;
374 
375 	  end = correctly_grouped_prefix (s, end, thousands, grouping);
376 	}
377     }
378   else
379 #endif
380     end = NULL;
381 
382   cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
383   cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
384 
385   overflow = 0;
386   i = 0;
387   c = *s;
388   if (sizeof (long int) != sizeof (LONG int))
389     {
390       unsigned long int j = 0;
391       unsigned long int jmax = ULONG_MAX / base;
392 
393       for (;c != L_('\0'); c = *++s)
394 	{
395 	  if (s == end)
396 	    break;
397 	  if (c >= L_('0') && c <= L_('9'))
398 	    c -= L_('0');
399 #ifdef USE_NUMBER_GROUPING
400 # ifdef USE_WIDE_CHAR
401 	  else if (grouping && c == thousands)
402 	    continue;
403 # else
404 	  else if (thousands_len)
405 	    {
406 	      for (cnt = 0; cnt < thousands_len; ++cnt)
407 		if (thousands[cnt] != s[cnt])
408 		  break;
409 	      if (cnt == thousands_len)
410 		{
411 		  s += thousands_len - 1;
412 		  continue;
413 		}
414 	      if (ISALPHA (c))
415 		c = TOUPPER (c) - L_('A') + 10;
416 	      else
417 		break;
418 	    }
419 # endif
420 #endif
421 	  else if (ISALPHA (c))
422 	    c = TOUPPER (c) - L_('A') + 10;
423 	  else
424 	    break;
425 	  if ((int) c >= base)
426 	    break;
427 	  /* Note that we never can have an overflow.  */
428 	  else if (j >= jmax)
429 	    {
430 	      /* We have an overflow.  Now use the long representation.  */
431 	      i = (unsigned LONG int) j;
432 	      goto use_long;
433 	    }
434 	  else
435 	    j = j * (unsigned long int) base + c;
436 	}
437 
438       i = (unsigned LONG int) j;
439     }
440   else
441     for (;c != L_('\0'); c = *++s)
442       {
443 	if (s == end)
444 	  break;
445 	if (c >= L_('0') && c <= L_('9'))
446 	  c -= L_('0');
447 #ifdef USE_NUMBER_GROUPING
448 # ifdef USE_WIDE_CHAR
449 	else if (grouping && c == thousands)
450 	  continue;
451 # else
452 	else if (thousands_len)
453 	  {
454 	    for (cnt = 0; cnt < thousands_len; ++cnt)
455 	      if (thousands[cnt] != s[cnt])
456 		break;
457 	    if (cnt == thousands_len)
458 	      {
459 		s += thousands_len - 1;
460 		continue;
461 	      }
462 	    if (ISALPHA (c))
463 	      c = TOUPPER (c) - L_('A') + 10;
464 	    else
465 	      break;
466 	  }
467 # endif
468 #endif
469 	else if (ISALPHA (c))
470 	  c = TOUPPER (c) - L_('A') + 10;
471 	else
472 	  break;
473 	if ((int) c >= base)
474 	  break;
475 	/* Check for overflow.  */
476 	if (i > cutoff || (i == cutoff && c > cutlim))
477 	  overflow = 1;
478 	else
479 	  {
480 	  use_long:
481 	    i *= (unsigned LONG int) base;
482 	    i += c;
483 	  }
484       }
485 
486   /* Check if anything actually happened.  */
487   if (s == save)
488     goto noconv;
489 
490   /* Store in ENDPTR the address of one character
491      past the last character we converted.  */
492   if (endptr != NULL)
493     *endptr = (STRING_TYPE *) s;
494 
495 #if !UNSIGNED
496   /* Check for a value that is within the range of
497      `unsigned LONG int', but outside the range of `LONG int'.  */
498   if (overflow == 0
499       && i > (negative
500 	      ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
501 	      : (unsigned LONG int) STRTOL_LONG_MAX))
502     overflow = 1;
503 #endif
504 
505   if (__builtin_expect (overflow, 0))
506     {
507       __set_errno (ERANGE);
508 #if UNSIGNED
509       return STRTOL_ULONG_MAX;
510 #else
511       return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
512 #endif
513     }
514 
515   /* Return the result of the appropriate sign.  */
516   return negative ? -i : i;
517 
518 noconv:
519   /* We must handle a special case here: the base is 0 or 16 and the
520      first two characters are '0' and 'x', but the rest are no
521      hexadecimal digits.  This is no error case.  We return 0 and
522      ENDPTR points to the `x`.  */
523   if (endptr != NULL)
524     {
525       if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
526 	  && save[-2] == L_('0'))
527 	*endptr = (STRING_TYPE *) &save[-1];
528       else
529 	/*  There was no number to convert.  */
530 	*endptr = (STRING_TYPE *) nptr;
531     }
532 
533   return 0L;
534 }
535 
536 /* External user entry point.  */
537 
538 #if _LIBC - 0 == 0
539 # undef PARAMS
540 # if defined (__STDC__) && __STDC__
541 #  define PARAMS(Args) Args
542 # else
543 #  define PARAMS(Args) ()
544 # endif
545 
546 /* Prototype.  */
547 INT strtol PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, int base));
548 #endif
549 
550 
551 INT
552 #ifdef weak_function
553 weak_function
554 #endif
555 strtol (nptr, endptr, base LOCALE_PARAM)
556      const STRING_TYPE *nptr;
557      STRING_TYPE **endptr;
558      int base;
559      LOCALE_PARAM_DECL
560 {
561   return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
562 }
563