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