78dc2fcfe54132be9718a2959ab8541cca501e7c
[platform/upstream/glibc.git] / stdio-common / vfscanf.c
1 /* Copyright (C) 1991-2013 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   const CHAR_T *f = format;
210   UCHAR_T fc;   /* Current character of the format.  */
211   WINT_T done = 0;      /* Assignments done.  */
212   size_t read_in = 0;   /* Chars read in.  */
213   WINT_T c = 0; /* Last char read.  */
214   int width;            /* Maximum field width.  */
215   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_digit, 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_digit = 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                 {
1975                   ADDW (c);
1976                   got_digit = 1;
1977                 }
1978               else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c))
1979                 {
1980                   ADDW (c);
1981                   got_digit = 1;
1982                 }
1983               else if (got_e && wp[wpsize - 1] == exp_char
1984                        && (c == L_('-') || c == L_('+')))
1985                 ADDW (c);
1986               else if (got_digit && !got_e
1987                        && (CHAR_T) TOLOWER (c) == exp_char)
1988                 {
1989                   ADDW (exp_char);
1990                   got_e = got_dot = 1;
1991                 }
1992               else
1993                 {
1994 #ifdef COMPILE_WSCANF
1995                   if (! got_dot && c == decimal)
1996                     {
1997                       ADDW (c);
1998                       got_dot = 1;
1999                     }
2000                   else if ((flags & GROUP) != 0 && ! got_dot && c == thousands)
2001                     ADDW (c);
2002                   else
2003                     {
2004                       /* The last read character is not part of the number
2005                          anymore.  */
2006                       ungetc (c, s);
2007                       break;
2008                     }
2009 #else
2010                   const char *cmpp = decimal;
2011                   int avail = width > 0 ? width : INT_MAX;
2012
2013                   if (! got_dot)
2014                     {
2015                       while ((unsigned char) *cmpp == c && avail >= 0)
2016                         if (*++cmpp == '\0')
2017                           break;
2018                         else
2019                           {
2020                             if (avail == 0 || inchar () == EOF)
2021                               break;
2022                             --avail;
2023                           }
2024                     }
2025
2026                   if (*cmpp == '\0')
2027                     {
2028                       /* Add all the characters.  */
2029                       for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
2030                         ADDW ((unsigned char) *cmpp);
2031                       if (width > 0)
2032                         width = avail;
2033                       got_dot = 1;
2034                     }
2035                   else
2036                     {
2037                       /* Figure out whether it is a thousands separator.
2038                          There is one problem: we possibly read more than
2039                          one character.  We cannot push them back but since
2040                          we know that parts of the `decimal' string matched,
2041                          we can compare against it.  */
2042                       const char *cmp2p = thousands;
2043
2044                       if ((flags & GROUP) != 0 && ! got_dot)
2045                         {
2046                           while (cmp2p - thousands < cmpp - decimal
2047                                  && *cmp2p == decimal[cmp2p - thousands])
2048                             ++cmp2p;
2049                           if (cmp2p - thousands == cmpp - decimal)
2050                             {
2051                               while ((unsigned char) *cmp2p == c && avail >= 0)
2052                                 if (*++cmp2p == '\0')
2053                                   break;
2054                                 else
2055                                   {
2056                                     if (avail == 0 || inchar () == EOF)
2057                                       break;
2058                                     --avail;
2059                                   }
2060                             }
2061                         }
2062
2063                       if (cmp2p != NULL && *cmp2p == '\0')
2064                         {
2065                           /* Add all the characters.  */
2066                           for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
2067                             ADDW ((unsigned char) *cmpp);
2068                           if (width > 0)
2069                             width = avail;
2070                         }
2071                       else
2072                         {
2073                           /* The last read character is not part of the number
2074                              anymore.  */
2075                           ungetc (c, s);
2076                           break;
2077                         }
2078                     }
2079 #endif
2080                 }
2081
2082               if (width == 0 || inchar () == EOF)
2083                 break;
2084
2085               if (width > 0)
2086                 --width;
2087             }
2088
2089           wctrans_t map;
2090           if (__builtin_expect ((flags & I18N) != 0, 0)
2091               /* Hexadecimal floats make no sense, fixing localized
2092                  digits with ASCII letters.  */
2093               && !(flags & HEXA_FLOAT)
2094               /* Minimum requirement.  */
2095               && (wpsize == 0 || got_dot)
2096               && (map = __wctrans ("to_inpunct")) != NULL)
2097             {
2098               /* Reget the first character.  */
2099               inchar ();
2100
2101               /* Localized digits, decimal points, and thousands
2102                  separator.  */
2103               wint_t wcdigits[12];
2104
2105               /* First get decimal equivalent to check if we read it
2106                  or not.  */
2107               wcdigits[11] = __towctrans (L'.', map);
2108
2109               /* If we have not read any character or have just read
2110                  locale decimal point which matches the decimal point
2111                  for localized FP numbers, then we may have localized
2112                  digits.  Note, we test GOT_DOT above.  */
2113 #ifdef COMPILE_WSCANF
2114               if (wpsize == 0 || (wpsize == 1 && wcdigits[11] == decimal))
2115 #else
2116               char mbdigits[12][MB_LEN_MAX + 1];
2117
2118               mbstate_t state;
2119               memset (&state, '\0', sizeof (state));
2120
2121               bool match_so_far = wpsize == 0;
2122               size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &state);
2123               if (mblen != (size_t) -1)
2124                 {
2125                   mbdigits[11][mblen] = '\0';
2126                   match_so_far |= (wpsize == strlen (decimal)
2127                                    && strcmp (decimal, mbdigits[11]) == 0);
2128                 }
2129               else
2130                 {
2131                   size_t decimal_len = strlen (decimal);
2132                   /* This should always be the case but the data comes
2133                      from a file.  */
2134                   if (decimal_len <= MB_LEN_MAX)
2135                     {
2136                       match_so_far |= wpsize == decimal_len;
2137                       memcpy (mbdigits[11], decimal, decimal_len + 1);
2138                     }
2139                   else
2140                     match_so_far = false;
2141                 }
2142
2143               if (match_so_far)
2144 #endif
2145                 {
2146                   bool have_locthousands = (flags & GROUP) != 0;
2147
2148                   /* Now get the digits and the thousands-sep equivalents.  */
2149                   for (int n = 0; n < 11; ++n)
2150                     {
2151                       if (n < 10)
2152                         wcdigits[n] = __towctrans (L'0' + n, map);
2153                       else if (n == 10)
2154                         {
2155                           wcdigits[10] = __towctrans (L',', map);
2156                           have_locthousands &= wcdigits[10] != L'\0';
2157                         }
2158
2159 #ifndef COMPILE_WSCANF
2160                       memset (&state, '\0', sizeof (state));
2161
2162                       size_t mblen = __wcrtomb (mbdigits[n], wcdigits[n],
2163                                                 &state);
2164                       if (mblen == (size_t) -1)
2165                         {
2166                           if (n == 10)
2167                             {
2168                               if (have_locthousands)
2169                                 {
2170                                   size_t thousands_len = strlen (thousands);
2171                                   if (thousands_len <= MB_LEN_MAX)
2172                                     memcpy (mbdigits[10], thousands,
2173                                             thousands_len + 1);
2174                                   else
2175                                     have_locthousands = false;
2176                                 }
2177                             }
2178                           else
2179                             /* Ignore checking against localized digits.  */
2180                             goto no_i18nflt;
2181                         }
2182                       else
2183                         mbdigits[n][mblen] = '\0';
2184 #endif
2185                     }
2186
2187                   /* Start checking against localized digits, if
2188                      conversion is done correctly. */
2189                   while (1)
2190                     {
2191                       if (got_e && wp[wpsize - 1] == exp_char
2192                           && (c == L_('-') || c == L_('+')))
2193                         ADDW (c);
2194                       else if (wpsize > 0 && !got_e
2195                                && (CHAR_T) TOLOWER (c) == exp_char)
2196                         {
2197                           ADDW (exp_char);
2198                           got_e = got_dot = 1;
2199                         }
2200                       else
2201                         {
2202                           /* Check against localized digits, decimal point,
2203                              and thousands separator.  */
2204                           int n;
2205                           for (n = 0; n < 12; ++n)
2206                             {
2207 #ifdef COMPILE_WSCANF
2208                               if (c == wcdigits[n])
2209                                 {
2210                                   if (n < 10)
2211                                     ADDW (L_('0') + n);
2212                                   else if (n == 11 && !got_dot)
2213                                     {
2214                                       ADDW (decimal);
2215                                       got_dot = 1;
2216                                     }
2217                                   else if (n == 10 && have_locthousands
2218                                            && ! got_dot)
2219                                     ADDW (thousands);
2220                                   else
2221                                     /* The last read character is not part
2222                                        of the number anymore.  */
2223                                     n = 12;
2224
2225                                   break;
2226                                 }
2227 #else
2228                               const char *cmpp = mbdigits[n];
2229                               int avail = width > 0 ? width : INT_MAX;
2230
2231                               while ((unsigned char) *cmpp == c && avail >= 0)
2232                                 if (*++cmpp == '\0')
2233                                   break;
2234                                 else
2235                                   {
2236                                     if (avail == 0 || inchar () == EOF)
2237                                       break;
2238                                     --avail;
2239                                   }
2240                               if (*cmpp == '\0')
2241                                 {
2242                                   if (width > 0)
2243                                     width = avail;
2244
2245                                   if (n < 10)
2246                                     ADDW (L_('0') + n);
2247                                   else if (n == 11 && !got_dot)
2248                                     {
2249                                       /* Add all the characters.  */
2250                                       for (cmpp = decimal; *cmpp != '\0';
2251                                            ++cmpp)
2252                                         ADDW ((unsigned char) *cmpp);
2253
2254                                       got_dot = 1;
2255                                     }
2256                                   else if (n == 10 && (flags & GROUP) != 0
2257                                            && ! got_dot)
2258                                     {
2259                                       /* Add all the characters.  */
2260                                       for (cmpp = thousands; *cmpp != '\0';
2261                                            ++cmpp)
2262                                         ADDW ((unsigned char) *cmpp);
2263                                     }
2264                                   else
2265                                     /* The last read character is not part
2266                                        of the number anymore.  */
2267                                       n = 12;
2268
2269                                   break;
2270                                 }
2271
2272                               /* We are pushing all read characters back.  */
2273                               if (cmpp > mbdigits[n])
2274                                 {
2275                                   ungetc (c, s);
2276                                   while (--cmpp > mbdigits[n])
2277                                     ungetc_not_eof ((unsigned char) *cmpp, s);
2278                                   c = (unsigned char) *cmpp;
2279                                 }
2280 #endif
2281                             }
2282
2283                           if (n >= 12)
2284                             {
2285                               /* The last read character is not part
2286                                  of the number anymore.  */
2287                               ungetc (c, s);
2288                               break;
2289                             }
2290                         }
2291
2292                       if (width == 0 || inchar () == EOF)
2293                         break;
2294
2295                       if (width > 0)
2296                         --width;
2297                     }
2298                 }
2299
2300 #ifndef COMPILE_WSCANF
2301             no_i18nflt:
2302               ;
2303 #endif
2304             }
2305
2306           /* Have we read any character?  If we try to read a number
2307              in hexadecimal notation and we have read only the `0x'
2308              prefix this is an error.  */
2309           if (__builtin_expect (wpsize == 0
2310                                 || ((flags & HEXA_FLOAT) && wpsize == 2), 0))
2311             conv_error ();
2312
2313         scan_float:
2314           /* Convert the number.  */
2315           ADDW (L_('\0'));
2316           if ((flags & LONGDBL) && !__ldbl_is_dbl)
2317             {
2318               long double d = __strtold_internal (wp, &tw, flags & GROUP);
2319               if (!(flags & SUPPRESS) && tw != wp)
2320                 *ARG (long double *) = negative ? -d : d;
2321             }
2322           else if (flags & (LONG | LONGDBL))
2323             {
2324               double d = __strtod_internal (wp, &tw, flags & GROUP);
2325               if (!(flags & SUPPRESS) && tw != wp)
2326                 *ARG (double *) = negative ? -d : d;
2327             }
2328           else
2329             {
2330               float d = __strtof_internal (wp, &tw, flags & GROUP);
2331               if (!(flags & SUPPRESS) && tw != wp)
2332                 *ARG (float *) = negative ? -d : d;
2333             }
2334
2335           if (__builtin_expect (tw == wp, 0))
2336             conv_error ();
2337
2338           if (!(flags & SUPPRESS))
2339             ++done;
2340           break;
2341
2342         case L_('['):   /* Character class.  */
2343           if (flags & LONG)
2344             STRING_ARG (wstr, wchar_t, 100);
2345           else
2346             STRING_ARG (str, char, 100);
2347
2348           if (*f == L_('^'))
2349             {
2350               ++f;
2351               not_in = 1;
2352             }
2353           else
2354             not_in = 0;
2355
2356           if (width < 0)
2357             /* There is no width given so there is also no limit on the
2358                number of characters we read.  Therefore we set width to
2359                a very high value to make the algorithm easier.  */
2360             width = INT_MAX;
2361
2362 #ifdef COMPILE_WSCANF
2363           /* Find the beginning and the end of the scanlist.  We are not
2364              creating a lookup table since it would have to be too large.
2365              Instead we search each time through the string.  This is not
2366              a constant lookup time but who uses this feature deserves to
2367              be punished.  */
2368           tw = (wchar_t *) f;   /* Marks the beginning.  */
2369
2370           if (*f == L']')
2371             ++f;
2372
2373           while ((fc = *f++) != L'\0' && fc != L']');
2374
2375           if (__builtin_expect (fc == L'\0', 0))
2376             conv_error ();
2377           wchar_t *twend = (wchar_t *) f - 1;
2378 #else
2379           /* Fill WP with byte flags indexed by character.
2380              We will use this flag map for matching input characters.  */
2381           if (wpmax < UCHAR_MAX + 1)
2382             {
2383               wpmax = UCHAR_MAX + 1;
2384               wp = (char *) alloca (wpmax);
2385             }
2386           memset (wp, '\0', UCHAR_MAX + 1);
2387
2388           fc = *f;
2389           if (fc == ']' || fc == '-')
2390             {
2391               /* If ] or - appears before any char in the set, it is not
2392                  the terminator or separator, but the first char in the
2393                  set.  */
2394               wp[fc] = 1;
2395               ++f;
2396             }
2397
2398           while ((fc = *f++) != '\0' && fc != ']')
2399             if (fc == '-' && *f != '\0' && *f != ']'
2400                 && (unsigned char) f[-2] <= (unsigned char) *f)
2401               {
2402                 /* Add all characters from the one before the '-'
2403                    up to (but not including) the next format char.  */
2404                 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
2405                   wp[fc] = 1;
2406               }
2407             else
2408               /* Add the character to the flag map.  */
2409               wp[fc] = 1;
2410
2411           if (__builtin_expect (fc == '\0', 0))
2412             conv_error();
2413 #endif
2414
2415           if (flags & LONG)
2416             {
2417               size_t now = read_in;
2418 #ifdef COMPILE_WSCANF
2419               if (__builtin_expect (inchar () == WEOF, 0))
2420                 input_error ();
2421
2422               do
2423                 {
2424                   wchar_t *runp;
2425
2426                   /* Test whether it's in the scanlist.  */
2427                   runp = tw;
2428                   while (runp < twend)
2429                     {
2430                       if (runp[0] == L'-' && runp[1] != '\0'
2431                           && runp + 1 != twend
2432                           && runp != tw
2433                           && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2434                         {
2435                           /* Match against all characters in between the
2436                              first and last character of the sequence.  */
2437                           wchar_t wc;
2438
2439                           for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2440                             if ((wint_t) wc == c)
2441                               break;
2442
2443                           if (wc <= runp[1] && !not_in)
2444                             break;
2445                           if (wc <= runp[1] && not_in)
2446                             {
2447                               /* The current character is not in the
2448                                  scanset.  */
2449                               ungetc (c, s);
2450                               goto out;
2451                             }
2452
2453                           runp += 2;
2454                         }
2455                       else
2456                         {
2457                           if ((wint_t) *runp == c && !not_in)
2458                             break;
2459                           if ((wint_t) *runp == c && not_in)
2460                             {
2461                               ungetc (c, s);
2462                               goto out;
2463                             }
2464
2465                           ++runp;
2466                         }
2467                     }
2468
2469                   if (runp == twend && !not_in)
2470                     {
2471                       ungetc (c, s);
2472                       goto out;
2473                     }
2474
2475                   if (!(flags & SUPPRESS))
2476                     {
2477                       *wstr++ = c;
2478
2479                       if ((flags & MALLOC)
2480                           && wstr == (wchar_t *) *strptr + strsize)
2481                         {
2482                           /* Enlarge the buffer.  */
2483                           wstr = (wchar_t *) realloc (*strptr,
2484                                                       (2 * strsize)
2485                                                       * sizeof (wchar_t));
2486                           if (wstr == NULL)
2487                             {
2488                               /* Can't allocate that much.  Last-ditch
2489                                  effort.  */
2490                               wstr = (wchar_t *)
2491                                 realloc (*strptr, (strsize + 1)
2492                                                   * sizeof (wchar_t));
2493                               if (wstr == NULL)
2494                                 {
2495                                   if (flags & POSIX_MALLOC)
2496                                     {
2497                                       done = EOF;
2498                                       goto errout;
2499                                     }
2500                                   /* We lose.  Oh well.  Terminate the string
2501                                      and stop converting, so at least we don't
2502                                      skip any input.  */
2503                                   ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2504                                   strptr = NULL;
2505                                   ++done;
2506                                   conv_error ();
2507                                 }
2508                               else
2509                                 {
2510                                   *strptr = (char *) wstr;
2511                                   wstr += strsize;
2512                                   ++strsize;
2513                                 }
2514                             }
2515                           else
2516                             {
2517                               *strptr = (char *) wstr;
2518                               wstr += strsize;
2519                               strsize *= 2;
2520                             }
2521                         }
2522                     }
2523                 }
2524               while (--width > 0 && inchar () != WEOF);
2525             out:
2526 #else
2527               char buf[MB_LEN_MAX];
2528               size_t cnt = 0;
2529               mbstate_t cstate;
2530
2531               if (__builtin_expect (inchar () == EOF, 0))
2532                 input_error ();
2533
2534               memset (&cstate, '\0', sizeof (cstate));
2535
2536               do
2537                 {
2538                   if (wp[c] == not_in)
2539                     {
2540                       ungetc_not_eof (c, s);
2541                       break;
2542                     }
2543
2544                   /* This is easy.  */
2545                   if (!(flags & SUPPRESS))
2546                     {
2547                       size_t n;
2548
2549                       /* Convert it into a wide character.  */
2550                       buf[0] = c;
2551                       n = __mbrtowc (wstr, buf, 1, &cstate);
2552
2553                       if (n == (size_t) -2)
2554                         {
2555                           /* Possibly correct character, just not enough
2556                              input.  */
2557                           ++cnt;
2558                           assert (cnt < MB_CUR_MAX);
2559                           continue;
2560                         }
2561                       cnt = 0;
2562
2563                       ++wstr;
2564                       if ((flags & MALLOC)
2565                           && wstr == (wchar_t *) *strptr + strsize)
2566                         {
2567                           /* Enlarge the buffer.  */
2568                           wstr = (wchar_t *) realloc (*strptr,
2569                                                       (2 * strsize
2570                                                        * sizeof (wchar_t)));
2571                           if (wstr == NULL)
2572                             {
2573                               /* Can't allocate that much.  Last-ditch
2574                                  effort.  */
2575                               wstr = (wchar_t *)
2576                                 realloc (*strptr, ((strsize + 1)
2577                                                    * sizeof (wchar_t)));
2578                               if (wstr == NULL)
2579                                 {
2580                                   if (flags & POSIX_MALLOC)
2581                                     {
2582                                       done = EOF;
2583                                       goto errout;
2584                                     }
2585                                   /* We lose.  Oh well.  Terminate the
2586                                      string and stop converting,
2587                                      so at least we don't skip any input.  */
2588                                   ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2589                                   strptr = NULL;
2590                                   ++done;
2591                                   conv_error ();
2592                                 }
2593                               else
2594                                 {
2595                                   *strptr = (char *) wstr;
2596                                   wstr += strsize;
2597                                   ++strsize;
2598                                 }
2599                             }
2600                           else
2601                             {
2602                               *strptr = (char *) wstr;
2603                               wstr += strsize;
2604                               strsize *= 2;
2605                             }
2606                         }
2607                     }
2608
2609                   if (--width <= 0)
2610                     break;
2611                 }
2612               while (inchar () != EOF);
2613
2614               if (__builtin_expect (cnt != 0, 0))
2615                 /* We stopped in the middle of recognizing another
2616                    character.  That's a problem.  */
2617                 encode_error ();
2618 #endif
2619
2620               if (__builtin_expect (now == read_in, 0))
2621                 /* We haven't succesfully read any character.  */
2622                 conv_error ();
2623
2624               if (!(flags & SUPPRESS))
2625                 {
2626                   *wstr++ = L'\0';
2627
2628                   if ((flags & MALLOC)
2629                       && wstr - (wchar_t *) *strptr != strsize)
2630                     {
2631                       wchar_t *cp = (wchar_t *)
2632                         realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2633                                            * sizeof(wchar_t)));
2634                       if (cp != NULL)
2635                         *strptr = (char *) cp;
2636                     }
2637                   strptr = NULL;
2638
2639                   ++done;
2640                 }
2641             }
2642           else
2643             {
2644               size_t now = read_in;
2645
2646               if (__builtin_expect (inchar () == EOF, 0))
2647                 input_error ();
2648
2649 #ifdef COMPILE_WSCANF
2650
2651               memset (&state, '\0', sizeof (state));
2652
2653               do
2654                 {
2655                   wchar_t *runp;
2656                   size_t n;
2657
2658                   /* Test whether it's in the scanlist.  */
2659                   runp = tw;
2660                   while (runp < twend)
2661                     {
2662                       if (runp[0] == L'-' && runp[1] != '\0'
2663                           && runp + 1 != twend
2664                           && runp != tw
2665                           && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2666                         {
2667                           /* Match against all characters in between the
2668                              first and last character of the sequence.  */
2669                           wchar_t wc;
2670
2671                           for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2672                             if ((wint_t) wc == c)
2673                               break;
2674
2675                           if (wc <= runp[1] && !not_in)
2676                             break;
2677                           if (wc <= runp[1] && not_in)
2678                             {
2679                               /* The current character is not in the
2680                                  scanset.  */
2681                               ungetc (c, s);
2682                               goto out2;
2683                             }
2684
2685                           runp += 2;
2686                         }
2687                       else
2688                         {
2689                           if ((wint_t) *runp == c && !not_in)
2690                             break;
2691                           if ((wint_t) *runp == c && not_in)
2692                             {
2693                               ungetc (c, s);
2694                               goto out2;
2695                             }
2696
2697                           ++runp;
2698                         }
2699                     }
2700
2701                   if (runp == twend && !not_in)
2702                     {
2703                       ungetc (c, s);
2704                       goto out2;
2705                     }
2706
2707                   if (!(flags & SUPPRESS))
2708                     {
2709                       if ((flags & MALLOC)
2710                           && str + MB_CUR_MAX >= *strptr + strsize)
2711                         {
2712                           /* Enlarge the buffer.  */
2713                           size_t strleng = str - *strptr;
2714                           char *newstr;
2715
2716                           newstr = (char *) realloc (*strptr, 2 * strsize);
2717                           if (newstr == NULL)
2718                             {
2719                               /* Can't allocate that much.  Last-ditch
2720                                  effort.  */
2721                               newstr = (char *) realloc (*strptr,
2722                                                          strleng + MB_CUR_MAX);
2723                               if (newstr == NULL)
2724                                 {
2725                                   if (flags & POSIX_MALLOC)
2726                                     {
2727                                       done = EOF;
2728                                       goto errout;
2729                                     }
2730                                   /* We lose.  Oh well.  Terminate the string
2731                                      and stop converting, so at least we don't
2732                                      skip any input.  */
2733                                   ((char *) (*strptr))[strleng] = '\0';
2734                                   strptr = NULL;
2735                                   ++done;
2736                                   conv_error ();
2737                                 }
2738                               else
2739                                 {
2740                                   *strptr = newstr;
2741                                   str = newstr + strleng;
2742                                   strsize = strleng + MB_CUR_MAX;
2743                                 }
2744                             }
2745                           else
2746                             {
2747                               *strptr = newstr;
2748                               str = newstr + strleng;
2749                               strsize *= 2;
2750                             }
2751                         }
2752                     }
2753
2754                   n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2755                   if (__builtin_expect (n == (size_t) -1, 0))
2756                     encode_error ();
2757
2758                   assert (n <= MB_CUR_MAX);
2759                   str += n;
2760                 }
2761               while (--width > 0 && inchar () != WEOF);
2762             out2:
2763 #else
2764               do
2765                 {
2766                   if (wp[c] == not_in)
2767                     {
2768                       ungetc_not_eof (c, s);
2769                       break;
2770                     }
2771
2772                   /* This is easy.  */
2773                   if (!(flags & SUPPRESS))
2774                     {
2775                       *str++ = c;
2776                       if ((flags & MALLOC)
2777                           && (char *) str == *strptr + strsize)
2778                         {
2779                           /* Enlarge the buffer.  */
2780                           size_t newsize = 2 * strsize;
2781
2782                         allocagain:
2783                           str = (char *) realloc (*strptr, newsize);
2784                           if (str == NULL)
2785                             {
2786                               /* Can't allocate that much.  Last-ditch
2787                                  effort.  */
2788                               if (newsize > strsize + 1)
2789                                 {
2790                                   newsize = strsize + 1;
2791                                   goto allocagain;
2792                                 }
2793                               if (flags & POSIX_MALLOC)
2794                                 {
2795                                   done = EOF;
2796                                   goto errout;
2797                                 }
2798                               /* We lose.  Oh well.  Terminate the
2799                                  string and stop converting,
2800                                  so at least we don't skip any input.  */
2801                               ((char *) (*strptr))[strsize - 1] = '\0';
2802                               strptr = NULL;
2803                               ++done;
2804                               conv_error ();
2805                             }
2806                           else
2807                             {
2808                               *strptr = (char *) str;
2809                               str += strsize;
2810                               strsize = newsize;
2811                             }
2812                         }
2813                     }
2814                 }
2815               while (--width > 0 && inchar () != EOF);
2816 #endif
2817
2818               if (__builtin_expect (now == read_in, 0))
2819                 /* We haven't succesfully read any character.  */
2820                 conv_error ();
2821
2822               if (!(flags & SUPPRESS))
2823                 {
2824 #ifdef COMPILE_WSCANF
2825                   /* We have to emit the code to get into the initial
2826                      state.  */
2827                   char buf[MB_LEN_MAX];
2828                   size_t n = __wcrtomb (buf, L'\0', &state);
2829                   if (n > 0 && (flags & MALLOC)
2830                       && str + n >= *strptr + strsize)
2831                     {
2832                       /* Enlarge the buffer.  */
2833                       size_t strleng = str - *strptr;
2834                       char *newstr;
2835
2836                       newstr = (char *) realloc (*strptr, strleng + n + 1);
2837                       if (newstr == NULL)
2838                         {
2839                           if (flags & POSIX_MALLOC)
2840                             {
2841                               done = EOF;
2842                               goto errout;
2843                             }
2844                           /* We lose.  Oh well.  Terminate the string
2845                              and stop converting, so at least we don't
2846                              skip any input.  */
2847                           ((char *) (*strptr))[strleng] = '\0';
2848                           strptr = NULL;
2849                           ++done;
2850                           conv_error ();
2851                         }
2852                       else
2853                         {
2854                           *strptr = newstr;
2855                           str = newstr + strleng;
2856                           strsize = strleng + n + 1;
2857                         }
2858                     }
2859
2860                   str = __mempcpy (str, buf, n);
2861 #endif
2862                   *str++ = '\0';
2863
2864                   if ((flags & MALLOC) && str - *strptr != strsize)
2865                     {
2866                       char *cp = (char *) realloc (*strptr, str - *strptr);
2867                       if (cp != NULL)
2868                         *strptr = cp;
2869                     }
2870                   strptr = NULL;
2871
2872                   ++done;
2873                 }
2874             }
2875           break;
2876
2877         case L_('p'):   /* Generic pointer.  */
2878           base = 16;
2879           /* A PTR must be the same size as a `long int'.  */
2880           flags &= ~(SHORT|LONGDBL);
2881           if (need_long)
2882             flags |= LONG;
2883           flags |= READ_POINTER;
2884           goto number;
2885
2886         default:
2887           /* If this is an unknown format character punt.  */
2888           conv_error ();
2889         }
2890     }
2891
2892   /* The last thing we saw int the format string was a white space.
2893      Consume the last white spaces.  */
2894   if (skip_space)
2895     {
2896       do
2897         c = inchar ();
2898       while (ISSPACE (c));
2899       ungetc (c, s);
2900     }
2901
2902  errout:
2903   /* Unlock stream.  */
2904   UNLOCK_STREAM (s);
2905
2906   if (use_malloc)
2907     free (wp);
2908
2909   if (errp != NULL)
2910     *errp |= errval;
2911
2912   if (__builtin_expect (done == EOF, 0))
2913     {
2914       if (__builtin_expect (ptrs_to_free != NULL, 0))
2915         {
2916           struct ptrs_to_free *p = ptrs_to_free;
2917           while (p != NULL)
2918             {
2919               for (size_t cnt = 0; cnt < p->count; ++cnt)
2920                 {
2921                   free (*p->ptrs[cnt]);
2922                   *p->ptrs[cnt] = NULL;
2923                 }
2924               p = p->next;
2925               ptrs_to_free = p;
2926             }
2927         }
2928     }
2929   else if (__builtin_expect (strptr != NULL, 0))
2930     {
2931       free (*strptr);
2932       *strptr = NULL;
2933     }
2934   return done;
2935 }
2936
2937 #ifdef COMPILE_WSCANF
2938 int
2939 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2940 {
2941   return _IO_vfwscanf (s, format, argptr, NULL);
2942 }
2943 ldbl_weak_alias (__vfwscanf, vfwscanf)
2944 #else
2945 int
2946 ___vfscanf (FILE *s, const char *format, va_list argptr)
2947 {
2948   return _IO_vfscanf_internal (s, format, argptr, NULL);
2949 }
2950 ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
2951 ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf)
2952 ldbl_strong_alias (___vfscanf, __vfscanf)
2953 ldbl_hidden_def (___vfscanf, __vfscanf)
2954 ldbl_weak_alias (___vfscanf, vfscanf)
2955 #endif