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