Home | History | Annotate | Line # | Download | only in lib
      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 (at) 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
    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.  */
    441 
    442 
    443 INT
    444 #ifdef weak_function
    445 weak_function
    446 #endif
    447 strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr,
    448 	int base LOCALE_PARAM_PROTO)
    449 {
    450   return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
    451 }
    452