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