Quash warning in s_sincosl.
[platform/upstream/glibc.git] / stdio-common / vfscanf.c
1 /* Copyright (C) 1991-2012 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #include <assert.h>
19 #include <errno.h>
20 #include <limits.h>
21 #include <ctype.h>
22 #include <stdarg.h>
23 #include <stdbool.h>
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <wchar.h>
29 #include <wctype.h>
30 #include <bits/libc-lock.h>
31 #include <locale/localeinfo.h>
32
33 #ifdef  __GNUC__
34 # define HAVE_LONGLONG
35 # define LONGLONG       long long
36 #else
37 # define LONGLONG       long
38 #endif
39
40 /* Determine whether we have to handle `long long' at all.  */
41 #if LONG_MAX == LONG_LONG_MAX
42 # define need_longlong  0
43 #else
44 # define need_longlong  1
45 #endif
46
47 /* Determine whether we have to handle `long'.  */
48 #if INT_MAX == LONG_MAX
49 # define need_long      0
50 #else
51 # define need_long      1
52 #endif
53
54 /* Those are flags in the conversion format. */
55 #define LONG            0x0001  /* l: long or double */
56 #define LONGDBL         0x0002  /* L: long long or long double */
57 #define SHORT           0x0004  /* h: short */
58 #define SUPPRESS        0x0008  /* *: suppress assignment */
59 #define POINTER         0x0010  /* weird %p pointer (`fake hex') */
60 #define NOSKIP          0x0020  /* do not skip blanks */
61 #define NUMBER_SIGNED   0x0040  /* signed integer */
62 #define GROUP           0x0080  /* ': group numbers */
63 #define GNU_MALLOC      0x0100  /* a: malloc strings */
64 #define CHAR            0x0200  /* hh: char */
65 #define I18N            0x0400  /* I: use locale's digits */
66 #define HEXA_FLOAT      0x0800  /* hexadecimal float */
67 #define READ_POINTER    0x1000  /* this is a pointer value */
68 #define POSIX_MALLOC    0x2000  /* m: malloc strings */
69 #define MALLOC          (GNU_MALLOC | POSIX_MALLOC)
70
71 #include <locale/localeinfo.h>
72 #include <libioP.h>
73 #include <libio.h>
74
75 #undef va_list
76 #define va_list _IO_va_list
77
78 #ifdef COMPILE_WSCANF
79 # define ungetc(c, s)   ((void) (c == WEOF                                    \
80                                  || (--read_in,                               \
81                                      _IO_sputbackwc (s, c))))
82 # define ungetc_not_eof(c, s)   ((void) (--read_in,                           \
83                                          _IO_sputbackwc (s, c)))
84 # define inchar()       (c == WEOF ? ((errno = inchar_errno), WEOF)           \
85                          : ((c = _IO_getwc_unlocked (s)),                     \
86                             (void) (c != WEOF                                 \
87                                     ? ++read_in                               \
88                                     : (size_t) (inchar_errno = errno)), c))
89
90 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
91 # define ISSPACE(Ch)      iswspace (Ch)
92 # define ISDIGIT(Ch)      iswdigit (Ch)
93 # define ISXDIGIT(Ch)     iswxdigit (Ch)
94 # define TOLOWER(Ch)      towlower (Ch)
95 # define ORIENT   if (_IO_fwide (s, 1) != 1) return WEOF
96 # define __strtoll_internal     __wcstoll_internal
97 # define __strtoull_internal    __wcstoull_internal
98 # define __strtol_internal      __wcstol_internal
99 # define __strtoul_internal     __wcstoul_internal
100 # define __strtold_internal     __wcstold_internal
101 # define __strtod_internal      __wcstod_internal
102 # define __strtof_internal      __wcstof_internal
103
104 # define L_(Str)        L##Str
105 # define CHAR_T         wchar_t
106 # define UCHAR_T        unsigned int
107 # define WINT_T         wint_t
108 # undef EOF
109 # define EOF            WEOF
110 #else
111 # define ungetc(c, s)   ((void) ((int) c == EOF                               \
112                                  || (--read_in,                               \
113                                      _IO_sputbackc (s, (unsigned char) c))))
114 # define ungetc_not_eof(c, s)   ((void) (--read_in,                           \
115                                          _IO_sputbackc (s, (unsigned char) c)))
116 # define inchar()       (c == EOF ? ((errno = inchar_errno), EOF)             \
117                          : ((c = _IO_getc_unlocked (s)),                      \
118                             (void) (c != EOF                                  \
119                                     ? ++read_in                               \
120                                     : (size_t) (inchar_errno = errno)), c))
121 # define MEMCPY(d, s, n) memcpy (d, s, n)
122 # define ISSPACE(Ch)      __isspace_l (Ch, loc)
123 # define ISDIGIT(Ch)      __isdigit_l (Ch, loc)
124 # define ISXDIGIT(Ch)     __isxdigit_l (Ch, loc)
125 # define TOLOWER(Ch)      __tolower_l ((unsigned char) (Ch), loc)
126 # define ORIENT   if (_IO_vtable_offset (s) == 0                              \
127                               && _IO_fwide (s, -1) != -1)                     \
128                             return EOF
129
130 # define L_(Str)        Str
131 # define CHAR_T         char
132 # define UCHAR_T        unsigned char
133 # define WINT_T         int
134 #endif
135
136 #define encode_error() do {                                                   \
137                           errval = 4;                                         \
138                           __set_errno (EILSEQ);                               \
139                           goto errout;                                        \
140                         } while (0)
141 #define conv_error()    do {                                                  \
142                           errval = 2;                                         \
143                           goto errout;                                        \
144                         } while (0)
145 #define input_error()   do {                                                  \
146                           errval = 1;                                         \
147                           if (done == 0) done = EOF;                          \
148                           goto errout;                                        \
149                         } while (0)
150 #define add_ptr_to_free(ptr)                                                  \
151   do                                                                          \
152     {                                                                         \
153       if (ptrs_to_free == NULL                                                \
154           || ptrs_to_free->count == (sizeof (ptrs_to_free->ptrs)              \
155                                      / sizeof (ptrs_to_free->ptrs[0])))       \
156         {                                                                     \
157           struct ptrs_to_free *new_ptrs = alloca (sizeof (*ptrs_to_free));    \
158           new_ptrs->count = 0;                                                \
159           new_ptrs->next = ptrs_to_free;                                      \
160           ptrs_to_free = new_ptrs;                                            \
161         }                                                                     \
162       ptrs_to_free->ptrs[ptrs_to_free->count++] = (ptr);                      \
163     }                                                                         \
164   while (0)
165 #define ARGCHECK(s, format)                                                   \
166   do                                                                          \
167     {                                                                         \
168       /* Check file argument for consistence.  */                             \
169       CHECK_FILE (s, EOF);                                                    \
170       if (s->_flags & _IO_NO_READS)                                           \
171         {                                                                     \
172           __set_errno (EBADF);                                                \
173           return EOF;                                                         \
174         }                                                                     \
175       else if (format == NULL)                                                \
176         {                                                                     \
177           MAYBE_SET_EINVAL;                                                   \
178           return EOF;                                                         \
179         }                                                                     \
180     } while (0)
181 #define LOCK_STREAM(S)                                                        \
182   __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
183   _IO_flockfile (S)
184 #define UNLOCK_STREAM(S)                                                      \
185   _IO_funlockfile (S);                                                        \
186   __libc_cleanup_region_end (0)
187
188 struct ptrs_to_free
189 {
190   size_t count;
191   struct ptrs_to_free *next;
192   char **ptrs[32];
193 };
194
195 /* Read formatted input from S according to the format string
196    FORMAT, using the argument list in ARG.
197    Return the number of assignments made, or -1 for an input error.  */
198 #ifdef COMPILE_WSCANF
199 int
200 _IO_vfwscanf (_IO_FILE *s, const wchar_t *format, _IO_va_list argptr,
201               int *errp)
202 #else
203 int
204 _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
205                       int *errp)
206 #endif
207 {
208   va_list arg;
209   register const CHAR_T *f = format;
210   register UCHAR_T fc;  /* Current character of the format.  */
211   register WINT_T done = 0;     /* Assignments done.  */
212   register size_t read_in = 0;  /* Chars read in.  */
213   register WINT_T c = 0;        /* Last char read.  */
214   register int width;           /* Maximum field width.  */
215   register int flags;           /* Modifiers for current format element.  */
216   int errval = 0;
217 #ifndef COMPILE_WSCANF
218   __locale_t loc = _NL_CURRENT_LOCALE;
219   struct __locale_data *const curctype = loc->__locales[LC_CTYPE];
220 #endif
221
222   /* Errno of last failed inchar call.  */
223   int inchar_errno = 0;
224   /* Status for reading F-P nums.  */
225   char got_dot, got_e, negative;
226   /* If a [...] is a [^...].  */
227   CHAR_T not_in;
228 #define exp_char not_in
229   /* Base for integral numbers.  */
230   int base;
231   /* Decimal point character.  */
232 #ifdef COMPILE_WSCANF
233   wint_t decimal;
234 #else
235   const char *decimal;
236 #endif
237   /* The thousands character of the current locale.  */
238 #ifdef COMPILE_WSCANF
239   wint_t thousands;
240 #else
241   const char *thousands;
242 #endif
243   struct ptrs_to_free *ptrs_to_free = NULL;
244   /* State for the conversions.  */
245   mbstate_t state;
246   /* Integral holding variables.  */
247   union
248     {
249       long long int q;
250       unsigned long long int uq;
251       long int l;
252       unsigned long int ul;
253     } num;
254   /* Character-buffer pointer.  */
255   char *str = NULL;
256   wchar_t *wstr = NULL;
257   char **strptr = NULL;
258   ssize_t strsize = 0;
259   /* We must not react on white spaces immediately because they can
260      possibly be matched even if in the input stream no character is
261      available anymore.  */
262   int skip_space = 0;
263   /* Workspace.  */
264   CHAR_T *tw;                   /* Temporary pointer.  */
265   CHAR_T *wp = NULL;            /* Workspace.  */
266   size_t wpmax = 0;             /* Maximal size of workspace.  */
267   size_t wpsize;                /* Currently used bytes in workspace.  */
268   bool use_malloc = false;
269 #define ADDW(Ch)                                                            \
270   do                                                                        \
271     {                                                                       \
272       if (__builtin_expect (wpsize == wpmax, 0))                            \
273         {                                                                   \
274           CHAR_T *old = wp;                                                 \
275           size_t newsize = (UCHAR_MAX + 1 > 2 * wpmax                       \
276                             ? UCHAR_MAX + 1 : 2 * wpmax);                   \
277           if (use_malloc || !__libc_use_alloca (newsize))                   \
278             {                                                               \
279               wp = realloc (use_malloc ? wp : NULL, newsize);               \
280               if (wp == NULL)                                               \
281                 {                                                           \
282                   if (use_malloc)                                           \
283                     free (old);                                             \
284                   done = EOF;                                               \
285                   goto errout;                                              \
286                 }                                                           \
287               if (! use_malloc)                                             \
288                 MEMCPY (wp, old, wpsize);                                   \
289               wpmax = newsize;                                              \
290               use_malloc = true;                                            \
291             }                                                               \
292           else                                                              \
293             {                                                               \
294               size_t s = wpmax * sizeof (CHAR_T);                           \
295               wp = (CHAR_T *) extend_alloca (wp, s,                         \
296                                              newsize * sizeof (CHAR_T));    \
297               wpmax = s / sizeof (CHAR_T);                                  \
298               if (old != NULL)                                              \
299                 MEMCPY (wp, old, wpsize);                                   \
300             }                                                               \
301         }                                                                   \
302       wp[wpsize++] = (Ch);                                                  \
303     }                                                                       \
304   while (0)
305
306 #ifdef __va_copy
307   __va_copy (arg, argptr);
308 #else
309   arg = (va_list) argptr;
310 #endif
311
312 #ifdef ORIENT
313   ORIENT;
314 #endif
315
316   ARGCHECK (s, format);
317
318  {
319 #ifndef COMPILE_WSCANF
320    struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
321 #endif
322
323    /* Figure out the decimal point character.  */
324 #ifdef COMPILE_WSCANF
325    decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
326 #else
327    decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
328 #endif
329    /* Figure out the thousands separator character.  */
330 #ifdef COMPILE_WSCANF
331    thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
332 #else
333    thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
334    if (*thousands == '\0')
335      thousands = NULL;
336 #endif
337  }
338
339   /* Lock the stream.  */
340   LOCK_STREAM (s);
341
342
343 #ifndef COMPILE_WSCANF
344   /* From now on we use `state' to convert the format string.  */
345   memset (&state, '\0', sizeof (state));
346 #endif
347
348   /* Run through the format string.  */
349   while (*f != '\0')
350     {
351       unsigned int argpos;
352       /* Extract the next argument, which is of type TYPE.
353          For a %N$... spec, this is the Nth argument from the beginning;
354          otherwise it is the next argument after the state now in ARG.  */
355 #ifdef __va_copy
356 # define ARG(type)      (argpos == 0 ? va_arg (arg, type) :                   \
357                          ({ unsigned int pos = argpos;                        \
358                             va_list arg;                                      \
359                             __va_copy (arg, argptr);                          \
360                             while (--pos > 0)                                 \
361                               (void) va_arg (arg, void *);                    \
362                             va_arg (arg, type);                               \
363                           }))
364 #else
365 # if 0
366       /* XXX Possible optimization.  */
367 #  define ARG(type)     (argpos == 0 ? va_arg (arg, type) :                   \
368                          ({ va_list arg = (va_list) argptr;                   \
369                             arg = (va_list) ((char *) arg                     \
370                                              + (argpos - 1)                   \
371                                              * __va_rounded_size (void *));   \
372                             va_arg (arg, type);                               \
373                          }))
374 # else
375 #  define ARG(type)     (argpos == 0 ? va_arg (arg, type) :                   \
376                          ({ unsigned int pos = argpos;                        \
377                             va_list arg = (va_list) argptr;                   \
378                             while (--pos > 0)                                 \
379                               (void) va_arg (arg, void *);                    \
380                             va_arg (arg, type);                               \
381                           }))
382 # endif
383 #endif
384
385 #ifndef COMPILE_WSCANF
386       if (!isascii ((unsigned char) *f))
387         {
388           /* Non-ASCII, may be a multibyte.  */
389           int len = __mbrlen (f, strlen (f), &state);
390           if (len > 0)
391             {
392               do
393                 {
394                   c = inchar ();
395                   if (__builtin_expect (c == EOF, 0))
396                     input_error ();
397                   else if (c != (unsigned char) *f++)
398                     {
399                       ungetc_not_eof (c, s);
400                       conv_error ();
401                     }
402                 }
403               while (--len > 0);
404               continue;
405             }
406         }
407 #endif
408
409       fc = *f++;
410       if (fc != '%')
411         {
412           /* Remember to skip spaces.  */
413           if (ISSPACE (fc))
414             {
415               skip_space = 1;
416               continue;
417             }
418
419           /* Read a character.  */
420           c = inchar ();
421
422           /* Characters other than format specs must just match.  */
423           if (__builtin_expect (c == EOF, 0))
424             input_error ();
425
426           /* We saw white space char as the last character in the format
427              string.  Now it's time to skip all leading white space.  */
428           if (skip_space)
429             {
430               while (ISSPACE (c))
431                 if (__builtin_expect (inchar () == EOF, 0))
432                   input_error ();
433               skip_space = 0;
434             }
435
436           if (__builtin_expect (c != fc, 0))
437             {
438               ungetc (c, s);
439               conv_error ();
440             }
441
442           continue;
443         }
444
445       /* This is the start of the conversion string. */
446       flags = 0;
447
448       /* Initialize state of modifiers.  */
449       argpos = 0;
450
451       /* Prepare temporary buffer.  */
452       wpsize = 0;
453
454       /* Check for a positional parameter specification.  */
455       if (ISDIGIT ((UCHAR_T) *f))
456         {
457           argpos = (UCHAR_T) *f++ - L_('0');
458           while (ISDIGIT ((UCHAR_T) *f))
459             argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0'));
460           if (*f == L_('$'))
461             ++f;
462           else
463             {
464               /* Oops; that was actually the field width.  */
465               width = argpos;
466               argpos = 0;
467               goto got_width;
468             }
469         }
470
471       /* Check for the assignment-suppressing, the number grouping flag,
472          and the signal to use the locale's digit representation.  */
473       while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
474         switch (*f++)
475           {
476           case L_('*'):
477             flags |= SUPPRESS;
478             break;
479           case L_('\''):
480 #ifdef COMPILE_WSCANF
481             if (thousands != L'\0')
482 #else
483             if (thousands != NULL)
484 #endif
485               flags |= GROUP;
486             break;
487           case L_('I'):
488             flags |= I18N;
489             break;
490           }
491
492       /* Find the maximum field width.  */
493       width = 0;
494       while (ISDIGIT ((UCHAR_T) *f))
495         {
496           width *= 10;
497           width += (UCHAR_T) *f++ - L_('0');
498         }
499     got_width:
500       if (width == 0)
501         width = -1;
502
503       /* Check for type modifiers.  */
504       switch (*f++)
505         {
506         case L_('h'):
507           /* ints are short ints or chars.  */
508           if (*f == L_('h'))
509             {
510               ++f;
511               flags |= CHAR;
512             }
513           else
514             flags |= SHORT;
515           break;
516         case L_('l'):
517           if (*f == L_('l'))
518             {
519               /* A double `l' is equivalent to an `L'.  */
520               ++f;
521               flags |= LONGDBL | LONG;
522             }
523           else
524             /* ints are long ints.  */
525             flags |= LONG;
526           break;
527         case L_('q'):
528         case L_('L'):
529           /* doubles are long doubles, and ints are long long ints.  */
530           flags |= LONGDBL | LONG;
531           break;
532         case L_('a'):
533           /* The `a' is used as a flag only if followed by `s', `S' or
534              `['.  */
535           if (*f != L_('s') && *f != L_('S') && *f != L_('['))
536             {
537               --f;
538               break;
539             }
540           /* In __isoc99_*scanf %as, %aS and %a[ extension is not
541              supported at all.  */
542           if (s->_flags2 & _IO_FLAGS2_SCANF_STD)
543             {
544               --f;
545               break;
546             }
547           /* String conversions (%s, %[) take a `char **'
548              arg and fill it in with a malloc'd pointer.  */
549           flags |= GNU_MALLOC;
550           break;
551         case L_('m'):
552           flags |= POSIX_MALLOC;
553           if (*f == L_('l'))
554             {
555               ++f;
556               flags |= LONG;
557             }
558           break;
559         case L_('z'):
560           if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
561             flags |= LONGDBL;
562           else if (sizeof (size_t) > sizeof (unsigned int))
563             flags |= LONG;
564           break;
565         case L_('j'):
566           if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
567             flags |= LONGDBL;
568           else if (sizeof (uintmax_t) > sizeof (unsigned int))
569             flags |= LONG;
570           break;
571         case L_('t'):
572           if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
573             flags |= LONGDBL;
574           else if (sizeof (ptrdiff_t) > sizeof (int))
575             flags |= LONG;
576           break;
577         default:
578           /* Not a recognized modifier.  Backup.  */
579           --f;
580           break;
581         }
582
583       /* End of the format string?  */
584       if (__builtin_expect (*f == L_('\0'), 0))
585         conv_error ();
586
587       /* Find the conversion specifier.  */
588       fc = *f++;
589       if (skip_space || (fc != L_('[') && fc != L_('c')
590                          && fc != L_('C') && fc != L_('n')))
591         {
592           /* Eat whitespace.  */
593           int save_errno = errno;
594           __set_errno (0);
595           do
596             /* We add the additional test for EOF here since otherwise
597                inchar will restore the old errno value which might be
598                EINTR but does not indicate an interrupt since nothing
599                was read at this time.  */
600             if (__builtin_expect ((c == EOF || inchar () == EOF)
601                                   && errno == EINTR, 0))
602               input_error ();
603           while (ISSPACE (c));
604           __set_errno (save_errno);
605           ungetc (c, s);
606           skip_space = 0;
607         }
608
609       switch (fc)
610         {
611         case L_('%'):   /* Must match a literal '%'.  */
612           c = inchar ();
613           if (__builtin_expect (c == EOF, 0))
614             input_error ();
615           if (__builtin_expect (c != fc, 0))
616             {
617               ungetc_not_eof (c, s);
618               conv_error ();
619             }
620           break;
621
622         case L_('n'):   /* Answer number of assignments done.  */
623           /* Corrigendum 1 to ISO C 1990 describes the allowed flags
624              with the 'n' conversion specifier.  */
625           if (!(flags & SUPPRESS))
626             {
627               /* Don't count the read-ahead.  */
628               if (need_longlong && (flags & LONGDBL))
629                 *ARG (long long int *) = read_in;
630               else if (need_long && (flags & LONG))
631                 *ARG (long int *) = read_in;
632               else if (flags & SHORT)
633                 *ARG (short int *) = read_in;
634               else if (!(flags & CHAR))
635                 *ARG (int *) = read_in;
636               else
637                 *ARG (char *) = read_in;
638
639 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
640               /* We have a severe problem here.  The ISO C standard
641                  contradicts itself in explaining the effect of the %n
642                  format in `scanf'.  While in ISO C:1990 and the ISO C
643                  Amendement 1:1995 the result is described as
644
645                    Execution of a %n directive does not effect the
646                    assignment count returned at the completion of
647                    execution of the f(w)scanf function.
648
649                  in ISO C Corrigendum 1:1994 the following was added:
650
651                    Subclause 7.9.6.2
652                    Add the following fourth example:
653                      In:
654                        #include <stdio.h>
655                        int d1, d2, n1, n2, i;
656                        i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
657                      the value 123 is assigned to d1 and the value3 to n1.
658                      Because %n can never get an input failure the value
659                      of 3 is also assigned to n2.  The value of d2 is not
660                      affected.  The value 3 is assigned to i.
661
662                  We go for now with the historically correct code from ISO C,
663                  i.e., we don't count the %n assignments.  When it ever
664                  should proof to be wrong just remove the #ifdef above.  */
665               ++done;
666 #endif
667             }
668           break;
669
670         case L_('c'):   /* Match characters.  */
671           if ((flags & LONG) == 0)
672             {
673               if (width == -1)
674                 width = 1;
675
676 #define STRING_ARG(Str, Type, Width)                                          \
677               do if (!(flags & SUPPRESS))                                     \
678                 {                                                             \
679                   if (flags & MALLOC)                                         \
680                     {                                                         \
681                       /* The string is to be stored in a malloc'd buffer.  */ \
682                       /* For %mS using char ** is actually wrong, but         \
683                          shouldn't make a difference on any arch glibc        \
684                          supports and would unnecessarily complicate          \
685                          things. */                                           \
686                       strptr = ARG (char **);                                 \
687                       if (strptr == NULL)                                     \
688                         conv_error ();                                        \
689                       /* Allocate an initial buffer.  */                      \
690                       strsize = Width;                                        \
691                       *strptr = (char *) malloc (strsize * sizeof (Type));    \
692                       Str = (Type *) *strptr;                                 \
693                       if (Str != NULL)                                        \
694                         add_ptr_to_free (strptr);                             \
695                       else if (flags & POSIX_MALLOC)                          \
696                         {                                                     \
697                           done = EOF;                                         \
698                           goto errout;                                        \
699                         }                                                     \
700                     }                                                         \
701                   else                                                        \
702                     Str = ARG (Type *);                                       \
703                   if (Str == NULL)                                            \
704                     conv_error ();                                            \
705                 } while (0)
706 #ifdef COMPILE_WSCANF
707               STRING_ARG (str, char, 100);
708 #else
709               STRING_ARG (str, char, (width > 1024 ? 1024 : width));
710 #endif
711
712               c = inchar ();
713               if (__builtin_expect (c == EOF, 0))
714                 input_error ();
715
716 #ifdef COMPILE_WSCANF
717               /* We have to convert the wide character(s) into multibyte
718                  characters and store the result.  */
719               memset (&state, '\0', sizeof (state));
720
721               do
722                 {
723                   size_t n;
724
725                   if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
726                       && str + MB_CUR_MAX >= *strptr + strsize)
727                     {
728                       /* We have to enlarge the buffer if the `m' flag
729                          was given.  */
730                       size_t strleng = str - *strptr;
731                       char *newstr;
732
733                       newstr = (char *) realloc (*strptr, strsize * 2);
734                       if (newstr == NULL)
735                         {
736                           /* Can't allocate that much.  Last-ditch effort.  */
737                           newstr = (char *) realloc (*strptr,
738                                                      strleng + MB_CUR_MAX);
739                           if (newstr == NULL)
740                             {
741                               /* c can't have `a' flag, only `m'.  */
742                               done = EOF;
743                               goto errout;
744                             }
745                           else
746                             {
747                               *strptr = newstr;
748                               str = newstr + strleng;
749                               strsize = strleng + MB_CUR_MAX;
750                             }
751                         }
752                       else
753                         {
754                           *strptr = newstr;
755                           str = newstr + strleng;
756                           strsize *= 2;
757                         }
758                     }
759
760                   n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
761                   if (__builtin_expect (n == (size_t) -1, 0))
762                     /* No valid wide character.  */
763                     input_error ();
764
765                   /* Increment the output pointer.  Even if we don't
766                      write anything.  */
767                   str += n;
768                 }
769               while (--width > 0 && inchar () != EOF);
770 #else
771               if (!(flags & SUPPRESS))
772                 {
773                   do
774                     {
775                       if ((flags & MALLOC)
776                           && (char *) str == *strptr + strsize)
777                         {
778                           /* Enlarge the buffer.  */
779                           size_t newsize
780                             = strsize
781                               + (strsize >= width ? width - 1 : strsize);
782
783                           str = (char *) realloc (*strptr, newsize);
784                           if (str == NULL)
785                             {
786                               /* Can't allocate that much.  Last-ditch
787                                  effort.  */
788                               str = (char *) realloc (*strptr, strsize + 1);
789                               if (str == NULL)
790                                 {
791                                   /* c can't have `a' flag, only `m'.  */
792                                   done = EOF;
793                                   goto errout;
794                                 }
795                               else
796                                 {
797                                   *strptr = (char *) str;
798                                   str += strsize;
799                                   ++strsize;
800                                 }
801                             }
802                           else
803                             {
804                               *strptr = (char *) str;
805                               str += strsize;
806                               strsize = newsize;
807                             }
808                         }
809                       *str++ = c;
810                     }
811                   while (--width > 0 && inchar () != EOF);
812                 }
813               else
814                 while (--width > 0 && inchar () != EOF);
815 #endif
816
817               if (!(flags & SUPPRESS))
818                 {
819                   if ((flags & MALLOC) && str - *strptr != strsize)
820                     {
821                       char *cp = (char *) realloc (*strptr, str - *strptr);
822                       if (cp != NULL)
823                         *strptr = cp;
824                     }
825                   strptr = NULL;
826                   ++done;
827                 }
828
829               break;
830             }
831           /* FALLTHROUGH */
832         case L_('C'):
833           if (width == -1)
834             width = 1;
835
836           STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width));
837
838           c = inchar ();
839           if (__builtin_expect (c == EOF, 0))
840             input_error ();
841
842 #ifdef COMPILE_WSCANF
843           /* Just store the incoming wide characters.  */
844           if (!(flags & SUPPRESS))
845             {
846               do
847                 {
848                   if ((flags & MALLOC)
849                       && wstr == (wchar_t *) *strptr + strsize)
850                     {
851                       size_t newsize
852                         = strsize + (strsize > width ? width - 1 : strsize);
853                       /* Enlarge the buffer.  */
854                       wstr = (wchar_t *) realloc (*strptr,
855                                                   newsize * sizeof (wchar_t));
856                       if (wstr == NULL)
857                         {
858                           /* Can't allocate that much.  Last-ditch effort.  */
859                           wstr = (wchar_t *) realloc (*strptr,
860                                                       (strsize + 1)
861                                                       * sizeof (wchar_t));
862                           if (wstr == NULL)
863                             {
864                               /* C or lc can't have `a' flag, only `m'
865                                  flag.  */
866                               done = EOF;
867                               goto errout;
868                             }
869                           else
870                             {
871                               *strptr = (char *) wstr;
872                               wstr += strsize;
873                               ++strsize;
874                             }
875                         }
876                       else
877                         {
878                           *strptr = (char *) wstr;
879                           wstr += strsize;
880                           strsize = newsize;
881                         }
882                     }
883                   *wstr++ = c;
884                 }
885               while (--width > 0 && inchar () != EOF);
886             }
887           else
888             while (--width > 0 && inchar () != EOF);
889 #else
890           {
891             /* We have to convert the multibyte input sequence to wide
892                characters.  */
893             char buf[1];
894             mbstate_t cstate;
895
896             memset (&cstate, '\0', sizeof (cstate));
897
898             do
899               {
900                 /* This is what we present the mbrtowc function first.  */
901                 buf[0] = c;
902
903                 if (!(flags & SUPPRESS) && (flags & MALLOC)
904                     && wstr == (wchar_t *) *strptr + strsize)
905                   {
906                     size_t newsize
907                       = strsize + (strsize > width ? width - 1 : strsize);
908                     /* Enlarge the buffer.  */
909                     wstr = (wchar_t *) realloc (*strptr,
910                                                 newsize * sizeof (wchar_t));
911                     if (wstr == NULL)
912                       {
913                         /* Can't allocate that much.  Last-ditch effort.  */
914                         wstr = (wchar_t *) realloc (*strptr,
915                                                     ((strsize + 1)
916                                                      * sizeof (wchar_t)));
917                         if (wstr == NULL)
918                           {
919                             /* C or lc can't have `a' flag, only `m' flag.  */
920                             done = EOF;
921                             goto errout;
922                           }
923                         else
924                           {
925                             *strptr = (char *) wstr;
926                             wstr += strsize;
927                             ++strsize;
928                           }
929                       }
930                     else
931                       {
932                         *strptr = (char *) wstr;
933                         wstr += strsize;
934                         strsize = newsize;
935                       }
936                   }
937
938                 while (1)
939                   {
940                     size_t n;
941
942                     n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
943                                    buf, 1, &cstate);
944
945                     if (n == (size_t) -2)
946                       {
947                         /* Possibly correct character, just not enough
948                            input.  */
949                         if (__builtin_expect (inchar () == EOF, 0))
950                           encode_error ();
951
952                         buf[0] = c;
953                         continue;
954                       }
955
956                     if (__builtin_expect (n != 1, 0))
957                       encode_error ();
958
959                     /* We have a match.  */
960                     break;
961                   }
962
963                 /* Advance the result pointer.  */
964                 ++wstr;
965               }
966             while (--width > 0 && inchar () != EOF);
967           }
968 #endif
969
970           if (!(flags & SUPPRESS))
971             {
972               if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
973                 {
974                   wchar_t *cp = (wchar_t *) realloc (*strptr,
975                                                      ((wstr
976                                                        - (wchar_t *) *strptr)
977                                                       * sizeof (wchar_t)));
978                   if (cp != NULL)
979                     *strptr = (char *) cp;
980                 }
981               strptr = NULL;
982
983               ++done;
984             }
985
986           break;
987
988         case L_('s'):           /* Read a string.  */
989           if (!(flags & LONG))
990             {
991               STRING_ARG (str, char, 100);
992
993               c = inchar ();
994               if (__builtin_expect (c == EOF, 0))
995                 input_error ();
996
997 #ifdef COMPILE_WSCANF
998               memset (&state, '\0', sizeof (state));
999 #endif
1000
1001               do
1002                 {
1003                   if (ISSPACE (c))
1004                     {
1005                       ungetc_not_eof (c, s);
1006                       break;
1007                     }
1008
1009 #ifdef COMPILE_WSCANF
1010                   /* This is quite complicated.  We have to convert the
1011                      wide characters into multibyte characters and then
1012                      store them.  */
1013                   {
1014                     size_t n;
1015
1016                     if (!(flags & SUPPRESS) && (flags & MALLOC)
1017                         && str + MB_CUR_MAX >= *strptr + strsize)
1018                       {
1019                         /* We have to enlarge the buffer if the `a' or `m'
1020                            flag was given.  */
1021                         size_t strleng = str - *strptr;
1022                         char *newstr;
1023
1024                         newstr = (char *) realloc (*strptr, strsize * 2);
1025                         if (newstr == NULL)
1026                           {
1027                             /* Can't allocate that much.  Last-ditch
1028                                effort.  */
1029                             newstr = (char *) realloc (*strptr,
1030                                                        strleng + MB_CUR_MAX);
1031                             if (newstr == NULL)
1032                               {
1033                                 if (flags & POSIX_MALLOC)
1034                                   {
1035                                     done = EOF;
1036                                     goto errout;
1037                                   }
1038                                 /* We lose.  Oh well.  Terminate the
1039                                    string and stop converting,
1040                                    so at least we don't skip any input.  */
1041                                 ((char *) (*strptr))[strleng] = '\0';
1042                                 strptr = NULL;
1043                                 ++done;
1044                                 conv_error ();
1045                               }
1046                             else
1047                               {
1048                                 *strptr = newstr;
1049                                 str = newstr + strleng;
1050                                 strsize = strleng + MB_CUR_MAX;
1051                               }
1052                           }
1053                         else
1054                           {
1055                             *strptr = newstr;
1056                             str = newstr + strleng;
1057                             strsize *= 2;
1058                           }
1059                       }
1060
1061                     n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
1062                                    &state);
1063                     if (__builtin_expect (n == (size_t) -1, 0))
1064                       encode_error ();
1065
1066                     assert (n <= MB_CUR_MAX);
1067                     str += n;
1068                   }
1069 #else
1070                   /* This is easy.  */
1071                   if (!(flags & SUPPRESS))
1072                     {
1073                       *str++ = c;
1074                       if ((flags & MALLOC)
1075                           && (char *) str == *strptr + strsize)
1076                         {
1077                           /* Enlarge the buffer.  */
1078                           str = (char *) realloc (*strptr, 2 * strsize);
1079                           if (str == NULL)
1080                             {
1081                               /* Can't allocate that much.  Last-ditch
1082                                  effort.  */
1083                               str = (char *) realloc (*strptr, strsize + 1);
1084                               if (str == NULL)
1085                                 {
1086                                   if (flags & POSIX_MALLOC)
1087                                     {
1088                                       done = EOF;
1089                                       goto errout;
1090                                     }
1091                                   /* We lose.  Oh well.  Terminate the
1092                                      string and stop converting,
1093                                      so at least we don't skip any input.  */
1094                                   ((char *) (*strptr))[strsize - 1] = '\0';
1095                                   strptr = NULL;
1096                                   ++done;
1097                                   conv_error ();
1098                                 }
1099                               else
1100                                 {
1101                                   *strptr = (char *) str;
1102                                   str += strsize;
1103                                   ++strsize;
1104                                 }
1105                             }
1106                           else
1107                             {
1108                               *strptr = (char *) str;
1109                               str += strsize;
1110                               strsize *= 2;
1111                             }
1112                         }
1113                     }
1114 #endif
1115                 }
1116               while ((width <= 0 || --width > 0) && inchar () != EOF);
1117
1118               if (!(flags & SUPPRESS))
1119                 {
1120 #ifdef COMPILE_WSCANF
1121                   /* We have to emit the code to get into the initial
1122                      state.  */
1123                   char buf[MB_LEN_MAX];
1124                   size_t n = __wcrtomb (buf, L'\0', &state);
1125                   if (n > 0 && (flags & MALLOC)
1126                       && str + n >= *strptr + strsize)
1127                     {
1128                       /* Enlarge the buffer.  */
1129                       size_t strleng = str - *strptr;
1130                       char *newstr;
1131
1132                       newstr = (char *) realloc (*strptr, strleng + n + 1);
1133                       if (newstr == NULL)
1134                         {
1135                           if (flags & POSIX_MALLOC)
1136                             {
1137                               done = EOF;
1138                               goto errout;
1139                             }
1140                           /* We lose.  Oh well.  Terminate the string
1141                              and stop converting, so at least we don't
1142                              skip any input.  */
1143                           ((char *) (*strptr))[strleng] = '\0';
1144                           strptr = NULL;
1145                           ++done;
1146                           conv_error ();
1147                         }
1148                       else
1149                         {
1150                           *strptr = newstr;
1151                           str = newstr + strleng;
1152                           strsize = strleng + n + 1;
1153                         }
1154                     }
1155
1156                   str = __mempcpy (str, buf, n);
1157 #endif
1158                   *str++ = '\0';
1159
1160                   if ((flags & MALLOC) && str - *strptr != strsize)
1161                     {
1162                       char *cp = (char *) realloc (*strptr, str - *strptr);
1163                       if (cp != NULL)
1164                         *strptr = cp;
1165                     }
1166                   strptr = NULL;
1167
1168                   ++done;
1169                 }
1170               break;
1171             }
1172           /* FALLTHROUGH */
1173
1174         case L_('S'):
1175           {
1176 #ifndef COMPILE_WSCANF
1177             mbstate_t cstate;
1178 #endif
1179
1180             /* Wide character string.  */
1181             STRING_ARG (wstr, wchar_t, 100);
1182
1183             c = inchar ();
1184             if (__builtin_expect (c == EOF,  0))
1185               input_error ();
1186
1187 #ifndef COMPILE_WSCANF
1188             memset (&cstate, '\0', sizeof (cstate));
1189 #endif
1190
1191             do
1192               {
1193                 if (ISSPACE (c))
1194                   {
1195                     ungetc_not_eof (c, s);
1196                     break;
1197                   }
1198
1199 #ifdef COMPILE_WSCANF
1200                 /* This is easy.  */
1201                 if (!(flags & SUPPRESS))
1202                   {
1203                     *wstr++ = c;
1204                     if ((flags & MALLOC)
1205                         && wstr == (wchar_t *) *strptr + strsize)
1206                       {
1207                         /* Enlarge the buffer.  */
1208                         wstr = (wchar_t *) realloc (*strptr,
1209                                                     (2 * strsize)
1210                                                     * sizeof (wchar_t));
1211                         if (wstr == NULL)
1212                           {
1213                             /* Can't allocate that much.  Last-ditch
1214                                effort.  */
1215                             wstr = (wchar_t *) realloc (*strptr,
1216                                                         (strsize + 1)
1217                                                         * sizeof (wchar_t));
1218                             if (wstr == NULL)
1219                               {
1220                                 if (flags & POSIX_MALLOC)
1221                                   {
1222                                     done = EOF;
1223                                     goto errout;
1224                                   }
1225                                 /* We lose.  Oh well.  Terminate the string
1226                                    and stop converting, so at least we don't
1227                                    skip any input.  */
1228                                 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1229                                 strptr = NULL;
1230                                 ++done;
1231                                 conv_error ();
1232                               }
1233                             else
1234                               {
1235                                 *strptr = (char *) wstr;
1236                                 wstr += strsize;
1237                                 ++strsize;
1238                               }
1239                           }
1240                         else
1241                           {
1242                             *strptr = (char *) wstr;
1243                             wstr += strsize;
1244                             strsize *= 2;
1245                           }
1246                       }
1247                   }
1248 #else
1249                 {
1250                   char buf[1];
1251
1252                   buf[0] = c;
1253
1254                   while (1)
1255                     {
1256                       size_t n;
1257
1258                       n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1259                                      buf, 1, &cstate);
1260
1261                       if (n == (size_t) -2)
1262                         {
1263                           /* Possibly correct character, just not enough
1264                              input.  */
1265                           if (__builtin_expect (inchar () == EOF, 0))
1266                             encode_error ();
1267
1268                           buf[0] = c;
1269                           continue;
1270                         }
1271
1272                       if (__builtin_expect (n != 1, 0))
1273                         encode_error ();
1274
1275                       /* We have a match.  */
1276                       ++wstr;
1277                       break;
1278                     }
1279
1280                   if (!(flags & SUPPRESS) && (flags & MALLOC)
1281                       && wstr == (wchar_t *) *strptr + strsize)
1282                     {
1283                       /* Enlarge the buffer.  */
1284                       wstr = (wchar_t *) realloc (*strptr,
1285                                                   (2 * strsize
1286                                                    * sizeof (wchar_t)));
1287                       if (wstr == NULL)
1288                         {
1289                           /* Can't allocate that much.  Last-ditch effort.  */
1290                           wstr = (wchar_t *) realloc (*strptr,
1291                                                       ((strsize + 1)
1292                                                        * sizeof (wchar_t)));
1293                           if (wstr == NULL)
1294                             {
1295                               if (flags & POSIX_MALLOC)
1296                                 {
1297                                   done = EOF;
1298                                   goto errout;
1299                                 }
1300                               /* We lose.  Oh well.  Terminate the
1301                                  string and stop converting, so at
1302                                  least we don't skip any input.  */
1303                               ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1304                               strptr = NULL;
1305                               ++done;
1306                               conv_error ();
1307                             }
1308                           else
1309                             {
1310                               *strptr = (char *) wstr;
1311                               wstr += strsize;
1312                               ++strsize;
1313                             }
1314                         }
1315                       else
1316                         {
1317                           *strptr = (char *) wstr;
1318                           wstr += strsize;
1319                           strsize *= 2;
1320                         }
1321                     }
1322                 }
1323 #endif
1324               }
1325             while ((width <= 0 || --width > 0) && inchar () != EOF);
1326
1327             if (!(flags & SUPPRESS))
1328               {
1329                 *wstr++ = L'\0';
1330
1331                 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1332                   {
1333                     wchar_t *cp = (wchar_t *) realloc (*strptr,
1334                                                        ((wstr
1335                                                          - (wchar_t *) *strptr)
1336                                                         * sizeof(wchar_t)));
1337                     if (cp != NULL)
1338                       *strptr = (char *) cp;
1339                   }
1340                 strptr = NULL;
1341
1342                 ++done;
1343               }
1344           }
1345           break;
1346
1347         case L_('x'):   /* Hexadecimal integer.  */
1348         case L_('X'):   /* Ditto.  */
1349           base = 16;
1350           goto number;
1351
1352         case L_('o'):   /* Octal integer.  */
1353           base = 8;
1354           goto number;
1355
1356         case L_('u'):   /* Unsigned decimal integer.  */
1357           base = 10;
1358           goto number;
1359
1360         case L_('d'):   /* Signed decimal integer.  */
1361           base = 10;
1362           flags |= NUMBER_SIGNED;
1363           goto number;
1364
1365         case L_('i'):   /* Generic number.  */
1366           base = 0;
1367           flags |= NUMBER_SIGNED;
1368
1369         number:
1370           c = inchar ();
1371           if (__builtin_expect (c == EOF, 0))
1372             input_error ();
1373
1374           /* Check for a sign.  */
1375           if (c == L_('-') || c == L_('+'))
1376             {
1377               ADDW (c);
1378               if (width > 0)
1379                 --width;
1380               c = inchar ();
1381             }
1382
1383           /* Look for a leading indication of base.  */
1384           if (width != 0 && c == L_('0'))
1385             {
1386               if (width > 0)
1387                 --width;
1388
1389               ADDW (c);
1390               c = inchar ();
1391
1392               if (width != 0 && TOLOWER (c) == L_('x'))
1393                 {
1394                   if (base == 0)
1395                     base = 16;
1396                   if (base == 16)
1397                     {
1398                       if (width > 0)
1399                         --width;
1400                       c = inchar ();
1401                     }
1402                 }
1403               else if (base == 0)
1404                 base = 8;
1405             }
1406
1407           if (base == 0)
1408             base = 10;
1409
1410           if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0))
1411             {
1412               int from_level;
1413               int to_level;
1414               int level;
1415 #ifdef COMPILE_WSCANF
1416               const wchar_t *wcdigits[10];
1417               const wchar_t *wcdigits_extended[10];
1418 #else
1419               const char *mbdigits[10];
1420               const char *mbdigits_extended[10];
1421 #endif
1422               /*  "to_inpunct" is a map from ASCII digits to their
1423                   equivalent in locale. This is defined for locales
1424                   which use an extra digits set.  */
1425               wctrans_t map = __wctrans ("to_inpunct");
1426               int n;
1427
1428               from_level = 0;
1429 #ifdef COMPILE_WSCANF
1430               to_level = _NL_CURRENT_WORD (LC_CTYPE,
1431                                            _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1432 #else
1433               to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
1434 #endif
1435
1436               /* Get the alternative digit forms if there are any.  */
1437               if (__builtin_expect (map != NULL, 0))
1438                 {
1439                   /*  Adding new level for extra digits set in locale file.  */
1440                   ++to_level;
1441
1442                   for (n = 0; n < 10; ++n)
1443                     {
1444 #ifdef COMPILE_WSCANF
1445                       wcdigits[n] = (const wchar_t *)
1446                         _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1447
1448                       wchar_t *wc_extended = (wchar_t *)
1449                         alloca ((to_level + 2) * sizeof (wchar_t));
1450                       __wmemcpy (wc_extended, wcdigits[n], to_level);
1451                       wc_extended[to_level] = __towctrans (L'0' + n, map);
1452                       wc_extended[to_level + 1] = '\0';
1453                       wcdigits_extended[n] = wc_extended;
1454 #else
1455                       mbdigits[n]
1456                         = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1457
1458                       /*  Get the equivalent wide char in map.  */
1459                       wint_t extra_wcdigit = __towctrans (L'0' + n, map);
1460
1461                       /*  Convert it to multibyte representation.  */
1462                       mbstate_t state;
1463                       memset (&state, '\0', sizeof (state));
1464
1465                       char extra_mbdigit[MB_LEN_MAX];
1466                       size_t mblen
1467                         = __wcrtomb (extra_mbdigit, extra_wcdigit, &state);
1468
1469                       if (mblen == (size_t) -1)
1470                         {
1471                           /*  Ignore this new level.  */
1472                           map = NULL;
1473                           break;
1474                         }
1475
1476                       /*  Calculate the length of mbdigits[n].  */
1477                       const char *last_char = mbdigits[n];
1478                       for (level = 0; level < to_level; ++level)
1479                         last_char = strchr (last_char, '\0') + 1;
1480
1481                       size_t mbdigits_len = last_char - mbdigits[n];
1482
1483                       /*  Allocate memory for extended multibyte digit.  */
1484                       char *mb_extended;
1485                       mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
1486
1487                       /*  And get the mbdigits + extra_digit string.  */
1488                       *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
1489                                                       mbdigits_len),
1490                                            extra_mbdigit, mblen) = '\0';
1491                       mbdigits_extended[n] = mb_extended;
1492 #endif
1493                     }
1494                 }
1495
1496               /* Read the number into workspace.  */
1497               while (c != EOF && width != 0)
1498                 {
1499                   /* In this round we get the pointer to the digit strings
1500                      and also perform the first round of comparisons.  */
1501                   for (n = 0; n < 10; ++n)
1502                     {
1503                       /* Get the string for the digits with value N.  */
1504 #ifdef COMPILE_WSCANF
1505                       if (__builtin_expect (map != NULL, 0))
1506                         wcdigits[n] = wcdigits_extended[n];
1507                       else
1508                         wcdigits[n] = (const wchar_t *)
1509                           _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1510                       wcdigits[n] += from_level;
1511
1512                       if (c == (wint_t) *wcdigits[n])
1513                         {
1514                           to_level = from_level;
1515                           break;
1516                         }
1517
1518                       /* Advance the pointer to the next string.  */
1519                       ++wcdigits[n];
1520 #else
1521                       const char *cmpp;
1522                       int avail = width > 0 ? width : INT_MAX;
1523
1524                       if (__builtin_expect (map != NULL, 0))
1525                         mbdigits[n] = mbdigits_extended[n];
1526                       else
1527                         mbdigits[n]
1528                           = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1529
1530                       for (level = 0; level < from_level; level++)
1531                         mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1532
1533                       cmpp = mbdigits[n];
1534                       while ((unsigned char) *cmpp == c && avail >= 0)
1535                         {
1536                           if (*++cmpp == '\0')
1537                             break;
1538                           else
1539                             {
1540                               if (avail == 0 || inchar () == EOF)
1541                                 break;
1542                               --avail;
1543                             }
1544                         }
1545
1546                       if (*cmpp == '\0')
1547                         {
1548                           if (width > 0)
1549                             width = avail;
1550                           to_level = from_level;
1551                           break;
1552                         }
1553
1554                       /* We are pushing all read characters back.  */
1555                       if (cmpp > mbdigits[n])
1556                         {
1557                           ungetc (c, s);
1558                           while (--cmpp > mbdigits[n])
1559                             ungetc_not_eof ((unsigned char) *cmpp, s);
1560                           c = (unsigned char) *cmpp;
1561                         }
1562
1563                       /* Advance the pointer to the next string.  */
1564                       mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1565 #endif
1566                     }
1567
1568                   if (n == 10)
1569                     {
1570                       /* Have not yet found the digit.  */
1571                       for (level = from_level + 1; level <= to_level; ++level)
1572                         {
1573                           /* Search all ten digits of this level.  */
1574                           for (n = 0; n < 10; ++n)
1575                             {
1576 #ifdef COMPILE_WSCANF
1577                               if (c == (wint_t) *wcdigits[n])
1578                                 break;
1579
1580                               /* Advance the pointer to the next string.  */
1581                               ++wcdigits[n];
1582 #else
1583                               const char *cmpp;
1584                               int avail = width > 0 ? width : INT_MAX;
1585
1586                               cmpp = mbdigits[n];
1587                               while ((unsigned char) *cmpp == c && avail >= 0)
1588                                 {
1589                                   if (*++cmpp == '\0')
1590                                     break;
1591                                   else
1592                                     {
1593                                       if (avail == 0 || inchar () == EOF)
1594                                         break;
1595                                       --avail;
1596                                     }
1597                                 }
1598
1599                               if (*cmpp == '\0')
1600                                 {
1601                                   if (width > 0)
1602                                     width = avail;
1603                                   break;
1604                                 }
1605
1606                               /* We are pushing all read characters back.  */
1607                               if (cmpp > mbdigits[n])
1608                                 {
1609                                   ungetc (c, s);
1610                                   while (--cmpp > mbdigits[n])
1611                                     ungetc_not_eof ((unsigned char) *cmpp, s);
1612                                   c = (unsigned char) *cmpp;
1613                                 }
1614
1615                               /* Advance the pointer to the next string.  */
1616                               mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1617 #endif
1618                             }
1619
1620                           if (n < 10)
1621                             {
1622                               /* Found it.  */
1623                               from_level = level;
1624                               to_level = level;
1625                               break;
1626                             }
1627                         }
1628                     }
1629
1630                   if (n < 10)
1631                     c = L_('0') + n;
1632                   else if (flags & GROUP)
1633                     {
1634                       /* Try matching against the thousands separator.  */
1635 #ifdef COMPILE_WSCANF
1636                       if (c != thousands)
1637                           break;
1638 #else
1639                       const char *cmpp = thousands;
1640                       int avail = width > 0 ? width : INT_MAX;
1641
1642                       while ((unsigned char) *cmpp == c && avail >= 0)
1643                         {
1644                           ADDW (c);
1645                           if (*++cmpp == '\0')
1646                             break;
1647                           else
1648                             {
1649                               if (avail == 0 || inchar () == EOF)
1650                                 break;
1651                               --avail;
1652                             }
1653                         }
1654
1655                       if (*cmpp != '\0')
1656                         {
1657                           /* We are pushing all read characters back.  */
1658                           if (cmpp > thousands)
1659                             {
1660                               wpsize -= cmpp - thousands;
1661                               ungetc (c, s);
1662                               while (--cmpp > thousands)
1663                                 ungetc_not_eof ((unsigned char) *cmpp, s);
1664                               c = (unsigned char) *cmpp;
1665                             }
1666                           break;
1667                         }
1668
1669                       if (width > 0)
1670                         width = avail;
1671
1672                       /* The last thousands character will be added back by
1673                          the ADDW below.  */
1674                         --wpsize;
1675 #endif
1676                     }
1677                   else
1678                     break;
1679
1680                   ADDW (c);
1681                   if (width > 0)
1682                     --width;
1683
1684                   c = inchar ();
1685                 }
1686             }
1687           else
1688             /* Read the number into workspace.  */
1689             while (c != EOF && width != 0)
1690               {
1691                 if (base == 16)
1692                   {
1693                     if (!ISXDIGIT (c))
1694                       break;
1695                   }
1696                 else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
1697                   {
1698                     if (base == 10 && (flags & GROUP))
1699                       {
1700                         /* Try matching against the thousands separator.  */
1701 #ifdef COMPILE_WSCANF
1702                         if (c != thousands)
1703                           break;
1704 #else
1705                         const char *cmpp = thousands;
1706                         int avail = width > 0 ? width : INT_MAX;
1707
1708                         while ((unsigned char) *cmpp == c && avail >= 0)
1709                           {
1710                             ADDW (c);
1711                             if (*++cmpp == '\0')
1712                               break;
1713                             else
1714                               {
1715                                 if (avail == 0 || inchar () == EOF)
1716                                   break;
1717                                 --avail;
1718                               }
1719                           }
1720
1721                         if (*cmpp != '\0')
1722                           {
1723                             /* We are pushing all read characters back.  */
1724                             if (cmpp > thousands)
1725                               {
1726                                 wpsize -= cmpp - thousands;
1727                                 ungetc (c, s);
1728                                 while (--cmpp > thousands)
1729                                   ungetc_not_eof ((unsigned char) *cmpp, s);
1730                                 c = (unsigned char) *cmpp;
1731                               }
1732                             break;
1733                           }
1734
1735                         if (width > 0)
1736                           width = avail;
1737
1738                         /* The last thousands character will be added back by
1739                            the ADDW below.  */
1740                         --wpsize;
1741 #endif
1742                       }
1743                     else
1744                       break;
1745                   }
1746                 ADDW (c);
1747                 if (width > 0)
1748                   --width;
1749
1750                 c = inchar ();
1751               }
1752
1753           if (wpsize == 0
1754               || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1755             {
1756               /* There was no number.  If we are supposed to read a pointer
1757                  we must recognize "(nil)" as well.  */
1758               if (__builtin_expect (wpsize == 0
1759                                     && (flags & READ_POINTER)
1760                                     && (width < 0 || width >= 0)
1761                                     && c == '('
1762                                     && TOLOWER (inchar ()) == L_('n')
1763                                     && TOLOWER (inchar ()) == L_('i')
1764                                     && TOLOWER (inchar ()) == L_('l')
1765                                     && inchar () == L_(')'), 1))
1766                 /* We must produce the value of a NULL pointer.  A single
1767                    '0' digit is enough.  */
1768                 ADDW (L_('0'));
1769               else
1770                 {
1771                   /* The last read character is not part of the number
1772                      anymore.  */
1773                   ungetc (c, s);
1774
1775                   conv_error ();
1776                 }
1777             }
1778           else
1779             /* The just read character is not part of the number anymore.  */
1780             ungetc (c, s);
1781
1782           /* Convert the number.  */
1783           ADDW (L_('\0'));
1784           if (need_longlong && (flags & LONGDBL))
1785             {
1786               if (flags & NUMBER_SIGNED)
1787                 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1788               else
1789                 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1790             }
1791           else
1792             {
1793               if (flags & NUMBER_SIGNED)
1794                 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1795               else
1796                 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1797             }
1798           if (__builtin_expect (wp == tw, 0))
1799             conv_error ();
1800
1801           if (!(flags & SUPPRESS))
1802             {
1803               if (flags & NUMBER_SIGNED)
1804                 {
1805                   if (need_longlong && (flags & LONGDBL))
1806                     *ARG (LONGLONG int *) = num.q;
1807                   else if (need_long && (flags & LONG))
1808                     *ARG (long int *) = num.l;
1809                   else if (flags & SHORT)
1810                     *ARG (short int *) = (short int) num.l;
1811                   else if (!(flags & CHAR))
1812                     *ARG (int *) = (int) num.l;
1813                   else
1814                     *ARG (signed char *) = (signed char) num.ul;
1815                 }
1816               else
1817                 {
1818                   if (need_longlong && (flags & LONGDBL))
1819                     *ARG (unsigned LONGLONG int *) = num.uq;
1820                   else if (need_long && (flags & LONG))
1821                     *ARG (unsigned long int *) = num.ul;
1822                   else if (flags & SHORT)
1823                     *ARG (unsigned short int *)
1824                       = (unsigned short int) num.ul;
1825                   else if (!(flags & CHAR))
1826                     *ARG (unsigned int *) = (unsigned int) num.ul;
1827                   else
1828                     *ARG (unsigned char *) = (unsigned char) num.ul;
1829                 }
1830               ++done;
1831             }
1832           break;
1833
1834         case L_('e'):   /* Floating-point numbers.  */
1835         case L_('E'):
1836         case L_('f'):
1837         case L_('F'):
1838         case L_('g'):
1839         case L_('G'):
1840         case L_('a'):
1841         case L_('A'):
1842           c = inchar ();
1843           if (width > 0)
1844             --width;
1845           if (__builtin_expect (c == EOF, 0))
1846             input_error ();
1847
1848           got_dot = got_e = 0;
1849
1850           /* Check for a sign.  */
1851           if (c == L_('-') || c == L_('+'))
1852             {
1853               negative = c == L_('-');
1854               if (__builtin_expect (width == 0 || inchar () == EOF, 0))
1855                 /* EOF is only an input error before we read any chars.  */
1856                 conv_error ();
1857               if (width > 0)
1858                 --width;
1859             }
1860           else
1861             negative = 0;
1862
1863           /* Take care for the special arguments "nan" and "inf".  */
1864           if (TOLOWER (c) == L_('n'))
1865             {
1866               /* Maybe "nan".  */
1867               ADDW (c);
1868               if (__builtin_expect (width == 0
1869                                     || inchar () == EOF
1870                                     || TOLOWER (c) != L_('a'), 0))
1871                 conv_error ();
1872               if (width > 0)
1873                 --width;
1874               ADDW (c);
1875               if (__builtin_expect (width == 0
1876                                     || inchar () == EOF
1877                                     || TOLOWER (c) != L_('n'), 0))
1878                 conv_error ();
1879               if (width > 0)
1880                 --width;
1881               ADDW (c);
1882               /* It is "nan".  */
1883               goto scan_float;
1884             }
1885           else if (TOLOWER (c) == L_('i'))
1886             {
1887               /* Maybe "inf" or "infinity".  */
1888               ADDW (c);
1889               if (__builtin_expect (width == 0
1890                                     || inchar () == EOF
1891                                     || TOLOWER (c) != L_('n'), 0))
1892                 conv_error ();
1893               if (width > 0)
1894                 --width;
1895               ADDW (c);
1896               if (__builtin_expect (width == 0
1897                                     || inchar () == EOF
1898                                     || TOLOWER (c) != L_('f'), 0))
1899                 conv_error ();
1900               if (width > 0)
1901                 --width;
1902               ADDW (c);
1903               /* It is as least "inf".  */
1904               if (width != 0 && inchar () != EOF)
1905                 {
1906                   if (TOLOWER (c) == L_('i'))
1907                     {
1908                       if (width > 0)
1909                         --width;
1910                       /* Now we have to read the rest as well.  */
1911                       ADDW (c);
1912                       if (__builtin_expect (width == 0
1913                                             || inchar () == EOF
1914                                             || TOLOWER (c) != L_('n'), 0))
1915                         conv_error ();
1916                       if (width > 0)
1917                         --width;
1918                       ADDW (c);
1919                       if (__builtin_expect (width == 0
1920                                             || inchar () == EOF
1921                                             || TOLOWER (c) != L_('i'), 0))
1922                         conv_error ();
1923                       if (width > 0)
1924                         --width;
1925                       ADDW (c);
1926                       if (__builtin_expect (width == 0
1927                                             || inchar () == EOF
1928                                             || TOLOWER (c) != L_('t'), 0))
1929                         conv_error ();
1930                       if (width > 0)
1931                         --width;
1932                       ADDW (c);
1933                       if (__builtin_expect (width == 0
1934                                             || inchar () == EOF
1935                                             || TOLOWER (c) != L_('y'), 0))
1936                         conv_error ();
1937                       if (width > 0)
1938                         --width;
1939                       ADDW (c);
1940                     }
1941                   else
1942                     /* Never mind.  */
1943                     ungetc (c, s);
1944                 }
1945               goto scan_float;
1946             }
1947
1948           exp_char = L_('e');
1949           if (width != 0 && c == L_('0'))
1950             {
1951               ADDW (c);
1952               c = inchar ();
1953               if (width > 0)
1954                 --width;
1955               if (width != 0 && TOLOWER (c) == L_('x'))
1956                 {
1957                   /* It is a number in hexadecimal format.  */
1958                   ADDW (c);
1959
1960                   flags |= HEXA_FLOAT;
1961                   exp_char = L_('p');
1962
1963                   /* Grouping is not allowed.  */
1964                   flags &= ~GROUP;
1965                   c = inchar ();
1966                   if (width > 0)
1967                     --width;
1968                 }
1969             }
1970
1971           while (1)
1972             {
1973               if (ISDIGIT (c))
1974                 ADDW (c);
1975               else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c))
1976                 ADDW (c);
1977               else if (got_e && wp[wpsize - 1] == exp_char
1978                        && (c == L_('-') || c == L_('+')))
1979                 ADDW (c);
1980               else if (wpsize > 0 && !got_e
1981                        && (CHAR_T) TOLOWER (c) == exp_char)
1982                 {
1983                   ADDW (exp_char);
1984                   got_e = got_dot = 1;
1985                 }
1986               else
1987                 {
1988 #ifdef COMPILE_WSCANF
1989                   if (! got_dot && c == decimal)
1990                     {
1991                       ADDW (c);
1992                       got_dot = 1;
1993                     }
1994                   else if ((flags & GROUP) != 0 && ! got_dot && c == thousands)
1995                     ADDW (c);
1996                   else
1997                     {
1998                       /* The last read character is not part of the number
1999                          anymore.  */
2000                       ungetc (c, s);
2001                       break;
2002                     }
2003 #else
2004                   const char *cmpp = decimal;
2005                   int avail = width > 0 ? width : INT_MAX;
2006
2007                   if (! got_dot)
2008                     {
2009                       while ((unsigned char) *cmpp == c && avail >= 0)
2010                         if (*++cmpp == '\0')
2011                           break;
2012                         else
2013                           {
2014                             if (avail == 0 || inchar () == EOF)
2015                               break;
2016                             --avail;
2017                           }
2018                     }
2019
2020                   if (*cmpp == '\0')
2021                     {
2022                       /* Add all the characters.  */
2023                       for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
2024                         ADDW ((unsigned char) *cmpp);
2025                       if (width > 0)
2026                         width = avail;
2027                       got_dot = 1;
2028                     }
2029                   else
2030                     {
2031                       /* Figure out whether it is a thousands separator.
2032                          There is one problem: we possibly read more than
2033                          one character.  We cannot push them back but since
2034                          we know that parts of the `decimal' string matched,
2035                          we can compare against it.  */
2036                       const char *cmp2p = thousands;
2037
2038                       if ((flags & GROUP) != 0 && ! got_dot)
2039                         {
2040                           while (cmp2p - thousands < cmpp - decimal
2041                                  && *cmp2p == decimal[cmp2p - thousands])
2042                             ++cmp2p;
2043                           if (cmp2p - thousands == cmpp - decimal)
2044                             {
2045                               while ((unsigned char) *cmp2p == c && avail >= 0)
2046                                 if (*++cmp2p == '\0')
2047                                   break;
2048                                 else
2049                                   {
2050                                     if (avail == 0 || inchar () == EOF)
2051                                       break;
2052                                     --avail;
2053                                   }
2054                             }
2055                         }
2056
2057                       if (cmp2p != NULL && *cmp2p == '\0')
2058                         {
2059                           /* Add all the characters.  */
2060                           for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
2061                             ADDW ((unsigned char) *cmpp);
2062                           if (width > 0)
2063                             width = avail;
2064                         }
2065                       else
2066                         {
2067                           /* The last read character is not part of the number
2068                              anymore.  */
2069                           ungetc (c, s);
2070                           break;
2071                         }
2072                     }
2073 #endif
2074                 }
2075
2076               if (width == 0 || inchar () == EOF)
2077                 break;
2078
2079               if (width > 0)
2080                 --width;
2081             }
2082
2083           wctrans_t map;
2084           if (__builtin_expect ((flags & I18N) != 0, 0)
2085               /* Hexadecimal floats make no sense, fixing localized
2086                  digits with ASCII letters.  */
2087               && !(flags & HEXA_FLOAT)
2088               /* Minimum requirement.  */
2089               && (wpsize == 0 || got_dot)
2090               && (map = __wctrans ("to_inpunct")) != NULL)
2091             {
2092               /* Reget the first character.  */
2093               inchar ();
2094
2095               /* Localized digits, decimal points, and thousands
2096                  separator.  */
2097               wint_t wcdigits[12];
2098
2099               /* First get decimal equivalent to check if we read it
2100                  or not.  */
2101               wcdigits[11] = __towctrans (L'.', map);
2102
2103               /* If we have not read any character or have just read
2104                  locale decimal point which matches the decimal point
2105                  for localized FP numbers, then we may have localized
2106                  digits.  Note, we test GOT_DOT above.  */
2107 #ifdef COMPILE_WSCANF
2108               if (wpsize == 0 || (wpsize == 1 && wcdigits[11] == decimal))
2109 #else
2110               char mbdigits[12][MB_LEN_MAX + 1];
2111
2112               mbstate_t state;
2113               memset (&state, '\0', sizeof (state));
2114
2115               bool match_so_far = wpsize == 0;
2116               size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &state);
2117               if (mblen != (size_t) -1)
2118                 {
2119                   mbdigits[11][mblen] = '\0';
2120                   match_so_far |= (wpsize == strlen (decimal)
2121                                    && strcmp (decimal, mbdigits[11]) == 0);
2122                 }
2123               else
2124                 {
2125                   size_t decimal_len = strlen (decimal);
2126                   /* This should always be the case but the data comes
2127                      from a file.  */
2128                   if (decimal_len <= MB_LEN_MAX)
2129                     {
2130                       match_so_far |= wpsize == decimal_len;
2131                       memcpy (mbdigits[11], decimal, decimal_len + 1);
2132                     }
2133                   else
2134                     match_so_far = false;
2135                 }
2136
2137               if (match_so_far)
2138 #endif
2139                 {
2140                   bool have_locthousands = (flags & GROUP) != 0;
2141
2142                   /* Now get the digits and the thousands-sep equivalents.  */
2143                   for (int n = 0; n < 11; ++n)
2144                     {
2145                       if (n < 10)
2146                         wcdigits[n] = __towctrans (L'0' + n, map);
2147                       else if (n == 10)
2148                         {
2149                           wcdigits[10] = __towctrans (L',', map);
2150                           have_locthousands &= wcdigits[10] != L'\0';
2151                         }
2152
2153 #ifndef COMPILE_WSCANF
2154                       memset (&state, '\0', sizeof (state));
2155
2156                       size_t mblen = __wcrtomb (mbdigits[n], wcdigits[n],
2157                                                 &state);
2158                       if (mblen == (size_t) -1)
2159                         {
2160                           if (n == 10)
2161                             {
2162                               if (have_locthousands)
2163                                 {
2164                                   size_t thousands_len = strlen (thousands);
2165                                   if (thousands_len <= MB_LEN_MAX)
2166                                     memcpy (mbdigits[10], thousands,
2167                                             thousands_len + 1);
2168                                   else
2169                                     have_locthousands = false;
2170                                 }
2171                             }
2172                           else
2173                             /* Ignore checking against localized digits.  */
2174                             goto no_i18nflt;
2175                         }
2176                       else
2177                         mbdigits[n][mblen] = '\0';
2178 #endif
2179                     }
2180
2181                   /* Start checking against localized digits, if
2182                      convertion is done correctly. */
2183                   while (1)
2184                     {
2185                       if (got_e && wp[wpsize - 1] == exp_char
2186                           && (c == L_('-') || c == L_('+')))
2187                         ADDW (c);
2188                       else if (wpsize > 0 && !got_e
2189                                && (CHAR_T) TOLOWER (c) == exp_char)
2190                         {
2191                           ADDW (exp_char);
2192                           got_e = got_dot = 1;
2193                         }
2194                       else
2195                         {
2196                           /* Check against localized digits, decimal point,
2197                              and thousands separator.  */
2198                           int n;
2199                           for (n = 0; n < 12; ++n)
2200                             {
2201 #ifdef COMPILE_WSCANF
2202                               if (c == wcdigits[n])
2203                                 {
2204                                   if (n < 10)
2205                                     ADDW (L_('0') + n);
2206                                   else if (n == 11 && !got_dot)
2207                                     {
2208                                       ADDW (decimal);
2209                                       got_dot = 1;
2210                                     }
2211                                   else if (n == 10 && have_locthousands
2212                                            && ! got_dot)
2213                                     ADDW (thousands);
2214                                   else
2215                                     /* The last read character is not part
2216                                        of the number anymore.  */
2217                                     n = 12;
2218
2219                                   break;
2220                                 }
2221 #else
2222                               const char *cmpp = mbdigits[n];
2223                               int avail = width > 0 ? width : INT_MAX;
2224
2225                               while ((unsigned char) *cmpp == c && avail >= 0)
2226                                 if (*++cmpp == '\0')
2227                                   break;
2228                                 else
2229                                   {
2230                                     if (avail == 0 || inchar () == EOF)
2231                                       break;
2232                                     --avail;
2233                                   }
2234                               if (*cmpp == '\0')
2235                                 {
2236                                   if (width > 0)
2237                                     width = avail;
2238
2239                                   if (n < 10)
2240                                     ADDW (L_('0') + n);
2241                                   else if (n == 11 && !got_dot)
2242                                     {
2243                                       /* Add all the characters.  */
2244                                       for (cmpp = decimal; *cmpp != '\0';
2245                                            ++cmpp)
2246                                         ADDW ((unsigned char) *cmpp);
2247
2248                                       got_dot = 1;
2249                                     }
2250                                   else if (n == 10 && (flags & GROUP) != 0
2251                                            && ! got_dot)
2252                                     {
2253                                       /* Add all the characters.  */
2254                                       for (cmpp = thousands; *cmpp != '\0';
2255                                            ++cmpp)
2256                                         ADDW ((unsigned char) *cmpp);
2257                                     }
2258                                   else
2259                                     /* The last read character is not part
2260                                        of the number anymore.  */
2261                                       n = 12;
2262
2263                                   break;
2264                                 }
2265
2266                               /* We are pushing all read characters back.  */
2267                               if (cmpp > mbdigits[n])
2268                                 {
2269                                   ungetc (c, s);
2270                                   while (--cmpp > mbdigits[n])
2271                                     ungetc_not_eof ((unsigned char) *cmpp, s);
2272                                   c = (unsigned char) *cmpp;
2273                                 }
2274 #endif
2275                             }
2276
2277                           if (n >= 12)
2278                             {
2279                               /* The last read character is not part
2280                                  of the number anymore.  */
2281                               ungetc (c, s);
2282                               break;
2283                             }
2284                         }
2285
2286                       if (width == 0 || inchar () == EOF)
2287                         break;
2288
2289                       if (width > 0)
2290                         --width;
2291                     }
2292                 }
2293
2294 #ifndef COMPILE_WSCANF
2295             no_i18nflt:
2296               ;
2297 #endif
2298             }
2299
2300           /* Have we read any character?  If we try to read a number
2301              in hexadecimal notation and we have read only the `0x'
2302              prefix this is an error.  */
2303           if (__builtin_expect (wpsize == 0
2304                                 || ((flags & HEXA_FLOAT) && wpsize == 2), 0))
2305             conv_error ();
2306
2307         scan_float:
2308           /* Convert the number.  */
2309           ADDW (L_('\0'));
2310           if ((flags & LONGDBL) && !__ldbl_is_dbl)
2311             {
2312               long double d = __strtold_internal (wp, &tw, flags & GROUP);
2313               if (!(flags & SUPPRESS) && tw != wp)
2314                 *ARG (long double *) = negative ? -d : d;
2315             }
2316           else if (flags & (LONG | LONGDBL))
2317             {
2318               double d = __strtod_internal (wp, &tw, flags & GROUP);
2319               if (!(flags & SUPPRESS) && tw != wp)
2320                 *ARG (double *) = negative ? -d : d;
2321             }
2322           else
2323             {
2324               float d = __strtof_internal (wp, &tw, flags & GROUP);
2325               if (!(flags & SUPPRESS) && tw != wp)
2326                 *ARG (float *) = negative ? -d : d;
2327             }
2328
2329           if (__builtin_expect (tw == wp, 0))
2330             conv_error ();
2331
2332           if (!(flags & SUPPRESS))
2333             ++done;
2334           break;
2335
2336         case L_('['):   /* Character class.  */
2337           if (flags & LONG)
2338             STRING_ARG (wstr, wchar_t, 100);
2339           else
2340             STRING_ARG (str, char, 100);
2341
2342           if (*f == L_('^'))
2343             {
2344               ++f;
2345               not_in = 1;
2346             }
2347           else
2348             not_in = 0;
2349
2350           if (width < 0)
2351             /* There is no width given so there is also no limit on the
2352                number of characters we read.  Therefore we set width to
2353                a very high value to make the algorithm easier.  */
2354             width = INT_MAX;
2355
2356 #ifdef COMPILE_WSCANF
2357           /* Find the beginning and the end of the scanlist.  We are not
2358              creating a lookup table since it would have to be too large.
2359              Instead we search each time through the string.  This is not
2360              a constant lookup time but who uses this feature deserves to
2361              be punished.  */
2362           tw = (wchar_t *) f;   /* Marks the beginning.  */
2363
2364           if (*f == L']')
2365             ++f;
2366
2367           while ((fc = *f++) != L'\0' && fc != L']');
2368
2369           if (__builtin_expect (fc == L'\0', 0))
2370             conv_error ();
2371           wchar_t *twend = (wchar_t *) f - 1;
2372 #else
2373           /* Fill WP with byte flags indexed by character.
2374              We will use this flag map for matching input characters.  */
2375           if (wpmax < UCHAR_MAX + 1)
2376             {
2377               wpmax = UCHAR_MAX + 1;
2378               wp = (char *) alloca (wpmax);
2379             }
2380           memset (wp, '\0', UCHAR_MAX + 1);
2381
2382           fc = *f;
2383           if (fc == ']' || fc == '-')
2384             {
2385               /* If ] or - appears before any char in the set, it is not
2386                  the terminator or separator, but the first char in the
2387                  set.  */
2388               wp[fc] = 1;
2389               ++f;
2390             }
2391
2392           while ((fc = *f++) != '\0' && fc != ']')
2393             if (fc == '-' && *f != '\0' && *f != ']'
2394                 && (unsigned char) f[-2] <= (unsigned char) *f)
2395               {
2396                 /* Add all characters from the one before the '-'
2397                    up to (but not including) the next format char.  */
2398                 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
2399                   wp[fc] = 1;
2400               }
2401             else
2402               /* Add the character to the flag map.  */
2403               wp[fc] = 1;
2404
2405           if (__builtin_expect (fc == '\0', 0))
2406             conv_error();
2407 #endif
2408
2409           if (flags & LONG)
2410             {
2411               size_t now = read_in;
2412 #ifdef COMPILE_WSCANF
2413               if (__builtin_expect (inchar () == WEOF, 0))
2414                 input_error ();
2415
2416               do
2417                 {
2418                   wchar_t *runp;
2419
2420                   /* Test whether it's in the scanlist.  */
2421                   runp = tw;
2422                   while (runp < twend)
2423                     {
2424                       if (runp[0] == L'-' && runp[1] != '\0'
2425                           && runp + 1 != twend
2426                           && runp != tw
2427                           && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2428                         {
2429                           /* Match against all characters in between the
2430                              first and last character of the sequence.  */
2431                           wchar_t wc;
2432
2433                           for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2434                             if ((wint_t) wc == c)
2435                               break;
2436
2437                           if (wc <= runp[1] && !not_in)
2438                             break;
2439                           if (wc <= runp[1] && not_in)
2440                             {
2441                               /* The current character is not in the
2442                                  scanset.  */
2443                               ungetc (c, s);
2444                               goto out;
2445                             }
2446
2447                           runp += 2;
2448                         }
2449                       else
2450                         {
2451                           if ((wint_t) *runp == c && !not_in)
2452                             break;
2453                           if ((wint_t) *runp == c && not_in)
2454                             {
2455                               ungetc (c, s);
2456                               goto out;
2457                             }
2458
2459                           ++runp;
2460                         }
2461                     }
2462
2463                   if (runp == twend && !not_in)
2464                     {
2465                       ungetc (c, s);
2466                       goto out;
2467                     }
2468
2469                   if (!(flags & SUPPRESS))
2470                     {
2471                       *wstr++ = c;
2472
2473                       if ((flags & MALLOC)
2474                           && wstr == (wchar_t *) *strptr + strsize)
2475                         {
2476                           /* Enlarge the buffer.  */
2477                           wstr = (wchar_t *) realloc (*strptr,
2478                                                       (2 * strsize)
2479                                                       * sizeof (wchar_t));
2480                           if (wstr == NULL)
2481                             {
2482                               /* Can't allocate that much.  Last-ditch
2483                                  effort.  */
2484                               wstr = (wchar_t *)
2485                                 realloc (*strptr, (strsize + 1)
2486                                                   * sizeof (wchar_t));
2487                               if (wstr == NULL)
2488                                 {
2489                                   if (flags & POSIX_MALLOC)
2490                                     {
2491                                       done = EOF;
2492                                       goto errout;
2493                                     }
2494                                   /* We lose.  Oh well.  Terminate the string
2495                                      and stop converting, so at least we don't
2496                                      skip any input.  */
2497                                   ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2498                                   strptr = NULL;
2499                                   ++done;
2500                                   conv_error ();
2501                                 }
2502                               else
2503                                 {
2504                                   *strptr = (char *) wstr;
2505                                   wstr += strsize;
2506                                   ++strsize;
2507                                 }
2508                             }
2509                           else
2510                             {
2511                               *strptr = (char *) wstr;
2512                               wstr += strsize;
2513                               strsize *= 2;
2514                             }
2515                         }
2516                     }
2517                 }
2518               while (--width > 0 && inchar () != WEOF);
2519             out:
2520 #else
2521               char buf[MB_LEN_MAX];
2522               size_t cnt = 0;
2523               mbstate_t cstate;
2524
2525               if (__builtin_expect (inchar () == EOF, 0))
2526                 input_error ();
2527
2528               memset (&cstate, '\0', sizeof (cstate));
2529
2530               do
2531                 {
2532                   if (wp[c] == not_in)
2533                     {
2534                       ungetc_not_eof (c, s);
2535                       break;
2536                     }
2537
2538                   /* This is easy.  */
2539                   if (!(flags & SUPPRESS))
2540                     {
2541                       size_t n;
2542
2543                       /* Convert it into a wide character.  */
2544                       buf[0] = c;
2545                       n = __mbrtowc (wstr, buf, 1, &cstate);
2546
2547                       if (n == (size_t) -2)
2548                         {
2549                           /* Possibly correct character, just not enough
2550                              input.  */
2551                           ++cnt;
2552                           assert (cnt < MB_CUR_MAX);
2553                           continue;
2554                         }
2555                       cnt = 0;
2556
2557                       ++wstr;
2558                       if ((flags & MALLOC)
2559                           && wstr == (wchar_t *) *strptr + strsize)
2560                         {
2561                           /* Enlarge the buffer.  */
2562                           wstr = (wchar_t *) realloc (*strptr,
2563                                                       (2 * strsize
2564                                                        * sizeof (wchar_t)));
2565                           if (wstr == NULL)
2566                             {
2567                               /* Can't allocate that much.  Last-ditch
2568                                  effort.  */
2569                               wstr = (wchar_t *)
2570                                 realloc (*strptr, ((strsize + 1)
2571                                                    * sizeof (wchar_t)));
2572                               if (wstr == NULL)
2573                                 {
2574                                   if (flags & POSIX_MALLOC)
2575                                     {
2576                                       done = EOF;
2577                                       goto errout;
2578                                     }
2579                                   /* We lose.  Oh well.  Terminate the
2580                                      string and stop converting,
2581                                      so at least we don't skip any input.  */
2582                                   ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2583                                   strptr = NULL;
2584                                   ++done;
2585                                   conv_error ();
2586                                 }
2587                               else
2588                                 {
2589                                   *strptr = (char *) wstr;
2590                                   wstr += strsize;
2591                                   ++strsize;
2592                                 }
2593                             }
2594                           else
2595                             {
2596                               *strptr = (char *) wstr;
2597                               wstr += strsize;
2598                               strsize *= 2;
2599                             }
2600                         }
2601                     }
2602
2603                   if (--width <= 0)
2604                     break;
2605                 }
2606               while (inchar () != EOF);
2607
2608               if (__builtin_expect (cnt != 0, 0))
2609                 /* We stopped in the middle of recognizing another
2610                    character.  That's a problem.  */
2611                 encode_error ();
2612 #endif
2613
2614               if (__builtin_expect (now == read_in, 0))
2615                 /* We haven't succesfully read any character.  */
2616                 conv_error ();
2617
2618               if (!(flags & SUPPRESS))
2619                 {
2620                   *wstr++ = L'\0';
2621
2622                   if ((flags & MALLOC)
2623                       && wstr - (wchar_t *) *strptr != strsize)
2624                     {
2625                       wchar_t *cp = (wchar_t *)
2626                         realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2627                                            * sizeof(wchar_t)));
2628                       if (cp != NULL)
2629                         *strptr = (char *) cp;
2630                     }
2631                   strptr = NULL;
2632
2633                   ++done;
2634                 }
2635             }
2636           else
2637             {
2638               size_t now = read_in;
2639
2640               if (__builtin_expect (inchar () == EOF, 0))
2641                 input_error ();
2642
2643 #ifdef COMPILE_WSCANF
2644
2645               memset (&state, '\0', sizeof (state));
2646
2647               do
2648                 {
2649                   wchar_t *runp;
2650                   size_t n;
2651
2652                   /* Test whether it's in the scanlist.  */
2653                   runp = tw;
2654                   while (runp < twend)
2655                     {
2656                       if (runp[0] == L'-' && runp[1] != '\0'
2657                           && runp + 1 != twend
2658                           && runp != tw
2659                           && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2660                         {
2661                           /* Match against all characters in between the
2662                              first and last character of the sequence.  */
2663                           wchar_t wc;
2664
2665                           for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2666                             if ((wint_t) wc == c)
2667                               break;
2668
2669                           if (wc <= runp[1] && !not_in)
2670                             break;
2671                           if (wc <= runp[1] && not_in)
2672                             {
2673                               /* The current character is not in the
2674                                  scanset.  */
2675                               ungetc (c, s);
2676                               goto out2;
2677                             }
2678
2679                           runp += 2;
2680                         }
2681                       else
2682                         {
2683                           if ((wint_t) *runp == c && !not_in)
2684                             break;
2685                           if ((wint_t) *runp == c && not_in)
2686                             {
2687                               ungetc (c, s);
2688                               goto out2;
2689                             }
2690
2691                           ++runp;
2692                         }
2693                     }
2694
2695                   if (runp == twend && !not_in)
2696                     {
2697                       ungetc (c, s);
2698                       goto out2;
2699                     }
2700
2701                   if (!(flags & SUPPRESS))
2702                     {
2703                       if ((flags & MALLOC)
2704                           && str + MB_CUR_MAX >= *strptr + strsize)
2705                         {
2706                           /* Enlarge the buffer.  */
2707                           size_t strleng = str - *strptr;
2708                           char *newstr;
2709
2710                           newstr = (char *) realloc (*strptr, 2 * strsize);
2711                           if (newstr == NULL)
2712                             {
2713                               /* Can't allocate that much.  Last-ditch
2714                                  effort.  */
2715                               newstr = (char *) realloc (*strptr,
2716                                                          strleng + MB_CUR_MAX);
2717                               if (newstr == NULL)
2718                                 {
2719                                   if (flags & POSIX_MALLOC)
2720                                     {
2721                                       done = EOF;
2722                                       goto errout;
2723                                     }
2724                                   /* We lose.  Oh well.  Terminate the string
2725                                      and stop converting, so at least we don't
2726                                      skip any input.  */
2727                                   ((char *) (*strptr))[strleng] = '\0';
2728                                   strptr = NULL;
2729                                   ++done;
2730                                   conv_error ();
2731                                 }
2732                               else
2733                                 {
2734                                   *strptr = newstr;
2735                                   str = newstr + strleng;
2736                                   strsize = strleng + MB_CUR_MAX;
2737                                 }
2738                             }
2739                           else
2740                             {
2741                               *strptr = newstr;
2742                               str = newstr + strleng;
2743                               strsize *= 2;
2744                             }
2745                         }
2746                     }
2747
2748                   n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2749                   if (__builtin_expect (n == (size_t) -1, 0))
2750                     encode_error ();
2751
2752                   assert (n <= MB_CUR_MAX);
2753                   str += n;
2754                 }
2755               while (--width > 0 && inchar () != WEOF);
2756             out2:
2757 #else
2758               do
2759                 {
2760                   if (wp[c] == not_in)
2761                     {
2762                       ungetc_not_eof (c, s);
2763                       break;
2764                     }
2765
2766                   /* This is easy.  */
2767                   if (!(flags & SUPPRESS))
2768                     {
2769                       *str++ = c;
2770                       if ((flags & MALLOC)
2771                           && (char *) str == *strptr + strsize)
2772                         {
2773                           /* Enlarge the buffer.  */
2774                           size_t newsize = 2 * strsize;
2775
2776                         allocagain:
2777                           str = (char *) realloc (*strptr, newsize);
2778                           if (str == NULL)
2779                             {
2780                               /* Can't allocate that much.  Last-ditch
2781                                  effort.  */
2782                               if (newsize > strsize + 1)
2783                                 {
2784                                   newsize = strsize + 1;
2785                                   goto allocagain;
2786                                 }
2787                               if (flags & POSIX_MALLOC)
2788                                 {
2789                                   done = EOF;
2790                                   goto errout;
2791                                 }
2792                               /* We lose.  Oh well.  Terminate the
2793                                  string and stop converting,
2794                                  so at least we don't skip any input.  */
2795                               ((char *) (*strptr))[strsize - 1] = '\0';
2796                               strptr = NULL;
2797                               ++done;
2798                               conv_error ();
2799                             }
2800                           else
2801                             {
2802                               *strptr = (char *) str;
2803                               str += strsize;
2804                               strsize = newsize;
2805                             }
2806                         }
2807                     }
2808                 }
2809               while (--width > 0 && inchar () != EOF);
2810 #endif
2811
2812               if (__builtin_expect (now == read_in, 0))
2813                 /* We haven't succesfully read any character.  */
2814                 conv_error ();
2815
2816               if (!(flags & SUPPRESS))
2817                 {
2818 #ifdef COMPILE_WSCANF
2819                   /* We have to emit the code to get into the initial
2820                      state.  */
2821                   char buf[MB_LEN_MAX];
2822                   size_t n = __wcrtomb (buf, L'\0', &state);
2823                   if (n > 0 && (flags & MALLOC)
2824                       && str + n >= *strptr + strsize)
2825                     {
2826                       /* Enlarge the buffer.  */
2827                       size_t strleng = str - *strptr;
2828                       char *newstr;
2829
2830                       newstr = (char *) realloc (*strptr, strleng + n + 1);
2831                       if (newstr == NULL)
2832                         {
2833                           if (flags & POSIX_MALLOC)
2834                             {
2835                               done = EOF;
2836                               goto errout;
2837                             }
2838                           /* We lose.  Oh well.  Terminate the string
2839                              and stop converting, so at least we don't
2840                              skip any input.  */
2841                           ((char *) (*strptr))[strleng] = '\0';
2842                           strptr = NULL;
2843                           ++done;
2844                           conv_error ();
2845                         }
2846                       else
2847                         {
2848                           *strptr = newstr;
2849                           str = newstr + strleng;
2850                           strsize = strleng + n + 1;
2851                         }
2852                     }
2853
2854                   str = __mempcpy (str, buf, n);
2855 #endif
2856                   *str++ = '\0';
2857
2858                   if ((flags & MALLOC) && str - *strptr != strsize)
2859                     {
2860                       char *cp = (char *) realloc (*strptr, str - *strptr);
2861                       if (cp != NULL)
2862                         *strptr = cp;
2863                     }
2864                   strptr = NULL;
2865
2866                   ++done;
2867                 }
2868             }
2869           break;
2870
2871         case L_('p'):   /* Generic pointer.  */
2872           base = 16;
2873           /* A PTR must be the same size as a `long int'.  */
2874           flags &= ~(SHORT|LONGDBL);
2875           if (need_long)
2876             flags |= LONG;
2877           flags |= READ_POINTER;
2878           goto number;
2879
2880         default:
2881           /* If this is an unknown format character punt.  */
2882           conv_error ();
2883         }
2884     }
2885
2886   /* The last thing we saw int the format string was a white space.
2887      Consume the last white spaces.  */
2888   if (skip_space)
2889     {
2890       do
2891         c = inchar ();
2892       while (ISSPACE (c));
2893       ungetc (c, s);
2894     }
2895
2896  errout:
2897   /* Unlock stream.  */
2898   UNLOCK_STREAM (s);
2899
2900   if (use_malloc)
2901     free (wp);
2902
2903   if (errp != NULL)
2904     *errp |= errval;
2905
2906   if (__builtin_expect (done == EOF, 0))
2907     {
2908       if (__builtin_expect (ptrs_to_free != NULL, 0))
2909         {
2910           struct ptrs_to_free *p = ptrs_to_free;
2911           while (p != NULL)
2912             {
2913               for (size_t cnt = 0; cnt < p->count; ++cnt)
2914                 {
2915                   free (*p->ptrs[cnt]);
2916                   *p->ptrs[cnt] = NULL;
2917                 }
2918               p = p->next;
2919               ptrs_to_free = p;
2920             }
2921         }
2922     }
2923   else if (__builtin_expect (strptr != NULL, 0))
2924     {
2925       free (*strptr);
2926       *strptr = NULL;
2927     }
2928   return done;
2929 }
2930
2931 #ifdef COMPILE_WSCANF
2932 int
2933 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2934 {
2935   return _IO_vfwscanf (s, format, argptr, NULL);
2936 }
2937 ldbl_weak_alias (__vfwscanf, vfwscanf)
2938 #else
2939 int
2940 ___vfscanf (FILE *s, const char *format, va_list argptr)
2941 {
2942   return _IO_vfscanf_internal (s, format, argptr, NULL);
2943 }
2944 ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
2945 ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf)
2946 ldbl_strong_alias (___vfscanf, __vfscanf)
2947 ldbl_hidden_def (___vfscanf, __vfscanf)
2948 ldbl_weak_alias (___vfscanf, vfscanf)
2949 #endif