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