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