90d73bdbde41ff00216d89ac44be73896befd6cd
[kopensolaris-gnu/glibc.git] / stdio-common / vfscanf.c
1 /* Copyright (C) 1991-1999, 2000 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 Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    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    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 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            0x001   /* l: long or double */
56 #define LONGDBL         0x002   /* L: long long or long double */
57 #define SHORT           0x004   /* h: short */
58 #define SUPPRESS        0x008   /* *: suppress assignment */
59 #define POINTER         0x010   /* weird %p pointer (`fake hex') */
60 #define NOSKIP          0x020   /* do not skip blanks */
61 #define WIDTH           0x040   /* width was given */
62 #define GROUP           0x080   /* ': group numbers */
63 #define MALLOC          0x100   /* a: malloc strings */
64 #define CHAR            0x200   /* hh: char */
65 #define I18N            0x400   /* I: use locale's digits */
66
67
68 #ifdef USE_IN_LIBIO
69 # include <libioP.h>
70 # include <libio.h>
71
72 # undef va_list
73 # define va_list        _IO_va_list
74
75 # ifdef COMPILE_WSCANF
76 #  define ungetc(c, s)  ((void) (c == WEOF                                    \
77                                  || (--read_in,                               \
78                                      _IO_sputbackwc (s, c))))
79 #  define inchar()      (c == WEOF ? WEOF                                     \
80                          : ((c = _IO_getwc_unlocked (s)),                     \
81                             (void) (c != WEOF && ++read_in), c))
82
83 #  define MEMCPY(d, s, n) wmemcpy (d, s, n)
84 #  define ISSPACE(Ch)     iswspace (Ch)
85 #  define ISDIGIT(Ch)     iswdigit (Ch)
86 #  define ISXDIGIT(Ch)    iswxdigit (Ch)
87 #  define TOLOWER(Ch)     towlower (Ch)
88 #  define ORIENT          if (s->_vtable_offset == 0 && _IO_fwide (s, 1) != 1)\
89                             return WEOF
90 #  define __strtoll_internal    __wcstoll_internal
91 #  define __strtoull_internal   __wcstoull_internal
92 #  define __strtol_internal     __wcstol_internal
93 #  define __strtoul_internal    __wcstoul_internal
94 #  define __strtold_internal    __wcstold_internal
95 #  define __strtod_internal     __wcstod_internal
96 #  define __strtof_internal     __wcstof_internal
97
98 #  define L_(Str)         L##Str
99 #  define CHAR_T          wchar_t
100 #  define UCHAR_T         unsigned int
101 #  define WINT_T          wint_t
102 #  undef EOF
103 #  define EOF             WEOF
104 # else
105 #  define ungetc(c, s)  ((void) ((int) c == EOF                               \
106                                  || (--read_in,                               \
107                                      _IO_sputbackc (s, (unsigned char) c))))
108 #  define inchar()      (c == EOF ? EOF                                       \
109                          : ((c = _IO_getc_unlocked (s)),                      \
110                             (void) (c != EOF && ++read_in), c))
111 #  define MEMCPY(d, s, n) memcpy (d, s, n)
112 #  define ISSPACE(Ch)     isspace (Ch)
113 #  define ISDIGIT(Ch)     isdigit (Ch)
114 #  define ISXDIGIT(Ch)    isxdigit (Ch)
115 #  define TOLOWER(Ch)     tolower (Ch)
116 #  define ORIENT          if (_IO_fwide (s, -1) != -1) return EOF
117
118 #  define L_(Str)         Str
119 #  define CHAR_T          char
120 #  define UCHAR_T         unsigned char
121 #  define WINT_T          int
122 # endif
123
124 # define encode_error() do {                                                  \
125                           if (errp != NULL) *errp |= 4;                       \
126                           _IO_funlockfile (s);                                \
127                           __libc_cleanup_end (0);                             \
128                           __set_errno (EILSEQ);                               \
129                           return done;                                        \
130                         } while (0)
131 # define conv_error()   do {                                                  \
132                           if (errp != NULL) *errp |= 2;                       \
133                           _IO_funlockfile (s);                                \
134                           __libc_cleanup_end (0);                             \
135                           return done;                                        \
136                         } while (0)
137 # define input_error()  do {                                                  \
138                           _IO_funlockfile (s);                                \
139                           if (errp != NULL) *errp |= 1;                       \
140                           __libc_cleanup_end (0);                             \
141                           return done ?: EOF;                                 \
142                         } while (0)
143 # define memory_error() do {                                                  \
144                           _IO_funlockfile (s);                                \
145                           __set_errno (ENOMEM);                               \
146                           __libc_cleanup_end (0);                             \
147                           return EOF;                                         \
148                         } while (0)
149 # define ARGCHECK(s, format)                                                  \
150   do                                                                          \
151     {                                                                         \
152       /* Check file argument for consistence.  */                             \
153       CHECK_FILE (s, EOF);                                                    \
154       if (s->_flags & _IO_NO_READS)                                           \
155         {                                                                     \
156           __set_errno (EBADF);                                                \
157           return EOF;                                                         \
158         }                                                                     \
159       else if (format == NULL)                                                \
160         {                                                                     \
161           MAYBE_SET_EINVAL;                                                   \
162           return EOF;                                                         \
163         }                                                                     \
164     } while (0)
165 # define LOCK_STREAM(S)                                                       \
166   __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, (S));    \
167   _IO_flockfile (S)
168 # define UNLOCK_STREAM(S)                                                     \
169   _IO_funlockfile (S);                                                        \
170   __libc_cleanup_region_end (0)
171 #else
172 # define ungetc(c, s)   ((void) (c != EOF && --read_in), ungetc (c, s))
173 # define inchar()       (c == EOF ? EOF                                       \
174                          : ((c = getc (s)), (void) (c != EOF && ++read_in), c))
175 # define MEMCPY(d, s, n)  memcpy (d, s, n)
176 # define ISSPACE(Ch)      isspace (Ch)
177 # define ISDIGIT(Ch)      isdigit (Ch)
178 # define ISXDIGIT(Ch)     isxdigit (Ch)
179 # define TOLOWER(Ch)      tolower (Ch)
180
181 # define L_(Str)          Str
182 # define CHAR_T           char
183 # define UCHAR_T          unsigned char
184 # define WINT_T           int
185
186 # define encode_error() do {                                                  \
187                           funlockfile (s);                                    \
188                           __set_errno (EILSEQ);                               \
189                           return done;                                        \
190                         } while (0)
191 # define conv_error()   do {                                                  \
192                           funlockfile (s);                                    \
193                           return done;                                        \
194                         } while (0)
195 # define input_error()  do {                                                  \
196                           funlockfile (s);                                    \
197                           return done ?: EOF;                                 \
198                         } while (0)
199 # define memory_error() do {                                                  \
200                           funlockfile (s);                                    \
201                           __set_errno (ENOMEM);                               \
202                           return EOF;                                         \
203                         } while (0)
204 # define ARGCHECK(s, format)                                                  \
205   do                                                                          \
206     {                                                                         \
207       /* Check file argument for consistence.  */                             \
208       if (!__validfp (s) || !s->__mode.__read)                                \
209         {                                                                     \
210           __set_errno (EBADF);                                                \
211           return EOF;                                                         \
212         }                                                                     \
213       else if (format == NULL)                                                \
214         {                                                                     \
215           __set_errno (EINVAL);                                               \
216           return EOF;                                                         \
217         }                                                                     \
218     } while (0)
219 #if 1
220       /* XXX For now !!! */
221 # define flockfile(S) /* nothing */
222 # define funlockfile(S) /* nothing */
223 # define LOCK_STREAM(S)
224 # define UNLOCK_STREAM(S)
225 #else
226 # define LOCK_STREAM(S)                                                       \
227   __libc_cleanup_region_start (&__funlockfile, (S));                          \
228   __flockfile (S)
229 # define UNLOCK_STREAM(S)                                                     \
230   __funlockfile (S);                                                          \
231   __libc_cleanup_region_end (0)
232 #endif
233 #endif
234
235
236 /* Read formatted input from S according to the format string
237    FORMAT, using the argument list in ARG.
238    Return the number of assignments made, or -1 for an input error.  */
239 #ifdef USE_IN_LIBIO
240 # ifdef COMPILE_WSCANF
241 int
242 _IO_vfwscanf (s, format, argptr, errp)
243      _IO_FILE *s;
244      const wchar_t *format;
245      _IO_va_list argptr;
246      int *errp;
247 # else
248 int
249 _IO_vfscanf (s, format, argptr, errp)
250      _IO_FILE *s;
251      const char *format;
252      _IO_va_list argptr;
253      int *errp;
254 # endif
255 #else
256 int
257 __vfscanf (FILE *s, const char *format, va_list argptr)
258 #endif
259 {
260   va_list arg;
261   register const CHAR_T *f = format;
262   register UCHAR_T fc;  /* Current character of the format.  */
263   register size_t done = 0;     /* Assignments done.  */
264   register size_t read_in = 0;  /* Chars read in.  */
265   register WINT_T c = 0;        /* Last char read.  */
266   register int width;           /* Maximum field width.  */
267   register int flags;           /* Modifiers for current format element.  */
268
269   /* Status for reading F-P nums.  */
270   char got_dot, got_e, negative;
271   /* If a [...] is a [^...].  */
272   CHAR_T not_in;
273 #define exp_char not_in
274   /* Base for integral numbers.  */
275   int base;
276   /* Signedness for integral numbers.  */
277   int number_signed;
278 #define is_hexa number_signed
279   /* Decimal point character.  */
280 #ifdef COMPILE_WSCANF
281   wchar_t decimal;
282 #else
283   const char *decimal;
284 #endif
285   /* The thousands character of the current locale.  */
286 #ifdef COMPILE_WSCANF
287   wchar_t thousands;
288 #else
289   const char *thousands;
290 #endif
291   /* State for the conversions.  */
292   mbstate_t state;
293   /* Integral holding variables.  */
294   union
295     {
296       long long int q;
297       unsigned long long int uq;
298       long int l;
299       unsigned long int ul;
300     } num;
301   /* Character-buffer pointer.  */
302   char *str = NULL;
303   wchar_t *wstr = NULL;
304   char **strptr = NULL;
305   size_t strsize = 0;
306   /* We must not react on white spaces immediately because they can
307      possibly be matched even if in the input stream no character is
308      available anymore.  */
309   int skip_space = 0;
310   /* Nonzero if we are reading a pointer.  */
311   int read_pointer;
312   /* Workspace.  */
313   CHAR_T *tw;                   /* Temporary pointer.  */
314   CHAR_T *wp = NULL;            /* Workspace.  */
315   size_t wpmax = 0;             /* Maximal size of workspace.  */
316   size_t wpsize;                /* Currently used bytes in workspace.  */
317 #define ADDW(Ch)                                                            \
318   do                                                                        \
319     {                                                                       \
320       if (wpsize == wpmax)                                                  \
321         {                                                                   \
322           CHAR_T *old = wp;                                                 \
323           wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax;            \
324           wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t));                \
325           if (old != NULL)                                                  \
326             MEMCPY (wp, old, wpsize);                                       \
327         }                                                                   \
328       wp[wpsize++] = (Ch);                                                  \
329     }                                                                       \
330   while (0)
331
332 #ifdef __va_copy
333   __va_copy (arg, argptr);
334 #else
335   arg = (va_list) argptr;
336 #endif
337
338 #ifdef ORIENT
339   ORIENT;
340 #endif
341
342   ARGCHECK (s, format);
343
344   /* Figure out the decimal point character.  */
345 #ifdef COMPILE_WSCANF
346   decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
347 #else
348   decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
349 #endif
350   /* Figure out the thousands separator character.  */
351 #ifdef COMPILE_WSCANF
352   thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
353 #else
354   thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
355   if (*thousands == '\0')
356     thousands = NULL;
357 #endif
358
359   /* Lock the stream.  */
360   LOCK_STREAM (s);
361
362
363 #ifndef COMPILE_WSCANF
364   /* From now on we use `state' to convert the format string.  */
365   memset (&state, '\0', sizeof (state));
366 #endif
367
368   /* Run through the format string.  */
369   while (*f != '\0')
370     {
371       unsigned int argpos;
372       /* Extract the next argument, which is of type TYPE.
373          For a %N$... spec, this is the Nth argument from the beginning;
374          otherwise it is the next argument after the state now in ARG.  */
375 #ifdef __va_copy
376 # define ARG(type)      (argpos == 0 ? va_arg (arg, type) :                   \
377                          ({ unsigned int pos = argpos;                        \
378                             va_list arg;                                      \
379                             __va_copy (arg, argptr);                          \
380                             while (--pos > 0)                                 \
381                               (void) va_arg (arg, void *);                    \
382                             va_arg (arg, type);                               \
383                           }))
384 #else
385 # if 0
386       /* XXX Possible optimization.  */
387 #  define ARG(type)     (argpos == 0 ? va_arg (arg, type) :                   \
388                          ({ va_list arg = (va_list) argptr;                   \
389                             arg = (va_list) ((char *) arg                     \
390                                              + (argpos - 1)                   \
391                                              * __va_rounded_size (void *));   \
392                             va_arg (arg, type);                               \
393                          }))
394 # else
395 #  define ARG(type)     (argpos == 0 ? va_arg (arg, type) :                   \
396                          ({ unsigned int pos = argpos;                        \
397                             va_list arg = (va_list) argptr;                   \
398                             while (--pos > 0)                                 \
399                               (void) va_arg (arg, void *);                    \
400                             va_arg (arg, type);                               \
401                           }))
402 # endif
403 #endif
404
405 #ifndef COMPILE_WSCANF
406       if (!isascii (*f))
407         {
408           /* Non-ASCII, may be a multibyte.  */
409           int len = __mbrlen (f, strlen (f), &state);
410           if (len > 0)
411             {
412               do
413                 {
414                   c = inchar ();
415                   if (c == EOF)
416                     input_error ();
417                   else if (c != *f++)
418                     {
419                       ungetc (c, s);
420                       conv_error ();
421                     }
422                 }
423               while (--len > 0);
424               continue;
425             }
426         }
427 #endif
428
429       fc = *f++;
430       if (fc != '%')
431         {
432           /* Remember to skip spaces.  */
433           if (ISSPACE (fc))
434             {
435               skip_space = 1;
436               continue;
437             }
438
439           /* Read a character.  */
440           c = inchar ();
441
442           /* Characters other than format specs must just match.  */
443           if (c == EOF)
444             input_error ();
445
446           /* We saw white space char as the last character in the format
447              string.  Now it's time to skip all leading white space.  */
448           if (skip_space)
449             {
450               while (ISSPACE (c))
451                 if (inchar () == EOF && errno == EINTR)
452                   conv_error ();
453               skip_space = 0;
454             }
455
456           if (c != fc)
457             {
458               ungetc (c, s);
459               conv_error ();
460             }
461
462           continue;
463         }
464
465       /* This is the start of the conversion string. */
466       flags = 0;
467
468       /* Not yet decided whether we read a pointer or not.  */
469       read_pointer = 0;
470
471       /* Initialize state of modifiers.  */
472       argpos = 0;
473
474       /* Prepare temporary buffer.  */
475       wpsize = 0;
476
477       /* Check for a positional parameter specification.  */
478       if (ISDIGIT (*f))
479         {
480           argpos = *f++ - L_('0');
481           while (ISDIGIT (*f))
482             argpos = argpos * 10 + (*f++ - L_('0'));
483           if (*f == L_('$'))
484             ++f;
485           else
486             {
487               /* Oops; that was actually the field width.  */
488               width = argpos;
489               flags |= WIDTH;
490               argpos = 0;
491               goto got_width;
492             }
493         }
494
495       /* Check for the assignment-suppressing, the number grouping flag,
496          and the signal to use the locale's digit representation.  */
497       while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
498         switch (*f++)
499           {
500           case L_('*'):
501             flags |= SUPPRESS;
502             break;
503           case L_('\''):
504             flags |= GROUP;
505             break;
506           case L_('I'):
507             flags |= I18N;
508             break;
509           }
510
511       /* We have seen width. */
512       if (ISDIGIT (*f))
513         flags |= WIDTH;
514
515       /* Find the maximum field width.  */
516       width = 0;
517       while (ISDIGIT (*f))
518         {
519           width *= 10;
520           width += *f++ - L_('0');
521         }
522     got_width:
523       if (width == 0)
524         width = -1;
525
526       /* Check for type modifiers.  */
527       switch (*f++)
528         {
529         case L_('h'):
530           /* ints are short ints or chars.  */
531           if (*f == L_('h'))
532             {
533               ++f;
534               flags |= CHAR;
535             }
536           else
537             flags |= SHORT;
538           break;
539         case L_('l'):
540           if (*f == L_('l'))
541             {
542               /* A double `l' is equivalent to an `L'.  */
543               ++f;
544               flags |= LONGDBL | LONG;
545             }
546           else
547             /* ints are long ints.  */
548             flags |= LONG;
549           break;
550         case L_('q'):
551         case L_('L'):
552           /* doubles are long doubles, and ints are long long ints.  */
553           flags |= LONGDBL | LONG;
554           break;
555         case L_('a'):
556           /* The `a' is used as a flag only if followed by `s', `S' or
557              `['.  */
558           if (*f != L_('s') && *f != L_('S') && *f != L_('['))
559             {
560               --f;
561               break;
562             }
563           /* String conversions (%s, %[) take a `char **'
564              arg and fill it in with a malloc'd pointer.  */
565           flags |= MALLOC;
566           break;
567         case L_('z'):
568           if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
569             flags |= LONGDBL;
570           else if (sizeof (size_t) > sizeof (unsigned int))
571             flags |= LONG;
572           break;
573         case L_('j'):
574           if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
575             flags |= LONGDBL;
576           else if (sizeof (uintmax_t) > sizeof (unsigned int))
577             flags |= LONG;
578           break;
579         case L_('t'):
580           if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
581             flags |= LONGDBL;
582           else if (sizeof (ptrdiff_t) > sizeof (int))
583             flags |= LONG;
584           break;
585         default:
586           /* Not a recognized modifier.  Backup.  */
587           --f;
588           break;
589         }
590
591       /* End of the format string?  */
592       if (*f == L_('\0'))
593         conv_error ();
594
595       /* Find the conversion specifier.  */
596       fc = *f++;
597       if (skip_space || (fc != L_('[') && fc != L_('c')
598                          && fc != L_('C') && fc != L_('n')))
599         {
600           /* Eat whitespace.  */
601           int save_errno = errno;
602           errno = 0;
603           do
604             if (inchar () == EOF && errno == EINTR)
605               input_error ();
606           while (ISSPACE (c));
607           errno = save_errno;
608           ungetc (c, s);
609           skip_space = 0;
610         }
611
612       switch (fc)
613         {
614         case L_('%'):   /* Must match a literal '%'.  */
615           c = inchar ();
616           if (c == EOF)
617             input_error ();
618           if (c != fc)
619             {
620               ungetc (c, s);
621               conv_error ();
622             }
623           break;
624
625         case L_('n'):   /* Answer number of assignments done.  */
626           /* Corrigendum 1 to ISO C 1990 describes the allowed flags
627              with the 'n' conversion specifier.  */
628           if (!(flags & SUPPRESS))
629             {
630               /* Don't count the read-ahead.  */
631               if (need_longlong && (flags & LONGDBL))
632                 *ARG (long long int *) = read_in;
633               else if (need_long && (flags & LONG))
634                 *ARG (long int *) = read_in;
635               else if (flags & SHORT)
636                 *ARG (short int *) = read_in;
637               else if (!(flags & CHAR))
638                 *ARG (int *) = read_in;
639               else
640                 *ARG (char *) = read_in;
641
642 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
643               /* We have a severe problem here.  The ISO C standard
644                  contradicts itself in explaining the effect of the %n
645                  format in `scanf'.  While in ISO C:1990 and the ISO C
646                  Amendement 1:1995 the result is described as
647
648                    Execution of a %n directive does not effect the
649                    assignment count returned at the completion of
650                    execution of the f(w)scanf function.
651
652                  in ISO C Corrigendum 1:1994 the following was added:
653
654                    Subclause 7.9.6.2
655                    Add the following fourth example:
656                      In:
657                        #include <stdio.h>
658                        int d1, d2, n1, n2, i;
659                        i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
660                      the value 123 is assigned to d1 and the value3 to n1.
661                      Because %n can never get an input failure the value
662                      of 3 is also assigned to n2.  The value of d2 is not
663                      affected.  The value 3 is assigned to i.
664
665                  We go for now with the historically correct code from ISO C,
666                  i.e., we don't count the %n assignments.  When it ever
667                  should proof to be wrong just remove the #ifdef above.  */
668               ++done;
669 #endif
670             }
671           break;
672
673         case L_('c'):   /* Match characters.  */
674           if ((flags & LONG) == 0)
675             {
676               if (!(flags & SUPPRESS))
677                 {
678                   str = ARG (char *);
679                   if (str == NULL)
680                     conv_error ();
681                 }
682
683               c = inchar ();
684               if (c == EOF)
685                 input_error ();
686
687               if (width == -1)
688                 width = 1;
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                   n = wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
700                   if (n == (size_t) -1)
701                     /* No valid wide character.  */
702                     input_error ();
703
704                   /* Increment the output pointer.  Even if we don't
705                      write anything.  */
706                   str += n;
707                 }
708               while (--width > 0 && inchar () != EOF);
709 #else
710               if (!(flags & SUPPRESS))
711                 {
712                   do
713                     *str++ = c;
714                   while (--width > 0 && inchar () != EOF);
715                 }
716               else
717                 while (--width > 0 && inchar () != EOF);
718 #endif
719
720               if (!(flags & SUPPRESS))
721                 ++done;
722
723               break;
724             }
725           /* FALLTHROUGH */
726         case L_('C'):
727           if (!(flags & SUPPRESS))
728             {
729               wstr = ARG (wchar_t *);
730               if (wstr == NULL)
731                 conv_error ();
732             }
733
734           c = inchar ();
735           if (c == EOF)
736             input_error ();
737
738 #ifdef COMPILE_WSCANF
739           /* Just store the incoming wide characters.  */
740           if (!(flags & SUPPRESS))
741             {
742               do
743                 *wstr++ = c;
744               while (--width > 0 && inchar () != EOF);
745             }
746           else
747             while (--width > 0 && inchar () != EOF);
748 #else
749           {
750             /* We have to convert the multibyte input sequence to wide
751                characters.  */
752             char buf[MB_LEN_MAX];
753             mbstate_t cstate;
754
755             memset (&cstate, '\0', sizeof (cstate));
756
757             do
758               {
759                 size_t cnt;
760
761                 /* This is what we present the mbrtowc function first.  */
762                 buf[0] = c;
763                 cnt = 1;
764
765                 while (1)
766                   {
767                     size_t n;
768
769                     n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
770                                    buf, cnt, &cstate);
771
772                     if (n == (size_t) -2)
773                       {
774                         /* Possibly correct character, just not enough
775                            input.  */
776                         assert (cnt < MB_CUR_MAX);
777
778                         if (inchar () == EOF)
779                           encode_error ();
780
781                         buf[cnt++] = c;
782                         continue;
783                       }
784
785                     if (n != cnt)
786                       encode_error ();
787
788                     /* We have a match.  */
789                     break;
790                   }
791
792                 /* Advance the result pointer.  */
793                 ++wstr;
794               }
795             while (--width > 0 && inchar () != EOF);
796           }
797 #endif
798
799           if (!(flags & SUPPRESS))
800             ++done;
801
802           break;
803
804         case L_('s'):           /* Read a string.  */
805           if (!(flags & LONG))
806             {
807 #define STRING_ARG(Str, Type)                                                 \
808               do if (!(flags & SUPPRESS))                                     \
809                 {                                                             \
810                   if (flags & MALLOC)                                         \
811                     {                                                         \
812                       /* The string is to be stored in a malloc'd buffer.  */ \
813                       strptr = ARG (char **);                                 \
814                       if (strptr == NULL)                                     \
815                         conv_error ();                                        \
816                       /* Allocate an initial buffer.  */                      \
817                       strsize = 100;                                          \
818                       *strptr = (char *) malloc (strsize * sizeof (Type));    \
819                       Str = (Type *) *strptr;                                 \
820                     }                                                         \
821                   else                                                        \
822                     Str = ARG (Type *);                                       \
823                   if (Str == NULL)                                            \
824                     conv_error ();                                            \
825                 } while (0)
826               STRING_ARG (str, char);
827
828               c = inchar ();
829               if (c == EOF)
830                 input_error ();
831
832 #ifdef COMPILE_WSCANF
833               memset (&state, '\0', sizeof (state));
834 #endif
835
836               do
837                 {
838                   if (ISSPACE (c))
839                     {
840                       ungetc (c, s);
841                       break;
842                     }
843
844 #ifdef COMPILE_WSCANF
845                   /* This is quite complicated.  We have to convert the
846                      wide characters into multibyte characters and then
847                      store them.  */
848                   {
849                     size_t n;
850
851                     if (!(flags & SUPPRESS) && (flags & MALLOC)
852                         && str + MB_CUR_MAX >= *strptr + strsize)
853                       {
854                         /* We have to enlarge the buffer if the `a' flag
855                            was given.  */
856                         str = (char *) realloc (*strptr, strsize * 2);
857                         if (str == NULL)
858                           {
859                             /* Can't allocate that much.  Last-ditch
860                                effort.  */
861                             str = (char *) realloc (*strptr, strsize + 1);
862                             if (str == NULL)
863                               {
864                                 /* We lose.  Oh well.  Terminate the
865                                    string and stop converting,
866                                    so at least we don't skip any input.  */
867                                 ((char *) (*strptr))[strsize - 1] = '\0';
868                                 ++done;
869                                 conv_error ();
870                               }
871                             else
872                               {
873                                 *strptr = (char *) str;
874                                 str += strsize;
875                                 ++strsize;
876                               }
877                           }
878                         else
879                           {
880                             *strptr = (char *) str;
881                             str += strsize;
882                             strsize *= 2;
883                           }
884                       }
885
886                     n = wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
887                     if (n == (size_t) -1)
888                       encode_error ();
889
890                     assert (n <= MB_CUR_MAX);
891                     str += n;
892                   }
893 #else
894                   /* This is easy.  */
895                   if (!(flags & SUPPRESS))
896                     {
897                       *str++ = c;
898                       if ((flags & MALLOC)
899                           && (char *) str == *strptr + strsize)
900                         {
901                           /* Enlarge the buffer.  */
902                           str = (char *) realloc (*strptr, 2 * strsize);
903                           if (str == NULL)
904                             {
905                               /* Can't allocate that much.  Last-ditch
906                                  effort.  */
907                               str = (char *) realloc (*strptr, strsize + 1);
908                               if (str == NULL)
909                                 {
910                                   /* We lose.  Oh well.  Terminate the
911                                      string and stop converting,
912                                      so at least we don't skip any input.  */
913                                   ((char *) (*strptr))[strsize - 1] = '\0';
914                                   ++done;
915                                   conv_error ();
916                                 }
917                               else
918                                 {
919                                   *strptr = (char *) str;
920                                   str += strsize;
921                                   ++strsize;
922                                 }
923                             }
924                           else
925                             {
926                               *strptr = (char *) str;
927                               str += strsize;
928                               strsize *= 2;
929                             }
930                         }
931                     }
932 #endif
933                 }
934               while ((width <= 0 || --width > 0) && inchar () != EOF);
935
936               if (!(flags & SUPPRESS))
937                 {
938 #ifdef COMPILE_WSCANF
939                   /* We have to emit the code to get into the intial
940                      state.  */
941                   char buf[MB_LEN_MAX];
942                   size_t n = wcrtomb (buf, L'\0', &state);
943                   if (n > 0 && (flags & MALLOC)
944                       && str + n >= *strptr + strsize)
945                     {
946                       /* Enlarge the buffer.  */
947                       str = (char *) realloc (*strptr,
948                                               (str + n + 1) - *strptr);
949                       if (str == NULL)
950                         {
951                           /* We lose.  Oh well.  Terminate the string
952                              and stop converting, so at least we don't
953                              skip any input.  */
954                           ((char *) (*strptr))[strsize - 1] = '\0';
955                           ++done;
956                           conv_error ();
957                         }
958                       else
959                         {
960                           *strptr = (char *) str;
961                           str = ((char *) *strptr) + strsize;
962                           strsize = (str + n + 1) - *strptr;
963                         }
964                     }
965
966                   str = __mempcpy (str, buf, n);
967 #endif
968                   *str = '\0';
969
970                   if ((flags & MALLOC) && str - *strptr != strsize)
971                     {
972                       char *cp = (char *) realloc (*strptr, str - *strptr);
973                       if (cp != NULL)
974                         *strptr = cp;
975                     }
976
977                   ++done;
978                 }
979               break;
980             }
981           /* FALLTHROUGH */
982
983         case L_('S'):
984           {
985 #ifndef COMPILE_WSCANF
986             mbstate_t cstate;
987 #endif
988
989             /* Wide character string.  */
990             STRING_ARG (wstr, wchar_t);
991
992             c = inchar ();
993             if (c == EOF)
994               input_error ();
995
996 #ifndef COMPILE_WSCANF
997             memset (&cstate, '\0', sizeof (cstate));
998 #endif
999
1000             do
1001               {
1002                 if (ISSPACE (c))
1003                   {
1004                     ungetc (c, s);
1005                     break;
1006                   }
1007
1008 #ifdef COMPILE_WSCANF
1009                 /* This is easy.  */
1010                 if (!(flags & SUPPRESS))
1011                   {
1012                     *wstr++ = c;
1013                     if ((flags & MALLOC)
1014                         && wstr == (wchar_t *) *strptr + strsize)
1015                       {
1016                         /* Enlarge the buffer.  */
1017                         wstr = (wchar_t *) realloc (*strptr,
1018                                                     (2 * strsize)
1019                                                     * sizeof (wchar_t));
1020                         if (wstr == NULL)
1021                           {
1022                             /* Can't allocate that much.  Last-ditch
1023                                effort.  */
1024                             wstr = (wchar_t *) realloc (*strptr,
1025                                                         (strsize
1026                                                          + sizeof (wchar_t)));
1027                             if (wstr == NULL)
1028                               {
1029                                 /* We lose.  Oh well.  Terminate the string
1030                                    and stop converting, so at least we don't
1031                                    skip any input.  */
1032                                 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1033                                 ++done;
1034                                 conv_error ();
1035                               }
1036                             else
1037                               {
1038                                 *strptr = (char *) wstr;
1039                                 wstr += strsize;
1040                                 ++strsize;
1041                               }
1042                           }
1043                         else
1044                           {
1045                             *strptr = (char *) wstr;
1046                             wstr += strsize;
1047                             strsize *= 2;
1048                           }
1049                       }
1050                   }
1051 #else
1052                 {
1053                   char buf[MB_LEN_MAX];
1054                   size_t cnt;
1055
1056                   buf[0] = c;
1057                   cnt = 1;
1058
1059                   while (1)
1060                     {
1061                       size_t n;
1062
1063                       n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1064                                      buf, cnt, &cstate);
1065
1066                       if (n == (size_t) -2)
1067                         {
1068                           /* Possibly correct character, just not enough
1069                              input.  */
1070                           assert (cnt < MB_CUR_MAX);
1071
1072                           if (inchar () == EOF)
1073                             encode_error ();
1074
1075                           buf[cnt++] = c;
1076                           continue;
1077                         }
1078
1079                       if (n != cnt)
1080                         encode_error ();
1081
1082                       /* We have a match.  */
1083                       break;
1084                     }
1085
1086                   if (!(flags & SUPPRESS) && (flags & MALLOC)
1087                       && wstr == (wchar_t *) *strptr + strsize)
1088                     {
1089                       /* Enlarge the buffer.  */
1090                       wstr = (wchar_t *) realloc (*strptr,
1091                                                   (2 * strsize
1092                                                    * sizeof (wchar_t)));
1093                       if (wstr == NULL)
1094                         {
1095                           /* Can't allocate that much.  Last-ditch effort.  */
1096                           wstr = (wchar_t *) realloc (*strptr,
1097                                                       ((strsize + 1)
1098                                                        * sizeof (wchar_t)));
1099                           if (wstr == NULL)
1100                             {
1101                               /* We lose.  Oh well.  Terminate the
1102                                  string and stop converting, so at
1103                                  least we don't skip any input.  */
1104                               ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1105                               ++done;
1106                               conv_error ();
1107                             }
1108                           else
1109                             {
1110                               *strptr = (char *) wstr;
1111                               wstr += strsize;
1112                               ++strsize;
1113                             }
1114                         }
1115                       else
1116                         {
1117                           *strptr = (char *) wstr;
1118                           wstr += strsize;
1119                           strsize *= 2;
1120                         }
1121                     }
1122                 }
1123 #endif
1124               }
1125             while ((width <= 0 || --width > 0) && inchar () != EOF);
1126
1127             if (!(flags & SUPPRESS))
1128               {
1129                 *wstr++ = L'\0';
1130
1131                 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1132                   {
1133                     wchar_t *cp = (wchar_t *) realloc (*strptr,
1134                                                        ((wstr
1135                                                          - (wchar_t *) *strptr)
1136                                                         * sizeof(wchar_t)));
1137                     if (cp != NULL)
1138                       *strptr = (char *) cp;
1139                   }
1140
1141                 ++done;
1142               }
1143           }
1144           break;
1145
1146         case L_('x'):   /* Hexadecimal integer.  */
1147         case L_('X'):   /* Ditto.  */
1148           base = 16;
1149           number_signed = 0;
1150           goto number;
1151
1152         case L_('o'):   /* Octal integer.  */
1153           base = 8;
1154           number_signed = 0;
1155           goto number;
1156
1157         case L_('u'):   /* Unsigned decimal integer.  */
1158           base = 10;
1159           number_signed = 0;
1160           goto number;
1161
1162         case L_('d'):   /* Signed decimal integer.  */
1163           base = 10;
1164           number_signed = 1;
1165           goto number;
1166
1167         case L_('i'):   /* Generic number.  */
1168           base = 0;
1169           number_signed = 1;
1170
1171         number:
1172           c = inchar ();
1173           if (c == EOF)
1174             input_error ();
1175
1176           /* Check for a sign.  */
1177           if (c == L_('-') || c == L_('+'))
1178             {
1179               ADDW (c);
1180               if (width > 0)
1181                 --width;
1182               c = inchar ();
1183             }
1184
1185           /* Look for a leading indication of base.  */
1186           if (width != 0 && c == L_('0'))
1187             {
1188               if (width > 0)
1189                 --width;
1190
1191               ADDW (c);
1192               c = inchar ();
1193
1194               if (width != 0 && TOLOWER (c) == L_('x'))
1195                 {
1196                   if (base == 0)
1197                     base = 16;
1198                   if (base == 16)
1199                     {
1200                       if (width > 0)
1201                         --width;
1202                       c = inchar ();
1203                     }
1204                 }
1205               else if (base == 0)
1206                 base = 8;
1207             }
1208
1209           if (base == 0)
1210             base = 10;
1211
1212           if (base == 10 && (flags & I18N) != 0)
1213             {
1214               int from_level;
1215               int to_level;
1216 #ifdef COMPILE_WSCANF
1217               const wchar_t *wcdigits[10];
1218 #else
1219               const char *mbdigits[10];
1220 #endif
1221               int n;
1222
1223               from_level = 0;
1224 #ifdef COMPILE_WSCANF
1225               to_level = _NL_CURRENT_WORD (LC_CTYPE,
1226                                            _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1227 #else
1228               to_level = _NL_CURRENT_WORD (LC_CTYPE,
1229                                            _NL_CTYPE_INDIGITS_MB_LEN) - 1;
1230 #endif
1231
1232               /* In this round we get the pointer to the digit strings
1233                  and also perform the first round of comparisons.  */
1234               for (n = 0; n < 10; ++n)
1235                 {
1236                   /* Get the string for the digits with value N.  */
1237 #ifdef COMPILE_WSCANF
1238                   wcdigits[n] = (const wchar_t *)
1239                     _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1240                   if (c == *wcdigits[n])
1241                     break;
1242
1243                   /* Advance the pointer to the next string.  */
1244                   ++wcdigits[n];
1245 #else
1246                   size_t dlen;
1247                   size_t dcnt;
1248
1249                   mbdigits[n] = _NL_CURRENT (LC_CTYPE,
1250                                              _NL_CTYPE_INDIGITS0_MB + n);
1251                   dlen = strlen (mbdigits[n]);
1252
1253                   dcnt = 0;
1254                   do
1255                     {
1256                       if (c != mbdigits[n][dcnt])
1257                         break;
1258                       c = inchar ();
1259                     }
1260                   while (--dcnt > 0);
1261
1262                   if (dcnt == 0)
1263                     /* We found it.  */
1264                     break;
1265
1266                   /* Advance the pointer to the next string.  */
1267                   mbdigits[n] += dlen + 1;
1268 #endif
1269                 }
1270
1271               if (n == 10)
1272                 {
1273                   /*Have not yet found the digit.  */
1274                   while (++from_level <= to_level)
1275                     {
1276                       /* Search all ten digits of this level.  */
1277                       for (n = 0; n < 10; ++n)
1278                         {
1279 #ifdef COMPILE_WSCANF
1280                           if (c == *wcdigits[n])
1281                             break;
1282
1283                           /* Advance the pointer to the next string.  */
1284                           ++wcdigits[n];
1285 #else
1286                           size_t dlen = strlen (mbdigits[n]);
1287                           size_t dcnt;
1288
1289                           dcnt = 0;
1290                           do
1291                             {
1292                               if (c != mbdigits[n][dcnt])
1293                                 break;
1294                               c = inchar ();
1295                             }
1296                           while (--dcnt > 0);
1297
1298                           if (dcnt == 0)
1299                             /* We found it.  */
1300                             break;
1301
1302                           /* Advance the pointer to the next string.  */
1303                           mbdigits[n] += dlen + 1;
1304 #endif
1305                         }
1306
1307                       if (n < 10)
1308                         /* Found it.  */
1309                         break;
1310
1311                       /* Next level.  */
1312                       ++from_level;
1313                     }
1314                 }
1315
1316               if (n == 10)
1317                 {
1318                   /* Haven't found anything.  Push the last character back
1319                      and return an error.  */
1320                   ungetc (c, s);
1321                   input_error ();
1322                 }
1323
1324               ADDW (L_('0') + n);
1325             }
1326           else
1327             /* Read the number into workspace.  */
1328             while (c != EOF && width != 0)
1329               {
1330                 if (base == 16)
1331                   {
1332                     if (!ISXDIGIT (c))
1333                       break;
1334                   }
1335                 else if (!ISDIGIT (c) || c - L_('0') >= base)
1336                   {
1337                     if (base == 10 && (flags & GROUP)
1338 #ifdef COMPILE_WSCANF
1339                         && thousands != L'\0'
1340 #else
1341                         && thousands != NULL
1342 #endif
1343                         )
1344                       {
1345                         /* Try matching against the thousands separator.  */
1346 #ifdef COMPILE_WSCANF
1347                         if (c != thousands)
1348                           break;
1349 #else
1350                         const char *cmpp = thousands;
1351                         int avail = width > 0 ? width : INT_MAX;
1352
1353                         while (*cmpp == c && avail > 0)
1354                           if (*++cmpp == '\0')
1355                             break;
1356                           else
1357                             {
1358                               if (inchar () == EOF)
1359                                 break;
1360                               --avail;
1361                             }
1362
1363                         if (*cmpp != '\0')
1364                           {
1365                             /* We are pushing all read character back.  */
1366                             if (cmpp > thousands)
1367                               {
1368                                 ungetc (c, s);
1369                                 while (--cmpp > thousands)
1370                                   ungetc (*cmpp, s);
1371                                 c = *cmpp;
1372                               }
1373                             break;
1374                           }
1375                         if (width > 0)
1376                           /* +1 because we substract below.  */
1377                           width = avail + 1;
1378 #endif
1379                       }
1380                     else
1381                       break;
1382                   }
1383                 ADDW (c);
1384                 if (width > 0)
1385                   --width;
1386
1387                 c = inchar ();
1388               }
1389
1390           if (wpsize == 0
1391               || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1392             {
1393               /* There was no number.  If we are supposed to read a pointer
1394                  we must recognize "(nil)" as well.  */
1395               if (wpsize == 0 && read_pointer && (width < 0 || width >= 0)
1396                   && c == '('
1397                   && TOLOWER (inchar ()) == L_('n')
1398                   && TOLOWER (inchar ()) == L_('i')
1399                   && TOLOWER (inchar ()) == L_('l')
1400                   && inchar () == L_(')'))
1401                 /* We must produce the value of a NULL pointer.  A single
1402                    '0' digit is enough.  */
1403                 ADDW (L_('0'));
1404               else
1405                 {
1406                   /* The last read character is not part of the number
1407                      anymore.  */
1408                   ungetc (c, s);
1409
1410                   conv_error ();
1411                 }
1412             }
1413           else
1414             /* The just read character is not part of the number anymore.  */
1415             ungetc (c, s);
1416
1417           /* Convert the number.  */
1418           ADDW (L_('\0'));
1419           if (need_longlong && (flags & LONGDBL))
1420             {
1421               if (number_signed)
1422                 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1423               else
1424                 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1425             }
1426           else
1427             {
1428               if (number_signed)
1429                 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1430               else
1431                 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1432             }
1433           if (wp == tw)
1434             conv_error ();
1435
1436           if (!(flags & SUPPRESS))
1437             {
1438               if (! number_signed)
1439                 {
1440                   if (need_longlong && (flags & LONGDBL))
1441                     *ARG (unsigned LONGLONG int *) = num.uq;
1442                   else if (need_long && (flags & LONG))
1443                     *ARG (unsigned long int *) = num.ul;
1444                   else if (flags & SHORT)
1445                     *ARG (unsigned short int *)
1446                       = (unsigned short int) num.ul;
1447                   else if (!(flags & CHAR))
1448                     *ARG (unsigned int *) = (unsigned int) num.ul;
1449                   else
1450                     *ARG (unsigned char *) = (unsigned char) num.ul;
1451                 }
1452               else
1453                 {
1454                   if (need_longlong && (flags & LONGDBL))
1455                     *ARG (LONGLONG int *) = num.q;
1456                   else if (need_long && (flags & LONG))
1457                     *ARG (long int *) = num.l;
1458                   else if (flags & SHORT)
1459                     *ARG (short int *) = (short int) num.l;
1460                   else if (!(flags & CHAR))
1461                     *ARG (int *) = (int) num.l;
1462                   else
1463                     *ARG (signed char *) = (signed char) num.ul;
1464                 }
1465               ++done;
1466             }
1467           break;
1468
1469         case L_('e'):   /* Floating-point numbers.  */
1470         case L_('E'):
1471         case L_('f'):
1472         case L_('g'):
1473         case L_('G'):
1474         case L_('a'):
1475         case L_('A'):
1476           c = inchar ();
1477           if (c == EOF)
1478             input_error ();
1479
1480           /* Check for a sign.  */
1481           if (c == L_('-') || c == L_('+'))
1482             {
1483               negative = c == L_('-');
1484               if (width == 0 || inchar () == EOF)
1485                 /* EOF is only an input error before we read any chars.  */
1486                 conv_error ();
1487               if (! ISDIGIT (c))
1488                 {
1489 #ifdef COMPILE_WSCANF
1490                   if (c != decimal)
1491                     {
1492                       /* This is no valid number.  */
1493                       ungetc (c, s);
1494                       input_error ();
1495                     }
1496 #else
1497                   /* Match against the decimal point.  At this point
1498                      we are taking advantage of the fact that we can
1499                      push more than one character back.  This is
1500                      (almost) never necessary since the decimal point
1501                      string hopefully never contains more than one
1502                      byte.  */
1503                   const char *cmpp = decimal;
1504                   int avail = width > 0 ? width : INT_MAX;
1505
1506                   while (*cmpp == c && avail > 0)
1507                     if (*++cmpp == '\0')
1508                       break;
1509                     else
1510                       {
1511                         if (inchar () == EOF)
1512                           break;
1513                         --avail;
1514                       }
1515
1516                   if (*cmpp != '\0')
1517                     {
1518                       /* This is no valid number.  */
1519                       while (1)
1520                         {
1521                           ungetc (c, s);
1522                           if (cmpp == decimal)
1523                             break;
1524                           c = *--cmpp;
1525                         }
1526
1527                       input_error ();
1528                     }
1529                   if (width > 0)
1530                     /* +1 because we substract below.  */
1531                     width = avail + 1;
1532 #endif
1533                 }
1534               if (width > 0)
1535                 --width;
1536             }
1537           else
1538             negative = 0;
1539
1540           /* Take care for the special arguments "nan" and "inf".  */
1541           if (TOLOWER (c) == L_('n'))
1542             {
1543               /* Maybe "nan".  */
1544               ADDW (c);
1545               if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('a'))
1546                 input_error ();
1547               if (width > 0)
1548                 --width;
1549               ADDW (c);
1550               if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1551                 input_error ();
1552               if (width > 0)
1553                 --width;
1554               ADDW (c);
1555               /* It is "nan".  */
1556               goto scan_float;
1557             }
1558           else if (TOLOWER (c) == L_('i'))
1559             {
1560               /* Maybe "inf" or "infinity".  */
1561               ADDW (c);
1562               if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1563                 input_error ();
1564               if (width > 0)
1565                 --width;
1566               ADDW (c);
1567               if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('f'))
1568                 input_error ();
1569               if (width > 0)
1570                 --width;
1571               ADDW (c);
1572               /* It is as least "inf".  */
1573               if (width != 0 && inchar () != EOF)
1574                 {
1575                   if (TOLOWER (c) == L_('i'))
1576                     {
1577                       if (width > 0)
1578                         --width;
1579                       /* Now we have to read the rest as well.  */
1580                       ADDW (c);
1581                       if (width == 0 || inchar () == EOF
1582                           || TOLOWER (c) != L_('n'))
1583                         input_error ();
1584                       if (width > 0)
1585                         --width;
1586                       ADDW (c);
1587                       if (width == 0 || inchar () == EOF
1588                           || TOLOWER (c) != L_('i'))
1589                         input_error ();
1590                       if (width > 0)
1591                         --width;
1592                       ADDW (c);
1593                       if (width == 0 || inchar () == EOF
1594                           || TOLOWER (c) != L_('t'))
1595                         input_error ();
1596                       if (width > 0)
1597                         --width;
1598                       ADDW (c);
1599                       if (width == 0 || inchar () == EOF
1600                           || TOLOWER (c) != L_('y'))
1601                         input_error ();
1602                       if (width > 0)
1603                         --width;
1604                       ADDW (c);
1605                     }
1606                   else
1607                     /* Never mind.  */
1608                     ungetc (c, s);
1609                 }
1610               goto scan_float;
1611             }
1612
1613           is_hexa = 0;
1614           exp_char = L_('e');
1615           if (width != 0 && c == L_('0'))
1616             {
1617               ADDW (c);
1618               c = inchar ();
1619               if (width > 0)
1620                 --width;
1621               if (width != 0 && TOLOWER (c) == L_('x'))
1622                 {
1623                   /* It is a number in hexadecimal format.  */
1624                   ADDW (c);
1625
1626                   is_hexa = 1;
1627                   exp_char = L_('p');
1628
1629                   /* Grouping is not allowed.  */
1630                   flags &= ~GROUP;
1631                   c = inchar ();
1632                   if (width > 0)
1633                     --width;
1634                 }
1635             }
1636
1637           got_dot = got_e = 0;
1638           do
1639             {
1640               if (ISDIGIT (c))
1641                 ADDW (c);
1642               else if (!got_e && is_hexa && ISXDIGIT (c))
1643                 ADDW (c);
1644               else if (got_e && wp[wpsize - 1] == exp_char
1645                        && (c == L_('-') || c == L_('+')))
1646                 ADDW (c);
1647               else if (wpsize > 0 && !got_e && TOLOWER (c) == exp_char)
1648                 {
1649                   ADDW (exp_char);
1650                   got_e = got_dot = 1;
1651                 }
1652               else
1653                 {
1654 #ifdef COMPILE_WSCANF
1655                   if (! got_dot && c == decimal)
1656                     {
1657                       ADDW (c);
1658                       got_dot = 1;
1659                     }
1660                   else if (thousands != L'\0' && ! got_dot && c == thousands)
1661                     ADDW (c);
1662                   else
1663                     {
1664                       /* The last read character is not part of the number
1665                          anymore.  */
1666                       ungetc (c, s);
1667                       break;
1668                     }
1669 #else
1670                   const char *cmpp = decimal;
1671                   int avail = width > 0 ? width : INT_MAX;
1672
1673                   if (! got_dot)
1674                     {
1675                       while (*cmpp == c && avail > 0)
1676                         if (*++cmpp == '\0')
1677                           break;
1678                         else
1679                           {
1680                             if (inchar () == EOF)
1681                               break;
1682                             --avail;
1683                           }
1684                     }
1685
1686                   if (*cmpp == '\0')
1687                     {
1688                       /* Add all the characters.  */
1689                       for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
1690                         ADDW (*cmpp);
1691                       if (width > 0)
1692                         /* +1 because we substract below.  */
1693                         width = avail + 1;
1694                       got_dot = 1;
1695                     }
1696                   else
1697                     {
1698                       /* Figure out whether it is a thousands separator.
1699                          There is one problem: we possibly read more than
1700                          one character.  We cannot push them back but since
1701                          we know that parts of the `decimal' string matched,
1702                          we can compare against it.  */
1703                       const char *cmp2p = thousands;
1704
1705                       if (thousands != NULL && ! got_dot)
1706                         {
1707                           while (cmp2p < cmpp
1708                                  && *cmp2p == decimal[cmp2p - thousands])
1709                             ++cmp2p;
1710                           if (cmp2p == cmpp)
1711                             {
1712                               while (*cmp2p == c && avail > 0)
1713                                 if (*++cmp2p == '\0')
1714                                   break;
1715                                 else
1716                                   {
1717                                     if (inchar () == EOF)
1718                                       break;
1719                                     --avail;
1720                                   }
1721                             }
1722                         }
1723
1724                       if (cmp2p != NULL && *cmp2p == '\0')
1725                         {
1726                           /* Add all the characters.  */
1727                           for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
1728                             ADDW (*cmpp);
1729                           if (width > 0)
1730                             /* +1 because we substract below.  */
1731                             width = avail + 1;
1732                         }
1733                       else
1734                         {
1735                           /* The last read character is not part of the number
1736                              anymore.  */
1737                           ungetc (c, s);
1738                           break;
1739                         }
1740                     }
1741 #endif
1742                 }
1743               if (width > 0)
1744                 --width;
1745             }
1746           while (width != 0 && inchar () != EOF);
1747
1748           /* Have we read any character?  If we try to read a number
1749              in hexadecimal notation and we have read only the `0x'
1750              prefix or no exponent this is an error.  */
1751           if (wpsize == 0 || (is_hexa && (wpsize == 2 || ! got_e)))
1752             conv_error ();
1753
1754         scan_float:
1755           /* Convert the number.  */
1756           ADDW (L_('\0'));
1757           if (flags & LONGDBL)
1758             {
1759               long double d = __strtold_internal (wp, &tw, flags & GROUP);
1760               if (!(flags & SUPPRESS) && tw != wp)
1761                 *ARG (long double *) = negative ? -d : d;
1762             }
1763           else if (flags & LONG)
1764             {
1765               double d = __strtod_internal (wp, &tw, flags & GROUP);
1766               if (!(flags & SUPPRESS) && tw != wp)
1767                 *ARG (double *) = negative ? -d : d;
1768             }
1769           else
1770             {
1771               float d = __strtof_internal (wp, &tw, flags & GROUP);
1772               if (!(flags & SUPPRESS) && tw != wp)
1773                 *ARG (float *) = negative ? -d : d;
1774             }
1775
1776           if (tw == wp)
1777             conv_error ();
1778
1779           if (!(flags & SUPPRESS))
1780             ++done;
1781           break;
1782
1783         case L_('['):   /* Character class.  */
1784           if (flags & LONG)
1785             STRING_ARG (wstr, wchar_t);
1786           else
1787             STRING_ARG (str, char);
1788
1789           if (*f == L_('^'))
1790             {
1791               ++f;
1792               not_in = 1;
1793             }
1794           else
1795             not_in = 0;
1796
1797           if (width < 0)
1798             /* There is no width given so there is also no limit on the
1799                number of characters we read.  Therefore we set width to
1800                a very high value to make the algorithm easier.  */
1801             width = INT_MAX;
1802
1803 #ifdef COMPILE_WSCANF
1804           /* Find the beginning and the end of the scanlist.  We are not
1805              creating a lookup table since it would have to be too large.
1806              Instead we search each time through the string.  This is not
1807              a constant lookup time but who uses this feature deserves to
1808              be punished.  */
1809           tw = (wchar_t *) f;   /* Marks the beginning.  */
1810
1811           if (*f == ']' || *f == '-')
1812             ++f;
1813
1814           while ((fc = *f++) != L'\0' && fc != L']');
1815
1816           if (fc == L'\0')
1817             conv_error ();
1818           wp = (wchar_t *) f - 1;
1819 #else
1820           /* Fill WP with byte flags indexed by character.
1821              We will use this flag map for matching input characters.  */
1822           if (wpmax < UCHAR_MAX)
1823             {
1824               wpmax = UCHAR_MAX;
1825               wp = (char *) alloca (wpmax);
1826             }
1827           memset (wp, '\0', UCHAR_MAX);
1828
1829           fc = *f;
1830           if (fc == ']' || fc == '-')
1831             {
1832               /* If ] or - appears before any char in the set, it is not
1833                  the terminator or separator, but the first char in the
1834                  set.  */
1835               wp[fc] = 1;
1836               ++f;
1837             }
1838
1839           while ((fc = *f++) != '\0' && fc != ']')
1840             if (fc == '-' && *f != '\0' && *f != ']'
1841                 && (unsigned char) f[-2] <= (unsigned char) *f)
1842               {
1843                 /* Add all characters from the one before the '-'
1844                    up to (but not including) the next format char.  */
1845                 for (fc = f[-2]; fc < *f; ++fc)
1846                   wp[fc] = 1;
1847               }
1848             else
1849               /* Add the character to the flag map.  */
1850               wp[fc] = 1;
1851
1852           if (fc == '\0')
1853             conv_error();
1854 #endif
1855
1856           if (flags & LONG)
1857             {
1858               size_t now = read_in;
1859 #ifdef COMPILE_WSCANF
1860               do
1861                 {
1862                   wchar_t *runp;
1863
1864                   if (inchar () == WEOF)
1865                     break;
1866
1867                   /* Test whether it's in the scanlist.  */
1868                   runp = tw;
1869                   while (runp < wp)
1870                     {
1871                       if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']'
1872                           && runp != tw
1873                           && (unsigned int) runp[-1] <= (unsigned int) runp[1])
1874                         {
1875                           /* Match against all characters in between the
1876                              first and last character of the sequence.  */
1877                           wchar_t wc;
1878
1879                           for (wc = runp[-1] + 1; wc < runp[1]; ++wc)
1880                             if (wc == c)
1881                               break;
1882
1883                           if (wc == runp[1] && !not_in)
1884                             break;
1885                           if (wc == runp[1] && not_in)
1886                             {
1887                               /* The current character is not in the
1888                                  scanset.  */
1889                               ungetwc (c, s);
1890                               goto out;
1891                             }
1892                         }
1893                       else
1894                         {
1895                           if (*runp == runp[1] && !not_in)
1896                             break;
1897                           if (*runp != runp[1] && not_in)
1898                             {
1899                               ungetwc (c ,s);
1900                               goto out;
1901                             }
1902                         }
1903
1904                       ++runp;
1905                     }
1906
1907                   if (!(flags & SUPPRESS))
1908                     {
1909                       *wstr++ = c;
1910
1911                       if ((flags & MALLOC)
1912                           && wstr == (wchar_t *) *strptr + strsize)
1913                         {
1914                           /* Enlarge the buffer.  */
1915                           wstr = (wchar_t *) realloc (*strptr,
1916                                                       (2 * strsize)
1917                                                       * sizeof (wchar_t));
1918                           if (wstr == NULL)
1919                             {
1920                               /* Can't allocate that much.  Last-ditch
1921                                  effort.  */
1922                               wstr = (wchar_t *)
1923                                 realloc (*strptr, (strsize
1924                                                    + sizeof (wchar_t)));
1925                               if (wstr == NULL)
1926                                 {
1927                                   /* We lose.  Oh well.  Terminate the string
1928                                      and stop converting, so at least we don't
1929                                      skip any input.  */
1930                                   ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1931                                   ++done;
1932                                   conv_error ();
1933                                 }
1934                               else
1935                                 {
1936                                   *strptr = (char *) wstr;
1937                                   wstr += strsize;
1938                                   ++strsize;
1939                                 }
1940                             }
1941                           else
1942                             {
1943                               *strptr = (char *) wstr;
1944                               wstr += strsize;
1945                               strsize *= 2;
1946                             }
1947                         }
1948                     }
1949                 }
1950               while (--width > 0);
1951             out:
1952 #else
1953               char buf[MB_LEN_MAX];
1954               size_t cnt = 0;
1955               mbstate_t cstate;
1956
1957               memset (&cstate, '\0', sizeof (cstate));
1958
1959               do
1960                 {
1961                 again:
1962                   if (inchar () == EOF)
1963                     break;
1964
1965                   if (wp[c] == not_in)
1966                     {
1967                       ungetc (c, s);
1968                       break;
1969                     }
1970
1971                   /* This is easy.  */
1972                   if (!(flags & SUPPRESS))
1973                     {
1974                       size_t n;
1975
1976                       /* Convert it into a wide character.  */
1977                       n = __mbrtowc (wstr, buf, cnt, &cstate);
1978
1979                       if (n == (size_t) -2)
1980                         {
1981                           /* Possibly correct character, just not enough
1982                              input.  */
1983                           assert (cnt < MB_CUR_MAX);
1984                           goto again;
1985                         }
1986
1987                       if (n != cnt)
1988                         encode_error ();
1989
1990                       ++wstr;
1991                       if ((flags & MALLOC)
1992                           && wstr == (wchar_t *) *strptr + strsize)
1993                         {
1994                           /* Enlarge the buffer.  */
1995                           wstr = (wchar_t *) realloc (*strptr,
1996                                                       (2 * strsize
1997                                                        * sizeof (wchar_t)));
1998                           if (wstr == NULL)
1999                             {
2000                               /* Can't allocate that much.  Last-ditch
2001                                  effort.  */
2002                               wstr = (wchar_t *)
2003                                 realloc (*strptr, ((strsize + 1)
2004                                                    * sizeof (wchar_t)));
2005                               if (wstr == NULL)
2006                                 {
2007                                   /* We lose.  Oh well.  Terminate the
2008                                      string and stop converting,
2009                                      so at least we don't skip any input.  */
2010                                   ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2011                                   ++done;
2012                                   conv_error ();
2013                                 }
2014                               else
2015                                 {
2016                                   *strptr = (char *) wstr;
2017                                   wstr += strsize;
2018                                   ++strsize;
2019                                 }
2020                             }
2021                           else
2022                             {
2023                               *strptr = (char *) wstr;
2024                               wstr += strsize;
2025                               strsize *= 2;
2026                             }
2027                         }
2028                     }
2029                 }
2030               while (--width > 0);
2031
2032               if (cnt != 0)
2033                 /* We stopped in the middle of recognizing another
2034                    character.  That's a problem.  */
2035                 encode_error ();
2036 #endif
2037
2038               if (now == read_in)
2039                 /* We haven't succesfully read any character.  */
2040                 conv_error ();
2041
2042               if (!(flags & SUPPRESS))
2043                 {
2044                   *wstr++ = L'\0';
2045
2046                   if ((flags & MALLOC)
2047                       && wstr - (wchar_t *) *strptr != strsize)
2048                     {
2049                       wchar_t *cp = (wchar_t *)
2050                         realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2051                                            * sizeof(wchar_t)));
2052                       if (cp != NULL)
2053                         *strptr = (char *) cp;
2054                     }
2055
2056                   ++done;
2057                 }
2058             }
2059           else
2060             {
2061               size_t now = read_in;
2062 #ifdef COMPILE_WSCANF
2063
2064               memset (&state, '\0', sizeof (state));
2065
2066               do
2067                 {
2068                   wchar_t *runp;
2069                   size_t n;
2070
2071                   if (inchar () == WEOF)
2072                     break;
2073
2074                   /* Test whether it's in the scanlist.  */
2075                   runp = tw;
2076                   while (runp < wp)
2077                     {
2078                       if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']'
2079                           && runp != tw
2080                           && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2081                         {
2082                           /* Match against all characters in between the
2083                              first and last character of the sequence.  */
2084                           wchar_t wc;
2085
2086                           for (wc = runp[-1] + 1; wc < runp[1]; ++wc)
2087                             if (wc == c)
2088                               break;
2089
2090                           if (wc == runp[1] && !not_in)
2091                             break;
2092                           if (wc == runp[1] && not_in)
2093                             {
2094                               /* The current character is not in the
2095                                  scanset.  */
2096                               ungetwc (c, s);
2097                               goto out2;
2098                             }
2099                         }
2100                       else
2101                         {
2102                           if (*runp == runp[1] && !not_in)
2103                             break;
2104                           if (*runp != runp[1] && not_in)
2105                             {
2106                               ungetwc (c ,s);
2107                               goto out2;
2108                             }
2109                         }
2110
2111                       ++runp;
2112                     }
2113
2114                   if (!(flags & SUPPRESS))
2115                     {
2116                       if ((flags & MALLOC)
2117                           && str + MB_CUR_MAX >= *strptr + strsize)
2118                         {
2119                           /* Enlarge the buffer.  */
2120                           str = (char *) realloc (*strptr, 2 * strsize);
2121                           if (str == NULL)
2122                             {
2123                               /* Can't allocate that much.  Last-ditch
2124                                  effort.  */
2125                               str = (char *) realloc (*strptr, strsize + 1);
2126                               if (str == NULL)
2127                                 {
2128                                   /* We lose.  Oh well.  Terminate the string
2129                                      and stop converting, so at least we don't
2130                                      skip any input.  */
2131                                   (*strptr)[strsize - 1] = '\0';
2132                                   ++done;
2133                                   conv_error ();
2134                                 }
2135                               else
2136                                 {
2137                                   *strptr = str;
2138                                   str += strsize;
2139                                   ++strsize;
2140                                 }
2141                             }
2142                           else
2143                             {
2144                               *strptr = str;
2145                               str += strsize;
2146                               strsize *= 2;
2147                             }
2148                         }
2149                     }
2150
2151                   n = wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2152                   if (n == (size_t) -1)
2153                     encode_error ();
2154
2155                   assert (n <= MB_CUR_MAX);
2156                   str += n;
2157                 }
2158               while (--width > 0);
2159             out2:
2160 #else
2161               do
2162                 {
2163                   if (inchar () == EOF)
2164                     break;
2165
2166                   if (wp[c] == not_in)
2167                     {
2168                       ungetc (c, s);
2169                       break;
2170                     }
2171
2172                   /* This is easy.  */
2173                   if (!(flags & SUPPRESS))
2174                     {
2175                       *str++ = c;
2176                       if ((flags & MALLOC)
2177                           && (char *) str == *strptr + strsize)
2178                         {
2179                           /* Enlarge the buffer.  */
2180                           str = (char *) realloc (*strptr, 2 * strsize);
2181                           if (str == NULL)
2182                             {
2183                               /* Can't allocate that much.  Last-ditch
2184                                  effort.  */
2185                               str = (char *) realloc (*strptr, strsize + 1);
2186                               if (str == NULL)
2187                                 {
2188                                   /* We lose.  Oh well.  Terminate the
2189                                      string and stop converting,
2190                                      so at least we don't skip any input.  */
2191                                   ((char *) (*strptr))[strsize - 1] = '\0';
2192                                   ++done;
2193                                   conv_error ();
2194                                 }
2195                               else
2196                                 {
2197                                   *strptr = (char *) str;
2198                                   str += strsize;
2199                                   ++strsize;
2200                                 }
2201                             }
2202                           else
2203                             {
2204                               *strptr = (char *) str;
2205                               str += strsize;
2206                               strsize *= 2;
2207                             }
2208                         }
2209                     }
2210                 }
2211               while (--width > 0);
2212 #endif
2213
2214               if (now == read_in)
2215                 /* We haven't succesfully read any character.  */
2216                 conv_error ();
2217
2218               if (!(flags & SUPPRESS))
2219                 {
2220 #ifdef COMPILE_WSCANF
2221                   /* We have to emit the code to get into the intial
2222                      state.  */
2223                   char buf[MB_LEN_MAX];
2224                   size_t n = wcrtomb (buf, L'\0', &state);
2225                   if (n > 0 && (flags & MALLOC)
2226                       && str + n >= *strptr + strsize)
2227                     {
2228                       /* Enlarge the buffer.  */
2229                       str = (char *) realloc (*strptr,
2230                                               (str + n + 1) - *strptr);
2231                       if (str == NULL)
2232                         {
2233                           /* We lose.  Oh well.  Terminate the string
2234                              and stop converting, so at least we don't
2235                              skip any input.  */
2236                           ((char *) (*strptr))[strsize - 1] = '\0';
2237                           ++done;
2238                           conv_error ();
2239                         }
2240                       else
2241                         {
2242                           *strptr = (char *) str;
2243                           str = ((char *) *strptr) + strsize;
2244                           strsize = (str + n + 1) - *strptr;
2245                         }
2246                     }
2247
2248                   str = __mempcpy (str, buf, n);
2249 #endif
2250                   *str = '\0';
2251
2252                   if ((flags & MALLOC) && str - *strptr != strsize)
2253                     {
2254                       char *cp = (char *) realloc (*strptr, str - *strptr);
2255                       if (cp != NULL)
2256                         *strptr = cp;
2257                     }
2258
2259                   ++done;
2260                 }
2261             }
2262           break;
2263
2264         case L_('p'):   /* Generic pointer.  */
2265           base = 16;
2266           /* A PTR must be the same size as a `long int'.  */
2267           flags &= ~(SHORT|LONGDBL);
2268           if (need_long)
2269             flags |= LONG;
2270           number_signed = 0;
2271           read_pointer = 1;
2272           goto number;
2273
2274         default:
2275           /* If this is an unknown format character punt.  */
2276           conv_error ();
2277         }
2278     }
2279
2280   /* The last thing we saw int the format string was a white space.
2281      Consume the last white spaces.  */
2282   if (skip_space)
2283     {
2284       do
2285         c = inchar ();
2286       while (ISSPACE (c));
2287       ungetc (c, s);
2288     }
2289
2290   /* Unlock stream.  */
2291   UNLOCK_STREAM (s);
2292
2293   return done;
2294 }
2295
2296 #ifdef USE_IN_LIBIO
2297 # ifdef COMPILE_WSCANF
2298 int
2299 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2300 {
2301   return _IO_vfwscanf (s, format, argptr, NULL);
2302 }
2303 # else
2304 int
2305 __vfscanf (FILE *s, const char *format, va_list argptr)
2306 {
2307   return _IO_vfscanf (s, format, argptr, NULL);
2308 }
2309 # endif
2310 #endif
2311
2312 #ifdef COMPILE_WSCANF
2313 weak_alias (__vfwscanf, vfwscanf)
2314 #else
2315 weak_alias (__vfscanf, vfscanf)
2316 #endif