Update NOTES.opensolaris with scheduling details
[kopensolaris-gnu/glibc.git] / stdlib / strtol_l.c
1 /* Convert string representing a number to integer value, using given locale.
2    Copyright (C) 1997, 2002, 2004, 2006, 2007 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
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 __set_errno
35 # define __set_errno(Val) errno = (Val)
36 #endif
37
38 #ifdef HAVE_LIMITS_H
39 # include <limits.h>
40 #endif
41
42 #include <stddef.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <locale.h>
46 #include <xlocale.h>
47 #include <bits/wordsize.h>
48
49 #ifdef USE_NUMBER_GROUPING
50 # include "../locale/localeinfo.h"
51 #endif
52
53 /* Nonzero if we are defining `strtoul' or `strtoull', operating on
54    unsigned integers.  */
55 #ifndef UNSIGNED
56 # define UNSIGNED 0
57 # define INT LONG int
58 #else
59 # define INT unsigned LONG int
60 #endif
61
62 /* Determine the name.  */
63 #if UNSIGNED
64 # ifdef USE_WIDE_CHAR
65 #  ifdef QUAD
66 #   define strtol_l wcstoull_l
67 #  else
68 #   define strtol_l wcstoul_l
69 #  endif
70 # else
71 #  ifdef QUAD
72 #   define strtol_l strtoull_l
73 #  else
74 #   define strtol_l strtoul_l
75 #  endif
76 # endif
77 #else
78 # ifdef USE_WIDE_CHAR
79 #  ifdef QUAD
80 #   define strtol_l wcstoll_l
81 #  else
82 #   define strtol_l wcstol_l
83 #  endif
84 # else
85 #  ifdef QUAD
86 #   define strtol_l strtoll_l
87 #  else
88 #   define strtol_l strtol_l
89 #  endif
90 # endif
91 #endif
92
93 #define __strtol_l __strtol_l2(strtol_l)
94 #define __strtol_l2(name) __strtol_l3(name)
95 #define __strtol_l3(name) __##name
96
97
98 /* If QUAD is defined, we are defining `strtoll' or `strtoull',
99    operating on `long long int's.  */
100 #ifdef QUAD
101 # define LONG long long
102 # define STRTOL_LONG_MIN LONG_LONG_MIN
103 # define STRTOL_LONG_MAX LONG_LONG_MAX
104 # define STRTOL_ULONG_MAX ULONG_LONG_MAX
105 #else
106 # define LONG long
107
108 # ifndef ULONG_MAX
109 #  define ULONG_MAX ((unsigned long int) ~(unsigned long int) 0)
110 # endif
111 # ifndef LONG_MAX
112 #  define LONG_MAX ((long int) (ULONG_MAX >> 1))
113 # endif
114 # define STRTOL_LONG_MIN LONG_MIN
115 # define STRTOL_LONG_MAX LONG_MAX
116 # define STRTOL_ULONG_MAX ULONG_MAX
117 #endif
118
119
120 /* We use this code for the extended locale handling where the
121    function gets as an additional argument the locale which has to be
122    used.  To access the values we have to redefine the _NL_CURRENT and
123    _NL_CURRENT_WORD macros.  */
124 #undef _NL_CURRENT
125 #define _NL_CURRENT(category, item) \
126   (current->values[_NL_ITEM_INDEX (item)].string)
127 #undef _NL_CURRENT_WORD
128 #define _NL_CURRENT_WORD(category, item) \
129   ((uint32_t) current->values[_NL_ITEM_INDEX (item)].word)
130
131 #if defined _LIBC || defined HAVE_WCHAR_H
132 # include <wchar.h>
133 #endif
134
135 #ifdef USE_WIDE_CHAR
136 # include <wctype.h>
137 # define L_(Ch) L##Ch
138 # define UCHAR_TYPE wint_t
139 # define STRING_TYPE wchar_t
140 # define ISSPACE(Ch) __iswspace_l ((Ch), loc)
141 # define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
142 # define TOUPPER(Ch) __towupper_l ((Ch), loc)
143 #else
144 # if defined _LIBC \
145    || defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
146 #  define IN_CTYPE_DOMAIN(c) 1
147 # else
148 #  define IN_CTYPE_DOMAIN(c) isascii(c)
149 # endif
150 # define L_(Ch) Ch
151 # define UCHAR_TYPE unsigned char
152 # define STRING_TYPE char
153 # define ISSPACE(Ch) __isspace_l ((Ch), loc)
154 # define ISALPHA(Ch) __isalpha_l ((Ch), loc)
155 # define TOUPPER(Ch) __toupper_l ((Ch), loc)
156 #endif
157
158 #define INTERNAL(X) INTERNAL1(X)
159 #define INTERNAL1(X) __##X##_internal
160 #define WEAKNAME(X) WEAKNAME1(X)
161
162 #ifdef USE_NUMBER_GROUPING
163 /* This file defines a function to check for correct grouping.  */
164 # include "grouping.h"
165 #endif
166
167
168 /* Define tables of maximum values and remainders in order to detect
169    overflow.  Do this at compile-time in order to avoid the runtime
170    overhead of the division.  */
171 extern const unsigned long __strtol_ul_max_tab[] attribute_hidden;
172 extern const unsigned char __strtol_ul_rem_tab[] attribute_hidden;
173 #if defined(QUAD) && __WORDSIZE == 32
174 extern const unsigned long long __strtol_ull_max_tab[] attribute_hidden;
175 extern const unsigned char __strtol_ull_rem_tab[] attribute_hidden;
176 #endif
177
178 #define DEF(TYPE, NAME)                                                    \
179   const TYPE NAME[] attribute_hidden =                                     \
180   {                                                                        \
181     F(2), F(3), F(4), F(5), F(6), F(7), F(8), F(9), F(10),                 \
182     F(11), F(12), F(13), F(14), F(15), F(16), F(17), F(18), F(19), F(20),  \
183     F(21), F(22), F(23), F(24), F(25), F(26), F(27), F(28), F(29), F(30),  \
184     F(31), F(32), F(33), F(34), F(35), F(36)                               \
185   }
186
187 #if !UNSIGNED && !defined (USE_WIDE_CHAR) && !defined (QUAD)
188 # define F(X)   ULONG_MAX / X
189   DEF (unsigned long, __strtol_ul_max_tab);
190 # undef F
191 # define F(X)   ULONG_MAX % X
192   DEF (unsigned char, __strtol_ul_rem_tab);
193 # undef F
194 #endif
195 #if !UNSIGNED && !defined (USE_WIDE_CHAR) && defined (QUAD) \
196     && __WORDSIZE == 32
197 # define F(X)   ULONG_LONG_MAX / X
198   DEF (unsigned long long, __strtol_ull_max_tab);
199 # undef F
200 # define F(X)   ULONG_LONG_MAX % X
201   DEF (unsigned char, __strtol_ull_rem_tab);
202 # undef F
203 #endif
204 #undef DEF
205
206 /* Define some more readable aliases for these arrays which correspond
207    to how they'll be used in the function below.  */
208 #define jmax_tab        __strtol_ul_max_tab
209 #if defined(QUAD) && __WORDSIZE == 32
210 # define cutoff_tab     __strtol_ull_max_tab
211 # define cutlim_tab     __strtol_ull_rem_tab
212 #else
213 # define cutoff_tab     __strtol_ul_max_tab
214 # define cutlim_tab     __strtol_ul_rem_tab
215 #endif
216
217
218 /* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
219    If BASE is 0 the base is determined by the presence of a leading
220    zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
221    If BASE is < 2 or > 36, it is reset to 10.
222    If ENDPTR is not NULL, a pointer to the character after the last
223    one converted is stored in *ENDPTR.  */
224
225 INT
226 INTERNAL (__strtol_l) (nptr, endptr, base, group, loc)
227      const STRING_TYPE *nptr;
228      STRING_TYPE **endptr;
229      int base;
230      int group;
231      __locale_t loc;
232 {
233   int negative;
234   register unsigned LONG int cutoff;
235   register unsigned int cutlim;
236   register unsigned LONG int i;
237   register const STRING_TYPE *s;
238   register UCHAR_TYPE c;
239   const STRING_TYPE *save, *end;
240   int overflow;
241 #ifndef USE_WIDE_CHAR
242   size_t cnt;
243 #endif
244
245 #ifdef USE_NUMBER_GROUPING
246   struct locale_data *current = loc->__locales[LC_NUMERIC];
247   /* The thousands character of the current locale.  */
248 # ifdef USE_WIDE_CHAR
249   wchar_t thousands = L'\0';
250 # else
251   const char *thousands = NULL;
252   size_t thousands_len = 0;
253 # endif
254   /* The numeric grouping specification of the current locale,
255      in the format described in <locale.h>.  */
256   const char *grouping;
257
258   if (__builtin_expect (group, 0))
259     {
260       grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
261       if (*grouping <= 0 || *grouping == CHAR_MAX)
262         grouping = NULL;
263       else
264         {
265           /* Figure out the thousands separator character.  */
266 # ifdef USE_WIDE_CHAR
267 #  ifdef _LIBC
268           thousands = _NL_CURRENT_WORD (LC_NUMERIC,
269                                         _NL_NUMERIC_THOUSANDS_SEP_WC);
270 #  endif
271           if (thousands == L'\0')
272             grouping = NULL;
273 # else
274 #  ifdef _LIBC
275           thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
276 #  endif
277           if (*thousands == '\0')
278             {
279               thousands = NULL;
280               grouping = NULL;
281             }
282 # endif
283         }
284     }
285   else
286     grouping = NULL;
287 #endif
288
289   if (base < 0 || base == 1 || base > 36)
290     {
291       __set_errno (EINVAL);
292       return 0;
293     }
294
295   save = s = nptr;
296
297   /* Skip white space.  */
298   while (ISSPACE (*s))
299     ++s;
300   if (__builtin_expect (*s == L_('\0'), 0))
301     goto noconv;
302
303   /* Check for a sign.  */
304   negative = 0;
305   if (*s == L_('-'))
306     {
307       negative = 1;
308       ++s;
309     }
310   else if (*s == L_('+'))
311     ++s;
312
313   /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
314   if (*s == L_('0'))
315     {
316       if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
317         {
318           s += 2;
319           base = 16;
320         }
321       else if (base == 0)
322         base = 8;
323     }
324   else if (base == 0)
325     base = 10;
326
327   /* Save the pointer so we can check later if anything happened.  */
328   save = s;
329
330 #ifdef USE_NUMBER_GROUPING
331   if (base != 10)
332     grouping = NULL;
333
334   if (__builtin_expect (grouping != NULL, 0))
335     {
336 # ifndef USE_WIDE_CHAR
337       thousands_len = strlen (thousands);
338 # endif
339
340       /* Find the end of the digit string and check its grouping.  */
341       end = s;
342       if (
343 # ifdef USE_WIDE_CHAR
344           *s != thousands
345 # else
346           ({ for (cnt = 0; cnt < thousands_len; ++cnt)
347                if (thousands[cnt] != end[cnt])
348                  break;
349              cnt < thousands_len; })
350 # endif
351           )
352         {
353           for (c = *end; c != L_('\0'); c = *++end)
354             if (((STRING_TYPE) c < L_('0') || (STRING_TYPE) c > L_('9'))
355 # ifdef USE_WIDE_CHAR
356                 && (wchar_t) c != thousands
357 # else
358                 && ({ for (cnt = 0; cnt < thousands_len; ++cnt)
359                       if (thousands[cnt] != end[cnt])
360                         break;
361                       cnt < thousands_len; })
362 # endif
363                 && (!ISALPHA (c)
364                     || (int) (TOUPPER (c) - L_('A') + 10) >= base))
365               break;
366
367 # ifdef USE_WIDE_CHAR
368           end = __correctly_grouped_prefixwc (s, end, thousands, grouping);
369 # else
370           end = __correctly_grouped_prefixmb (s, end, thousands, grouping);
371 # endif
372         }
373     }
374   else
375 #endif
376     end = NULL;
377
378   /* Avoid runtime division; lookup cutoff and limit.  */
379   cutoff = cutoff_tab[base - 2];
380   cutlim = cutlim_tab[base - 2];
381
382   overflow = 0;
383   i = 0;
384   c = *s;
385   if (sizeof (long int) != sizeof (LONG int))
386     {
387       unsigned long int j = 0;
388       unsigned long int jmax = jmax_tab[base - 2];
389
390       for (;c != L_('\0'); c = *++s)
391         {
392           if (s == end)
393             break;
394           if (c >= L_('0') && c <= L_('9'))
395             c -= L_('0');
396 #ifdef USE_NUMBER_GROUPING
397 # ifdef USE_WIDE_CHAR
398           else if (grouping && (wchar_t) c == thousands)
399             continue;
400 # else
401           else if (thousands_len)
402             {
403               for (cnt = 0; cnt < thousands_len; ++cnt)
404                 if (thousands[cnt] != s[cnt])
405                   break;
406               if (cnt == thousands_len)
407                 {
408                   s += thousands_len - 1;
409                   continue;
410                 }
411               if (ISALPHA (c))
412                 c = TOUPPER (c) - L_('A') + 10;
413               else
414                 break;
415             }
416 # endif
417 #endif
418           else if (ISALPHA (c))
419             c = TOUPPER (c) - L_('A') + 10;
420           else
421             break;
422           if ((int) c >= base)
423             break;
424           /* Note that we never can have an overflow.  */
425           else if (j >= jmax)
426             {
427               /* We have an overflow.  Now use the long representation.  */
428               i = (unsigned LONG int) j;
429               goto use_long;
430             }
431           else
432             j = j * (unsigned long int) base + c;
433         }
434
435       i = (unsigned LONG int) j;
436     }
437   else
438     for (;c != L_('\0'); c = *++s)
439       {
440         if (s == end)
441           break;
442         if (c >= L_('0') && c <= L_('9'))
443           c -= L_('0');
444 #ifdef USE_NUMBER_GROUPING
445 # ifdef USE_WIDE_CHAR
446         else if (grouping && (wchar_t) c == thousands)
447           continue;
448 # else
449         else if (thousands_len)
450           {
451             for (cnt = 0; cnt < thousands_len; ++cnt)
452               if (thousands[cnt] != s[cnt])
453                 break;
454             if (cnt == thousands_len)
455               {
456                 s += thousands_len - 1;
457                 continue;
458               }
459             if (ISALPHA (c))
460               c = TOUPPER (c) - L_('A') + 10;
461             else
462               break;
463           }
464 # endif
465 #endif
466         else if (ISALPHA (c))
467           c = TOUPPER (c) - L_('A') + 10;
468         else
469           break;
470         if ((int) c >= base)
471           break;
472         /* Check for overflow.  */
473         if (i > cutoff || (i == cutoff && c > cutlim))
474           overflow = 1;
475         else
476           {
477           use_long:
478             i *= (unsigned LONG int) base;
479             i += c;
480           }
481       }
482
483   /* Check if anything actually happened.  */
484   if (s == save)
485     goto noconv;
486
487   /* Store in ENDPTR the address of one character
488      past the last character we converted.  */
489   if (endptr != NULL)
490     *endptr = (STRING_TYPE *) s;
491
492 #if !UNSIGNED
493   /* Check for a value that is within the range of
494      `unsigned LONG int', but outside the range of `LONG int'.  */
495   if (overflow == 0
496       && i > (negative
497               ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
498               : (unsigned LONG int) STRTOL_LONG_MAX))
499     overflow = 1;
500 #endif
501
502   if (__builtin_expect (overflow, 0))
503     {
504       __set_errno (ERANGE);
505 #if UNSIGNED
506       return STRTOL_ULONG_MAX;
507 #else
508       return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
509 #endif
510     }
511
512   /* Return the result of the appropriate sign.  */
513   return negative ? -i : i;
514
515 noconv:
516   /* We must handle a special case here: the base is 0 or 16 and the
517      first two characters are '0' and 'x', but the rest are no
518      hexadecimal digits.  This is no error case.  We return 0 and
519      ENDPTR points to the `x`.  */
520   if (endptr != NULL)
521     {
522       if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
523           && save[-2] == L_('0'))
524         *endptr = (STRING_TYPE *) &save[-1];
525       else
526         /*  There was no number to convert.  */
527         *endptr = (STRING_TYPE *) nptr;
528     }
529
530   return 0L;
531 }
532 #if defined _LIBC && !defined USE_WIDE_CHAR
533 libc_hidden_def (INTERNAL (__strtol_l))
534 #endif
535 \f
536 /* External user entry point.  */
537
538 #if _LIBC - 0 == 0
539 # undef PARAMS
540 # if defined (__STDC__) && __STDC__
541 #  define PARAMS(Args) Args
542 # else
543 #  define PARAMS(Args) ()
544 # endif
545
546 /* Prototype.  */
547 extern INT __strtol_l PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr,
548                                int base));
549 #endif
550
551
552 INT
553 #ifdef weak_function
554 weak_function
555 #endif
556 __strtol_l (nptr, endptr, base, loc)
557      const STRING_TYPE *nptr;
558      STRING_TYPE **endptr;
559      int base;
560      __locale_t loc;
561 {
562   return INTERNAL (__strtol_l) (nptr, endptr, base, 0, loc);
563 }
564 libc_hidden_def (__strtol_l)
565 weak_alias (__strtol_l, strtol_l)