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