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