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