| /* Copyright (C) 1991-2016 Free Software Foundation, Inc. | 
 |    This file is part of the GNU C Library. | 
 |  | 
 |    The GNU C Library is free software; you can redistribute it and/or | 
 |    modify it under the terms of the GNU Lesser General Public | 
 |    License as published by the Free Software Foundation; either | 
 |    version 2.1 of the License, or (at your option) any later version. | 
 |  | 
 |    The GNU C Library is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |    Lesser General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU Lesser General Public | 
 |    License along with the GNU C Library; if not, see | 
 |    <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #include <assert.h> | 
 | #include <errno.h> | 
 | #include <limits.h> | 
 | #include <ctype.h> | 
 | #include <stdarg.h> | 
 | #include <stdbool.h> | 
 | #include <stdio.h> | 
 | #include <stdint.h> | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 | #include <wchar.h> | 
 | #include <wctype.h> | 
 | #include <libc-internal.h> | 
 | #include <libc-lock.h> | 
 | #include <locale/localeinfo.h> | 
 | #include <scratch_buffer.h> | 
 |  | 
 | #ifdef	__GNUC__ | 
 | # define HAVE_LONGLONG | 
 | # define LONGLONG	long long | 
 | #else | 
 | # define LONGLONG	long | 
 | #endif | 
 |  | 
 | /* Determine whether we have to handle `long long' at all.  */ | 
 | #if LONG_MAX == LONG_LONG_MAX | 
 | # define need_longlong	0 | 
 | #else | 
 | # define need_longlong	1 | 
 | #endif | 
 |  | 
 | /* Determine whether we have to handle `long'.  */ | 
 | #if INT_MAX == LONG_MAX | 
 | # define need_long	0 | 
 | #else | 
 | # define need_long	1 | 
 | #endif | 
 |  | 
 | /* Those are flags in the conversion format. */ | 
 | #define LONG		0x0001	/* l: long or double */ | 
 | #define LONGDBL		0x0002	/* L: long long or long double */ | 
 | #define SHORT		0x0004	/* h: short */ | 
 | #define SUPPRESS	0x0008	/* *: suppress assignment */ | 
 | #define POINTER		0x0010	/* weird %p pointer (`fake hex') */ | 
 | #define NOSKIP		0x0020	/* do not skip blanks */ | 
 | #define NUMBER_SIGNED	0x0040	/* signed integer */ | 
 | #define GROUP		0x0080	/* ': group numbers */ | 
 | #define GNU_MALLOC	0x0100	/* a: malloc strings */ | 
 | #define CHAR		0x0200	/* hh: char */ | 
 | #define I18N		0x0400	/* I: use locale's digits */ | 
 | #define HEXA_FLOAT	0x0800	/* hexadecimal float */ | 
 | #define READ_POINTER	0x1000	/* this is a pointer value */ | 
 | #define POSIX_MALLOC	0x2000	/* m: malloc strings */ | 
 | #define MALLOC		(GNU_MALLOC | POSIX_MALLOC) | 
 |  | 
 | #include <locale/localeinfo.h> | 
 | #include <libioP.h> | 
 | #include <libio.h> | 
 |  | 
 | #undef va_list | 
 | #define va_list	_IO_va_list | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | # define ungetc(c, s)	((void) (c == WEOF				      \ | 
 | 				 || (--read_in,				      \ | 
 | 				     _IO_sputbackwc (s, c)))) | 
 | # define ungetc_not_eof(c, s)	((void) (--read_in,			      \ | 
 | 					 _IO_sputbackwc (s, c))) | 
 | # define inchar()	(c == WEOF ? ((errno = inchar_errno), WEOF)	      \ | 
 | 			 : ((c = _IO_getwc_unlocked (s)),		      \ | 
 | 			    (void) (c != WEOF				      \ | 
 | 				    ? ++read_in				      \ | 
 | 				    : (size_t) (inchar_errno = errno)), c)) | 
 |  | 
 | # define ISSPACE(Ch)	  iswspace (Ch) | 
 | # define ISDIGIT(Ch)	  iswdigit (Ch) | 
 | # define ISXDIGIT(Ch)	  iswxdigit (Ch) | 
 | # define TOLOWER(Ch)	  towlower (Ch) | 
 | # define ORIENT	  if (_IO_fwide (s, 1) != 1) return WEOF | 
 | # define __strtoll_internal	__wcstoll_internal | 
 | # define __strtoull_internal	__wcstoull_internal | 
 | # define __strtol_internal	__wcstol_internal | 
 | # define __strtoul_internal	__wcstoul_internal | 
 | # define __strtold_internal	__wcstold_internal | 
 | # define __strtod_internal	__wcstod_internal | 
 | # define __strtof_internal	__wcstof_internal | 
 |  | 
 | # define L_(Str)	L##Str | 
 | # define CHAR_T		wchar_t | 
 | # define UCHAR_T	unsigned int | 
 | # define WINT_T		wint_t | 
 | # undef EOF | 
 | # define EOF		WEOF | 
 | #else | 
 | # define ungetc(c, s)	((void) ((int) c == EOF				      \ | 
 | 				 || (--read_in,				      \ | 
 | 				     _IO_sputbackc (s, (unsigned char) c)))) | 
 | # define ungetc_not_eof(c, s)	((void) (--read_in,			      \ | 
 | 					 _IO_sputbackc (s, (unsigned char) c))) | 
 | # define inchar()	(c == EOF ? ((errno = inchar_errno), EOF)	      \ | 
 | 			 : ((c = _IO_getc_unlocked (s)),		      \ | 
 | 			    (void) (c != EOF				      \ | 
 | 				    ? ++read_in				      \ | 
 | 				    : (size_t) (inchar_errno = errno)), c)) | 
 | # define ISSPACE(Ch)	  __isspace_l (Ch, loc) | 
 | # define ISDIGIT(Ch)	  __isdigit_l (Ch, loc) | 
 | # define ISXDIGIT(Ch)	  __isxdigit_l (Ch, loc) | 
 | # define TOLOWER(Ch)	  __tolower_l ((unsigned char) (Ch), loc) | 
 | # define ORIENT	  if (_IO_vtable_offset (s) == 0			      \ | 
 | 			      && _IO_fwide (s, -1) != -1)		      \ | 
 | 			    return EOF | 
 |  | 
 | # define L_(Str)	Str | 
 | # define CHAR_T		char | 
 | # define UCHAR_T	unsigned char | 
 | # define WINT_T		int | 
 | #endif | 
 |  | 
 | #define encode_error() do {						      \ | 
 | 			  errval = 4;					      \ | 
 | 			  __set_errno (EILSEQ);				      \ | 
 | 			  goto errout;					      \ | 
 | 			} while (0) | 
 | #define conv_error()	do {						      \ | 
 | 			  errval = 2;					      \ | 
 | 			  goto errout;					      \ | 
 | 			} while (0) | 
 | #define input_error()	do {						      \ | 
 | 			  errval = 1;					      \ | 
 | 			  if (done == 0) done = EOF;			      \ | 
 | 			  goto errout;					      \ | 
 | 			} while (0) | 
 | #define add_ptr_to_free(ptr)						      \ | 
 |   do									      \ | 
 |     {									      \ | 
 |       if (ptrs_to_free == NULL						      \ | 
 | 	  || ptrs_to_free->count == (sizeof (ptrs_to_free->ptrs)	      \ | 
 | 				     / sizeof (ptrs_to_free->ptrs[0])))	      \ | 
 | 	{								      \ | 
 | 	  struct ptrs_to_free *new_ptrs = alloca (sizeof (*ptrs_to_free));    \ | 
 | 	  new_ptrs->count = 0;						      \ | 
 | 	  new_ptrs->next = ptrs_to_free;				      \ | 
 | 	  ptrs_to_free = new_ptrs;					      \ | 
 | 	}								      \ | 
 |       ptrs_to_free->ptrs[ptrs_to_free->count++] = (ptr);		      \ | 
 |     }									      \ | 
 |   while (0) | 
 | #define ARGCHECK(s, format)						      \ | 
 |   do									      \ | 
 |     {									      \ | 
 |       /* Check file argument for consistence.  */			      \ | 
 |       CHECK_FILE (s, EOF);						      \ | 
 |       if (s->_flags & _IO_NO_READS)					      \ | 
 | 	{								      \ | 
 | 	  __set_errno (EBADF);						      \ | 
 | 	  return EOF;							      \ | 
 | 	}								      \ | 
 |       else if (format == NULL)						      \ | 
 | 	{								      \ | 
 | 	  MAYBE_SET_EINVAL;						      \ | 
 | 	  return EOF;							      \ | 
 | 	}								      \ | 
 |     } while (0) | 
 | #define LOCK_STREAM(S)							      \ | 
 |   __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \ | 
 |   _IO_flockfile (S) | 
 | #define UNLOCK_STREAM(S)						      \ | 
 |   _IO_funlockfile (S);							      \ | 
 |   __libc_cleanup_region_end (0) | 
 |  | 
 | struct ptrs_to_free | 
 | { | 
 |   size_t count; | 
 |   struct ptrs_to_free *next; | 
 |   char **ptrs[32]; | 
 | }; | 
 |  | 
 | struct char_buffer { | 
 |   CHAR_T *current; | 
 |   CHAR_T *end; | 
 |   struct scratch_buffer scratch; | 
 | }; | 
 |  | 
 | /* Returns a pointer to the first CHAR_T object in the buffer.  Only | 
 |    valid if char_buffer_add (BUFFER, CH) has been called and | 
 |    char_buffer_error (BUFFER) is false.  */ | 
 | static inline CHAR_T * | 
 | char_buffer_start (const struct char_buffer *buffer) | 
 | { | 
 |   return (CHAR_T *) buffer->scratch.data; | 
 | } | 
 |  | 
 | /* Returns the number of CHAR_T objects in the buffer.  Only valid if | 
 |    char_buffer_error (BUFFER) is false.  */ | 
 | static inline size_t | 
 | char_buffer_size (const struct char_buffer *buffer) | 
 | { | 
 |   return buffer->current - char_buffer_start (buffer); | 
 | } | 
 |  | 
 | /* Reinitializes BUFFER->current and BUFFER->end to cover the entire | 
 |    scratch buffer.  */ | 
 | static inline void | 
 | char_buffer_rewind (struct char_buffer *buffer) | 
 | { | 
 |   buffer->current = char_buffer_start (buffer); | 
 |   buffer->end = buffer->current + buffer->scratch.length / sizeof (CHAR_T); | 
 | } | 
 |  | 
 | /* Returns true if a previous call to char_buffer_add (BUFFER, CH) | 
 |    failed.  */ | 
 | static inline bool | 
 | char_buffer_error (const struct char_buffer *buffer) | 
 | { | 
 |   return __glibc_unlikely (buffer->current == NULL); | 
 | } | 
 |  | 
 | /* Slow path for char_buffer_add.  */ | 
 | static void | 
 | char_buffer_add_slow (struct char_buffer *buffer, CHAR_T ch) | 
 | { | 
 |   if (char_buffer_error (buffer)) | 
 |     return; | 
 |   size_t offset = buffer->end - (CHAR_T *) buffer->scratch.data; | 
 |   if (!scratch_buffer_grow_preserve (&buffer->scratch)) | 
 |     { | 
 |       buffer->current = NULL; | 
 |       buffer->end = NULL; | 
 |       return; | 
 |     } | 
 |   char_buffer_rewind (buffer); | 
 |   buffer->current += offset; | 
 |   *buffer->current++ = ch; | 
 | } | 
 |  | 
 | /* Adds CH to BUFFER.  This function does not report any errors, check | 
 |    for them with char_buffer_error.  */ | 
 | static inline void | 
 | char_buffer_add (struct char_buffer *buffer, CHAR_T ch) | 
 |   __attribute__ ((always_inline)); | 
 | static inline void | 
 | char_buffer_add (struct char_buffer *buffer, CHAR_T ch) | 
 | { | 
 |   if (__glibc_unlikely (buffer->current == buffer->end)) | 
 |     char_buffer_add_slow (buffer, ch); | 
 |   else | 
 |     *buffer->current++ = ch; | 
 | } | 
 |  | 
 | /* Read formatted input from S according to the format string | 
 |    FORMAT, using the argument list in ARG. | 
 |    Return the number of assignments made, or -1 for an input error.  */ | 
 | #ifdef COMPILE_WSCANF | 
 | int | 
 | _IO_vfwscanf (_IO_FILE *s, const wchar_t *format, _IO_va_list argptr, | 
 | 	      int *errp) | 
 | #else | 
 | int | 
 | _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr, | 
 | 		      int *errp) | 
 | #endif | 
 | { | 
 |   va_list arg; | 
 |   const CHAR_T *f = format; | 
 |   UCHAR_T fc;	/* Current character of the format.  */ | 
 |   WINT_T done = 0;	/* Assignments done.  */ | 
 |   size_t read_in = 0;	/* Chars read in.  */ | 
 |   WINT_T c = 0;	/* Last char read.  */ | 
 |   int width;		/* Maximum field width.  */ | 
 |   int flags;		/* Modifiers for current format element.  */ | 
 |   int errval = 0; | 
 | #ifndef COMPILE_WSCANF | 
 |   __locale_t loc = _NL_CURRENT_LOCALE; | 
 |   struct __locale_data *const curctype = loc->__locales[LC_CTYPE]; | 
 | #endif | 
 |  | 
 |   /* Errno of last failed inchar call.  */ | 
 |   int inchar_errno = 0; | 
 |   /* Status for reading F-P nums.  */ | 
 |   char got_digit, got_dot, got_e, negative; | 
 |   /* If a [...] is a [^...].  */ | 
 |   CHAR_T not_in; | 
 | #define exp_char not_in | 
 |   /* Base for integral numbers.  */ | 
 |   int base; | 
 |   /* Decimal point character.  */ | 
 | #ifdef COMPILE_WSCANF | 
 |   wint_t decimal; | 
 | #else | 
 |   const char *decimal; | 
 | #endif | 
 |   /* The thousands character of the current locale.  */ | 
 | #ifdef COMPILE_WSCANF | 
 |   wint_t thousands; | 
 | #else | 
 |   const char *thousands; | 
 | #endif | 
 |   struct ptrs_to_free *ptrs_to_free = NULL; | 
 |   /* State for the conversions.  */ | 
 |   mbstate_t state; | 
 |   /* Integral holding variables.  */ | 
 |   union | 
 |     { | 
 |       long long int q; | 
 |       unsigned long long int uq; | 
 |       long int l; | 
 |       unsigned long int ul; | 
 |     } num; | 
 |   /* Character-buffer pointer.  */ | 
 |   char *str = NULL; | 
 |   wchar_t *wstr = NULL; | 
 |   char **strptr = NULL; | 
 |   ssize_t strsize = 0; | 
 |   /* We must not react on white spaces immediately because they can | 
 |      possibly be matched even if in the input stream no character is | 
 |      available anymore.  */ | 
 |   int skip_space = 0; | 
 |   /* Workspace.  */ | 
 |   CHAR_T *tw;			/* Temporary pointer.  */ | 
 |   struct char_buffer charbuf; | 
 |   scratch_buffer_init (&charbuf.scratch); | 
 |  | 
 | #ifdef __va_copy | 
 |   __va_copy (arg, argptr); | 
 | #else | 
 |   arg = (va_list) argptr; | 
 | #endif | 
 |  | 
 | #ifdef ORIENT | 
 |   ORIENT; | 
 | #endif | 
 |  | 
 |   ARGCHECK (s, format); | 
 |  | 
 |  { | 
 | #ifndef COMPILE_WSCANF | 
 |    struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC]; | 
 | #endif | 
 |  | 
 |    /* Figure out the decimal point character.  */ | 
 | #ifdef COMPILE_WSCANF | 
 |    decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC); | 
 | #else | 
 |    decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string; | 
 | #endif | 
 |    /* Figure out the thousands separator character.  */ | 
 | #ifdef COMPILE_WSCANF | 
 |    thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC); | 
 | #else | 
 |    thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string; | 
 |    if (*thousands == '\0') | 
 |      thousands = NULL; | 
 | #endif | 
 |  } | 
 |  | 
 |   /* Lock the stream.  */ | 
 |   LOCK_STREAM (s); | 
 |  | 
 |  | 
 | #ifndef COMPILE_WSCANF | 
 |   /* From now on we use `state' to convert the format string.  */ | 
 |   memset (&state, '\0', sizeof (state)); | 
 | #endif | 
 |  | 
 |   /* Run through the format string.  */ | 
 |   while (*f != '\0') | 
 |     { | 
 |       unsigned int argpos; | 
 |       /* Extract the next argument, which is of type TYPE. | 
 | 	 For a %N$... spec, this is the Nth argument from the beginning; | 
 | 	 otherwise it is the next argument after the state now in ARG.  */ | 
 | #ifdef __va_copy | 
 | # define ARG(type)	(argpos == 0 ? va_arg (arg, type) :		      \ | 
 | 			 ({ unsigned int pos = argpos;			      \ | 
 | 			    va_list arg;				      \ | 
 | 			    __va_copy (arg, argptr);			      \ | 
 | 			    while (--pos > 0)				      \ | 
 | 			      (void) va_arg (arg, void *);		      \ | 
 | 			    va_arg (arg, type);				      \ | 
 | 			  })) | 
 | #else | 
 | # if 0 | 
 |       /* XXX Possible optimization.  */ | 
 | #  define ARG(type)	(argpos == 0 ? va_arg (arg, type) :		      \ | 
 | 			 ({ va_list arg = (va_list) argptr;		      \ | 
 | 			    arg = (va_list) ((char *) arg		      \ | 
 | 					     + (argpos - 1)		      \ | 
 | 					     * __va_rounded_size (void *));   \ | 
 | 			    va_arg (arg, type);				      \ | 
 | 			 })) | 
 | # else | 
 | #  define ARG(type)	(argpos == 0 ? va_arg (arg, type) :		      \ | 
 | 			 ({ unsigned int pos = argpos;			      \ | 
 | 			    va_list arg = (va_list) argptr;		      \ | 
 | 			    while (--pos > 0)				      \ | 
 | 			      (void) va_arg (arg, void *);		      \ | 
 | 			    va_arg (arg, type);				      \ | 
 | 			  })) | 
 | # endif | 
 | #endif | 
 |  | 
 | #ifndef COMPILE_WSCANF | 
 |       if (!isascii ((unsigned char) *f)) | 
 | 	{ | 
 | 	  /* Non-ASCII, may be a multibyte.  */ | 
 | 	  int len = __mbrlen (f, strlen (f), &state); | 
 | 	  if (len > 0) | 
 | 	    { | 
 | 	      do | 
 | 		{ | 
 | 		  c = inchar (); | 
 | 		  if (__glibc_unlikely (c == EOF)) | 
 | 		    input_error (); | 
 | 		  else if (c != (unsigned char) *f++) | 
 | 		    { | 
 | 		      ungetc_not_eof (c, s); | 
 | 		      conv_error (); | 
 | 		    } | 
 | 		} | 
 | 	      while (--len > 0); | 
 | 	      continue; | 
 | 	    } | 
 | 	} | 
 | #endif | 
 |  | 
 |       fc = *f++; | 
 |       if (fc != '%') | 
 | 	{ | 
 | 	  /* Remember to skip spaces.  */ | 
 | 	  if (ISSPACE (fc)) | 
 | 	    { | 
 | 	      skip_space = 1; | 
 | 	      continue; | 
 | 	    } | 
 |  | 
 | 	  /* Read a character.  */ | 
 | 	  c = inchar (); | 
 |  | 
 | 	  /* Characters other than format specs must just match.  */ | 
 | 	  if (__glibc_unlikely (c == EOF)) | 
 | 	    input_error (); | 
 |  | 
 | 	  /* We saw white space char as the last character in the format | 
 | 	     string.  Now it's time to skip all leading white space.  */ | 
 | 	  if (skip_space) | 
 | 	    { | 
 | 	      while (ISSPACE (c)) | 
 | 		if (__glibc_unlikely (inchar () == EOF)) | 
 | 		  input_error (); | 
 | 	      skip_space = 0; | 
 | 	    } | 
 |  | 
 | 	  if (__glibc_unlikely (c != fc)) | 
 | 	    { | 
 | 	      ungetc (c, s); | 
 | 	      conv_error (); | 
 | 	    } | 
 |  | 
 | 	  continue; | 
 | 	} | 
 |  | 
 |       /* This is the start of the conversion string. */ | 
 |       flags = 0; | 
 |  | 
 |       /* Initialize state of modifiers.  */ | 
 |       argpos = 0; | 
 |  | 
 |       /* Prepare temporary buffer.  */ | 
 |       char_buffer_rewind (&charbuf); | 
 |  | 
 |       /* Check for a positional parameter specification.  */ | 
 |       if (ISDIGIT ((UCHAR_T) *f)) | 
 | 	{ | 
 | 	  argpos = (UCHAR_T) *f++ - L_('0'); | 
 | 	  while (ISDIGIT ((UCHAR_T) *f)) | 
 | 	    argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0')); | 
 | 	  if (*f == L_('$')) | 
 | 	    ++f; | 
 | 	  else | 
 | 	    { | 
 | 	      /* Oops; that was actually the field width.  */ | 
 | 	      width = argpos; | 
 | 	      argpos = 0; | 
 | 	      goto got_width; | 
 | 	    } | 
 | 	} | 
 |  | 
 |       /* Check for the assignment-suppressing, the number grouping flag, | 
 | 	 and the signal to use the locale's digit representation.  */ | 
 |       while (*f == L_('*') || *f == L_('\'') || *f == L_('I')) | 
 | 	switch (*f++) | 
 | 	  { | 
 | 	  case L_('*'): | 
 | 	    flags |= SUPPRESS; | 
 | 	    break; | 
 | 	  case L_('\''): | 
 | #ifdef COMPILE_WSCANF | 
 | 	    if (thousands != L'\0') | 
 | #else | 
 | 	    if (thousands != NULL) | 
 | #endif | 
 | 	      flags |= GROUP; | 
 | 	    break; | 
 | 	  case L_('I'): | 
 | 	    flags |= I18N; | 
 | 	    break; | 
 | 	  } | 
 |  | 
 |       /* Find the maximum field width.  */ | 
 |       width = 0; | 
 |       while (ISDIGIT ((UCHAR_T) *f)) | 
 | 	{ | 
 | 	  width *= 10; | 
 | 	  width += (UCHAR_T) *f++ - L_('0'); | 
 | 	} | 
 |     got_width: | 
 |       if (width == 0) | 
 | 	width = -1; | 
 |  | 
 |       /* Check for type modifiers.  */ | 
 |       switch (*f++) | 
 | 	{ | 
 | 	case L_('h'): | 
 | 	  /* ints are short ints or chars.  */ | 
 | 	  if (*f == L_('h')) | 
 | 	    { | 
 | 	      ++f; | 
 | 	      flags |= CHAR; | 
 | 	    } | 
 | 	  else | 
 | 	    flags |= SHORT; | 
 | 	  break; | 
 | 	case L_('l'): | 
 | 	  if (*f == L_('l')) | 
 | 	    { | 
 | 	      /* A double `l' is equivalent to an `L'.  */ | 
 | 	      ++f; | 
 | 	      flags |= LONGDBL | LONG; | 
 | 	    } | 
 | 	  else | 
 | 	    /* ints are long ints.  */ | 
 | 	    flags |= LONG; | 
 | 	  break; | 
 | 	case L_('q'): | 
 | 	case L_('L'): | 
 | 	  /* doubles are long doubles, and ints are long long ints.  */ | 
 | 	  flags |= LONGDBL | LONG; | 
 | 	  break; | 
 | 	case L_('a'): | 
 | 	  /* The `a' is used as a flag only if followed by `s', `S' or | 
 | 	     `['.  */ | 
 | 	  if (*f != L_('s') && *f != L_('S') && *f != L_('[')) | 
 | 	    { | 
 | 	      --f; | 
 | 	      break; | 
 | 	    } | 
 | 	  /* In __isoc99_*scanf %as, %aS and %a[ extension is not | 
 | 	     supported at all.  */ | 
 | 	  if (s->_flags2 & _IO_FLAGS2_SCANF_STD) | 
 | 	    { | 
 | 	      --f; | 
 | 	      break; | 
 | 	    } | 
 | 	  /* String conversions (%s, %[) take a `char **' | 
 | 	     arg and fill it in with a malloc'd pointer.  */ | 
 | 	  flags |= GNU_MALLOC; | 
 | 	  break; | 
 | 	case L_('m'): | 
 | 	  flags |= POSIX_MALLOC; | 
 | 	  if (*f == L_('l')) | 
 | 	    { | 
 | 	      ++f; | 
 | 	      flags |= LONG; | 
 | 	    } | 
 | 	  break; | 
 | 	case L_('z'): | 
 | 	  if (need_longlong && sizeof (size_t) > sizeof (unsigned long int)) | 
 | 	    flags |= LONGDBL; | 
 | 	  else if (sizeof (size_t) > sizeof (unsigned int)) | 
 | 	    flags |= LONG; | 
 | 	  break; | 
 | 	case L_('j'): | 
 | 	  if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int)) | 
 | 	    flags |= LONGDBL; | 
 | 	  else if (sizeof (uintmax_t) > sizeof (unsigned int)) | 
 | 	    flags |= LONG; | 
 | 	  break; | 
 | 	case L_('t'): | 
 | 	  if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int)) | 
 | 	    flags |= LONGDBL; | 
 | 	  else if (sizeof (ptrdiff_t) > sizeof (int)) | 
 | 	    flags |= LONG; | 
 | 	  break; | 
 | 	default: | 
 | 	  /* Not a recognized modifier.  Backup.  */ | 
 | 	  --f; | 
 | 	  break; | 
 | 	} | 
 |  | 
 |       /* End of the format string?  */ | 
 |       if (__glibc_unlikely (*f == L_('\0'))) | 
 | 	conv_error (); | 
 |  | 
 |       /* Find the conversion specifier.  */ | 
 |       fc = *f++; | 
 |       if (skip_space || (fc != L_('[') && fc != L_('c') | 
 | 			 && fc != L_('C') && fc != L_('n'))) | 
 | 	{ | 
 | 	  /* Eat whitespace.  */ | 
 | 	  int save_errno = errno; | 
 | 	  __set_errno (0); | 
 | 	  do | 
 | 	    /* We add the additional test for EOF here since otherwise | 
 | 	       inchar will restore the old errno value which might be | 
 | 	       EINTR but does not indicate an interrupt since nothing | 
 | 	       was read at this time.  */ | 
 | 	    if (__builtin_expect ((c == EOF || inchar () == EOF) | 
 | 				  && errno == EINTR, 0)) | 
 | 	      input_error (); | 
 | 	  while (ISSPACE (c)); | 
 | 	  __set_errno (save_errno); | 
 | 	  ungetc (c, s); | 
 | 	  skip_space = 0; | 
 | 	} | 
 |  | 
 |       switch (fc) | 
 | 	{ | 
 | 	case L_('%'):	/* Must match a literal '%'.  */ | 
 | 	  c = inchar (); | 
 | 	  if (__glibc_unlikely (c == EOF)) | 
 | 	    input_error (); | 
 | 	  if (__glibc_unlikely (c != fc)) | 
 | 	    { | 
 | 	      ungetc_not_eof (c, s); | 
 | 	      conv_error (); | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case L_('n'):	/* Answer number of assignments done.  */ | 
 | 	  /* Corrigendum 1 to ISO C 1990 describes the allowed flags | 
 | 	     with the 'n' conversion specifier.  */ | 
 | 	  if (!(flags & SUPPRESS)) | 
 | 	    { | 
 | 	      /* Don't count the read-ahead.  */ | 
 | 	      if (need_longlong && (flags & LONGDBL)) | 
 | 		*ARG (long long int *) = read_in; | 
 | 	      else if (need_long && (flags & LONG)) | 
 | 		*ARG (long int *) = read_in; | 
 | 	      else if (flags & SHORT) | 
 | 		*ARG (short int *) = read_in; | 
 | 	      else if (!(flags & CHAR)) | 
 | 		*ARG (int *) = read_in; | 
 | 	      else | 
 | 		*ARG (char *) = read_in; | 
 |  | 
 | #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1 | 
 | 	      /* We have a severe problem here.  The ISO C standard | 
 | 		 contradicts itself in explaining the effect of the %n | 
 | 		 format in `scanf'.  While in ISO C:1990 and the ISO C | 
 | 		 Amendement 1:1995 the result is described as | 
 |  | 
 | 		   Execution of a %n directive does not effect the | 
 | 		   assignment count returned at the completion of | 
 | 		   execution of the f(w)scanf function. | 
 |  | 
 | 		 in ISO C Corrigendum 1:1994 the following was added: | 
 |  | 
 | 		   Subclause 7.9.6.2 | 
 | 		   Add the following fourth example: | 
 | 		     In: | 
 | 		       #include <stdio.h> | 
 | 		       int d1, d2, n1, n2, i; | 
 | 		       i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2); | 
 | 		     the value 123 is assigned to d1 and the value3 to n1. | 
 | 		     Because %n can never get an input failure the value | 
 | 		     of 3 is also assigned to n2.  The value of d2 is not | 
 | 		     affected.  The value 3 is assigned to i. | 
 |  | 
 | 		 We go for now with the historically correct code from ISO C, | 
 | 		 i.e., we don't count the %n assignments.  When it ever | 
 | 		 should proof to be wrong just remove the #ifdef above.  */ | 
 | 	      ++done; | 
 | #endif | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case L_('c'):	/* Match characters.  */ | 
 | 	  if ((flags & LONG) == 0) | 
 | 	    { | 
 | 	      if (width == -1) | 
 | 		width = 1; | 
 |  | 
 | #define STRING_ARG(Str, Type, Width)					      \ | 
 | 	      do if (!(flags & SUPPRESS))				      \ | 
 | 		{							      \ | 
 | 		  if (flags & MALLOC)					      \ | 
 | 		    {							      \ | 
 | 		      /* The string is to be stored in a malloc'd buffer.  */ \ | 
 | 		      /* For %mS using char ** is actually wrong, but	      \ | 
 | 			 shouldn't make a difference on any arch glibc	      \ | 
 | 			 supports and would unnecessarily complicate	      \ | 
 | 			 things. */					      \ | 
 | 		      strptr = ARG (char **);				      \ | 
 | 		      if (strptr == NULL)				      \ | 
 | 			conv_error ();					      \ | 
 | 		      /* Allocate an initial buffer.  */		      \ | 
 | 		      strsize = Width;					      \ | 
 | 		      *strptr = (char *) malloc (strsize * sizeof (Type));    \ | 
 | 		      Str = (Type *) *strptr;				      \ | 
 | 		      if (Str != NULL)					      \ | 
 | 			add_ptr_to_free (strptr);			      \ | 
 | 		      else if (flags & POSIX_MALLOC)			      \ | 
 | 			{						      \ | 
 | 			  done = EOF;					      \ | 
 | 			  goto errout;					      \ | 
 | 			}						      \ | 
 | 		    }							      \ | 
 | 		  else							      \ | 
 | 		    Str = ARG (Type *);					      \ | 
 | 		  if (Str == NULL)					      \ | 
 | 		    conv_error ();					      \ | 
 | 		} while (0) | 
 | #ifdef COMPILE_WSCANF | 
 | 	      STRING_ARG (str, char, 100); | 
 | #else | 
 | 	      STRING_ARG (str, char, (width > 1024 ? 1024 : width)); | 
 | #endif | 
 |  | 
 | 	      c = inchar (); | 
 | 	      if (__glibc_unlikely (c == EOF)) | 
 | 		input_error (); | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | 	      /* We have to convert the wide character(s) into multibyte | 
 | 		 characters and store the result.  */ | 
 | 	      memset (&state, '\0', sizeof (state)); | 
 |  | 
 | 	      do | 
 | 		{ | 
 | 		  size_t n; | 
 |  | 
 | 		  if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC) | 
 | 		      && str + MB_CUR_MAX >= *strptr + strsize) | 
 | 		    { | 
 | 		      /* We have to enlarge the buffer if the `m' flag | 
 | 			 was given.  */ | 
 | 		      size_t strleng = str - *strptr; | 
 | 		      char *newstr; | 
 |  | 
 | 		      newstr = (char *) realloc (*strptr, strsize * 2); | 
 | 		      if (newstr == NULL) | 
 | 			{ | 
 | 			  /* Can't allocate that much.  Last-ditch effort.  */ | 
 | 			  newstr = (char *) realloc (*strptr, | 
 | 						     strleng + MB_CUR_MAX); | 
 | 			  if (newstr == NULL) | 
 | 			    { | 
 | 			      /* c can't have `a' flag, only `m'.  */ | 
 | 			      done = EOF; | 
 | 			      goto errout; | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = newstr; | 
 | 			      str = newstr + strleng; | 
 | 			      strsize = strleng + MB_CUR_MAX; | 
 | 			    } | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  *strptr = newstr; | 
 | 			  str = newstr + strleng; | 
 | 			  strsize *= 2; | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); | 
 | 		  if (__glibc_unlikely (n == (size_t) -1)) | 
 | 		    /* No valid wide character.  */ | 
 | 		    input_error (); | 
 |  | 
 | 		  /* Increment the output pointer.  Even if we don't | 
 | 		     write anything.  */ | 
 | 		  str += n; | 
 | 		} | 
 | 	      while (--width > 0 && inchar () != EOF); | 
 | #else | 
 | 	      if (!(flags & SUPPRESS)) | 
 | 		{ | 
 | 		  do | 
 | 		    { | 
 | 		      if ((flags & MALLOC) | 
 | 			  && (char *) str == *strptr + strsize) | 
 | 			{ | 
 | 			  /* Enlarge the buffer.  */ | 
 | 			  size_t newsize | 
 | 			    = strsize | 
 | 			      + (strsize >= width ? width - 1 : strsize); | 
 |  | 
 | 			  str = (char *) realloc (*strptr, newsize); | 
 | 			  if (str == NULL) | 
 | 			    { | 
 | 			      /* Can't allocate that much.  Last-ditch | 
 | 				 effort.  */ | 
 | 			      str = (char *) realloc (*strptr, strsize + 1); | 
 | 			      if (str == NULL) | 
 | 				{ | 
 | 				  /* c can't have `a' flag, only `m'.  */ | 
 | 				  done = EOF; | 
 | 				  goto errout; | 
 | 				} | 
 | 			      else | 
 | 				{ | 
 | 				  *strptr = (char *) str; | 
 | 				  str += strsize; | 
 | 				  ++strsize; | 
 | 				} | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = (char *) str; | 
 | 			      str += strsize; | 
 | 			      strsize = newsize; | 
 | 			    } | 
 | 			} | 
 | 		      *str++ = c; | 
 | 		    } | 
 | 		  while (--width > 0 && inchar () != EOF); | 
 | 		} | 
 | 	      else | 
 | 		while (--width > 0 && inchar () != EOF); | 
 | #endif | 
 |  | 
 | 	      if (!(flags & SUPPRESS)) | 
 | 		{ | 
 | 		  if ((flags & MALLOC) && str - *strptr != strsize) | 
 | 		    { | 
 | 		      char *cp = (char *) realloc (*strptr, str - *strptr); | 
 | 		      if (cp != NULL) | 
 | 			*strptr = cp; | 
 | 		    } | 
 | 		  strptr = NULL; | 
 | 		  ++done; | 
 | 		} | 
 |  | 
 | 	      break; | 
 | 	    } | 
 | 	  /* FALLTHROUGH */ | 
 | 	case L_('C'): | 
 | 	  if (width == -1) | 
 | 	    width = 1; | 
 |  | 
 | 	  STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width)); | 
 |  | 
 | 	  c = inchar (); | 
 | 	  if (__glibc_unlikely (c == EOF)) | 
 | 	    input_error (); | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | 	  /* Just store the incoming wide characters.  */ | 
 | 	  if (!(flags & SUPPRESS)) | 
 | 	    { | 
 | 	      do | 
 | 		{ | 
 | 		  if ((flags & MALLOC) | 
 | 		      && wstr == (wchar_t *) *strptr + strsize) | 
 | 		    { | 
 | 		      size_t newsize | 
 | 			= strsize + (strsize > width ? width - 1 : strsize); | 
 | 		      /* Enlarge the buffer.  */ | 
 | 		      wstr = (wchar_t *) realloc (*strptr, | 
 | 						  newsize * sizeof (wchar_t)); | 
 | 		      if (wstr == NULL) | 
 | 			{ | 
 | 			  /* Can't allocate that much.  Last-ditch effort.  */ | 
 | 			  wstr = (wchar_t *) realloc (*strptr, | 
 | 						      (strsize + 1) | 
 | 						      * sizeof (wchar_t)); | 
 | 			  if (wstr == NULL) | 
 | 			    { | 
 | 			      /* C or lc can't have `a' flag, only `m' | 
 | 				 flag.  */ | 
 | 			      done = EOF; | 
 | 			      goto errout; | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = (char *) wstr; | 
 | 			      wstr += strsize; | 
 | 			      ++strsize; | 
 | 			    } | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  *strptr = (char *) wstr; | 
 | 			  wstr += strsize; | 
 | 			  strsize = newsize; | 
 | 			} | 
 | 		    } | 
 | 		  *wstr++ = c; | 
 | 		} | 
 | 	      while (--width > 0 && inchar () != EOF); | 
 | 	    } | 
 | 	  else | 
 | 	    while (--width > 0 && inchar () != EOF); | 
 | #else | 
 | 	  { | 
 | 	    /* We have to convert the multibyte input sequence to wide | 
 | 	       characters.  */ | 
 | 	    char buf[1]; | 
 | 	    mbstate_t cstate; | 
 |  | 
 | 	    memset (&cstate, '\0', sizeof (cstate)); | 
 |  | 
 | 	    do | 
 | 	      { | 
 | 		/* This is what we present the mbrtowc function first.  */ | 
 | 		buf[0] = c; | 
 |  | 
 | 		if (!(flags & SUPPRESS) && (flags & MALLOC) | 
 | 		    && wstr == (wchar_t *) *strptr + strsize) | 
 | 		  { | 
 | 		    size_t newsize | 
 | 		      = strsize + (strsize > width ? width - 1 : strsize); | 
 | 		    /* Enlarge the buffer.  */ | 
 | 		    wstr = (wchar_t *) realloc (*strptr, | 
 | 						newsize * sizeof (wchar_t)); | 
 | 		    if (wstr == NULL) | 
 | 		      { | 
 | 			/* Can't allocate that much.  Last-ditch effort.  */ | 
 | 			wstr = (wchar_t *) realloc (*strptr, | 
 | 						    ((strsize + 1) | 
 | 						     * sizeof (wchar_t))); | 
 | 			if (wstr == NULL) | 
 | 			  { | 
 | 			    /* C or lc can't have `a' flag, only `m' flag.  */ | 
 | 			    done = EOF; | 
 | 			    goto errout; | 
 | 			  } | 
 | 			else | 
 | 			  { | 
 | 			    *strptr = (char *) wstr; | 
 | 			    wstr += strsize; | 
 | 			    ++strsize; | 
 | 			  } | 
 | 		      } | 
 | 		    else | 
 | 		      { | 
 | 			*strptr = (char *) wstr; | 
 | 			wstr += strsize; | 
 | 			strsize = newsize; | 
 | 		      } | 
 | 		  } | 
 |  | 
 | 		while (1) | 
 | 		  { | 
 | 		    size_t n; | 
 |  | 
 | 		    n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL, | 
 | 				   buf, 1, &cstate); | 
 |  | 
 | 		    if (n == (size_t) -2) | 
 | 		      { | 
 | 			/* Possibly correct character, just not enough | 
 | 			   input.  */ | 
 | 			if (__glibc_unlikely (inchar () == EOF)) | 
 | 			  encode_error (); | 
 |  | 
 | 			buf[0] = c; | 
 | 			continue; | 
 | 		      } | 
 |  | 
 | 		    if (__glibc_unlikely (n != 1)) | 
 | 		      encode_error (); | 
 |  | 
 | 		    /* We have a match.  */ | 
 | 		    break; | 
 | 		  } | 
 |  | 
 | 		/* Advance the result pointer.  */ | 
 | 		++wstr; | 
 | 	      } | 
 | 	    while (--width > 0 && inchar () != EOF); | 
 | 	  } | 
 | #endif | 
 |  | 
 | 	  if (!(flags & SUPPRESS)) | 
 | 	    { | 
 | 	      if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize) | 
 | 		{ | 
 | 		  wchar_t *cp = (wchar_t *) realloc (*strptr, | 
 | 						     ((wstr | 
 | 						       - (wchar_t *) *strptr) | 
 | 						      * sizeof (wchar_t))); | 
 | 		  if (cp != NULL) | 
 | 		    *strptr = (char *) cp; | 
 | 		} | 
 | 	      strptr = NULL; | 
 |  | 
 | 	      ++done; | 
 | 	    } | 
 |  | 
 | 	  break; | 
 |  | 
 | 	case L_('s'):		/* Read a string.  */ | 
 | 	  if (!(flags & LONG)) | 
 | 	    { | 
 | 	      STRING_ARG (str, char, 100); | 
 |  | 
 | 	      c = inchar (); | 
 | 	      if (__glibc_unlikely (c == EOF)) | 
 | 		input_error (); | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | 	      memset (&state, '\0', sizeof (state)); | 
 | #endif | 
 |  | 
 | 	      do | 
 | 		{ | 
 | 		  if (ISSPACE (c)) | 
 | 		    { | 
 | 		      ungetc_not_eof (c, s); | 
 | 		      break; | 
 | 		    } | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | 		  /* This is quite complicated.  We have to convert the | 
 | 		     wide characters into multibyte characters and then | 
 | 		     store them.  */ | 
 | 		  { | 
 | 		    size_t n; | 
 |  | 
 | 		    if (!(flags & SUPPRESS) && (flags & MALLOC) | 
 | 			&& str + MB_CUR_MAX >= *strptr + strsize) | 
 | 		      { | 
 | 			/* We have to enlarge the buffer if the `a' or `m' | 
 | 			   flag was given.  */ | 
 | 			size_t strleng = str - *strptr; | 
 | 			char *newstr; | 
 |  | 
 | 			newstr = (char *) realloc (*strptr, strsize * 2); | 
 | 			if (newstr == NULL) | 
 | 			  { | 
 | 			    /* Can't allocate that much.  Last-ditch | 
 | 			       effort.  */ | 
 | 			    newstr = (char *) realloc (*strptr, | 
 | 						       strleng + MB_CUR_MAX); | 
 | 			    if (newstr == NULL) | 
 | 			      { | 
 | 				if (flags & POSIX_MALLOC) | 
 | 				  { | 
 | 				    done = EOF; | 
 | 				    goto errout; | 
 | 				  } | 
 | 				/* We lose.  Oh well.  Terminate the | 
 | 				   string and stop converting, | 
 | 				   so at least we don't skip any input.  */ | 
 | 				((char *) (*strptr))[strleng] = '\0'; | 
 | 				strptr = NULL; | 
 | 				++done; | 
 | 				conv_error (); | 
 | 			      } | 
 | 			    else | 
 | 			      { | 
 | 				*strptr = newstr; | 
 | 				str = newstr + strleng; | 
 | 				strsize = strleng + MB_CUR_MAX; | 
 | 			      } | 
 | 			  } | 
 | 			else | 
 | 			  { | 
 | 			    *strptr = newstr; | 
 | 			    str = newstr + strleng; | 
 | 			    strsize *= 2; | 
 | 			  } | 
 | 		      } | 
 |  | 
 | 		    n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, | 
 | 				   &state); | 
 | 		    if (__glibc_unlikely (n == (size_t) -1)) | 
 | 		      encode_error (); | 
 |  | 
 | 		    assert (n <= MB_CUR_MAX); | 
 | 		    str += n; | 
 | 		  } | 
 | #else | 
 | 		  /* This is easy.  */ | 
 | 		  if (!(flags & SUPPRESS)) | 
 | 		    { | 
 | 		      *str++ = c; | 
 | 		      if ((flags & MALLOC) | 
 | 			  && (char *) str == *strptr + strsize) | 
 | 			{ | 
 | 			  /* Enlarge the buffer.  */ | 
 | 			  str = (char *) realloc (*strptr, 2 * strsize); | 
 | 			  if (str == NULL) | 
 | 			    { | 
 | 			      /* Can't allocate that much.  Last-ditch | 
 | 				 effort.  */ | 
 | 			      str = (char *) realloc (*strptr, strsize + 1); | 
 | 			      if (str == NULL) | 
 | 				{ | 
 | 				  if (flags & POSIX_MALLOC) | 
 | 				    { | 
 | 				      done = EOF; | 
 | 				      goto errout; | 
 | 				    } | 
 | 				  /* We lose.  Oh well.  Terminate the | 
 | 				     string and stop converting, | 
 | 				     so at least we don't skip any input.  */ | 
 | 				  ((char *) (*strptr))[strsize - 1] = '\0'; | 
 | 				  strptr = NULL; | 
 | 				  ++done; | 
 | 				  conv_error (); | 
 | 				} | 
 | 			      else | 
 | 				{ | 
 | 				  *strptr = (char *) str; | 
 | 				  str += strsize; | 
 | 				  ++strsize; | 
 | 				} | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = (char *) str; | 
 | 			      str += strsize; | 
 | 			      strsize *= 2; | 
 | 			    } | 
 | 			} | 
 | 		    } | 
 | #endif | 
 | 		} | 
 | 	      while ((width <= 0 || --width > 0) && inchar () != EOF); | 
 |  | 
 | 	      if (!(flags & SUPPRESS)) | 
 | 		{ | 
 | #ifdef COMPILE_WSCANF | 
 | 		  /* We have to emit the code to get into the initial | 
 | 		     state.  */ | 
 | 		  char buf[MB_LEN_MAX]; | 
 | 		  size_t n = __wcrtomb (buf, L'\0', &state); | 
 | 		  if (n > 0 && (flags & MALLOC) | 
 | 		      && str + n >= *strptr + strsize) | 
 | 		    { | 
 | 		      /* Enlarge the buffer.  */ | 
 | 		      size_t strleng = str - *strptr; | 
 | 		      char *newstr; | 
 |  | 
 | 		      newstr = (char *) realloc (*strptr, strleng + n + 1); | 
 | 		      if (newstr == NULL) | 
 | 			{ | 
 | 			  if (flags & POSIX_MALLOC) | 
 | 			    { | 
 | 			      done = EOF; | 
 | 			      goto errout; | 
 | 			    } | 
 | 			  /* We lose.  Oh well.  Terminate the string | 
 | 			     and stop converting, so at least we don't | 
 | 			     skip any input.  */ | 
 | 			  ((char *) (*strptr))[strleng] = '\0'; | 
 | 			  strptr = NULL; | 
 | 			  ++done; | 
 | 			  conv_error (); | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  *strptr = newstr; | 
 | 			  str = newstr + strleng; | 
 | 			  strsize = strleng + n + 1; | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  str = __mempcpy (str, buf, n); | 
 | #endif | 
 | 		  *str++ = '\0'; | 
 |  | 
 | 		  if ((flags & MALLOC) && str - *strptr != strsize) | 
 | 		    { | 
 | 		      char *cp = (char *) realloc (*strptr, str - *strptr); | 
 | 		      if (cp != NULL) | 
 | 			*strptr = cp; | 
 | 		    } | 
 | 		  strptr = NULL; | 
 |  | 
 | 		  ++done; | 
 | 		} | 
 | 	      break; | 
 | 	    } | 
 | 	  /* FALLTHROUGH */ | 
 |  | 
 | 	case L_('S'): | 
 | 	  { | 
 | #ifndef COMPILE_WSCANF | 
 | 	    mbstate_t cstate; | 
 | #endif | 
 |  | 
 | 	    /* Wide character string.  */ | 
 | 	    STRING_ARG (wstr, wchar_t, 100); | 
 |  | 
 | 	    c = inchar (); | 
 | 	    if (__builtin_expect (c == EOF,  0)) | 
 | 	      input_error (); | 
 |  | 
 | #ifndef COMPILE_WSCANF | 
 | 	    memset (&cstate, '\0', sizeof (cstate)); | 
 | #endif | 
 |  | 
 | 	    do | 
 | 	      { | 
 | 		if (ISSPACE (c)) | 
 | 		  { | 
 | 		    ungetc_not_eof (c, s); | 
 | 		    break; | 
 | 		  } | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | 		/* This is easy.  */ | 
 | 		if (!(flags & SUPPRESS)) | 
 | 		  { | 
 | 		    *wstr++ = c; | 
 | 		    if ((flags & MALLOC) | 
 | 			&& wstr == (wchar_t *) *strptr + strsize) | 
 | 		      { | 
 | 			/* Enlarge the buffer.  */ | 
 | 			wstr = (wchar_t *) realloc (*strptr, | 
 | 						    (2 * strsize) | 
 | 						    * sizeof (wchar_t)); | 
 | 			if (wstr == NULL) | 
 | 			  { | 
 | 			    /* Can't allocate that much.  Last-ditch | 
 | 			       effort.  */ | 
 | 			    wstr = (wchar_t *) realloc (*strptr, | 
 | 							(strsize + 1) | 
 | 							* sizeof (wchar_t)); | 
 | 			    if (wstr == NULL) | 
 | 			      { | 
 | 				if (flags & POSIX_MALLOC) | 
 | 				  { | 
 | 				    done = EOF; | 
 | 				    goto errout; | 
 | 				  } | 
 | 				/* We lose.  Oh well.  Terminate the string | 
 | 				   and stop converting, so at least we don't | 
 | 				   skip any input.  */ | 
 | 				((wchar_t *) (*strptr))[strsize - 1] = L'\0'; | 
 | 				strptr = NULL; | 
 | 				++done; | 
 | 				conv_error (); | 
 | 			      } | 
 | 			    else | 
 | 			      { | 
 | 				*strptr = (char *) wstr; | 
 | 				wstr += strsize; | 
 | 				++strsize; | 
 | 			      } | 
 | 			  } | 
 | 			else | 
 | 			  { | 
 | 			    *strptr = (char *) wstr; | 
 | 			    wstr += strsize; | 
 | 			    strsize *= 2; | 
 | 			  } | 
 | 		      } | 
 | 		  } | 
 | #else | 
 | 		{ | 
 | 		  char buf[1]; | 
 |  | 
 | 		  buf[0] = c; | 
 |  | 
 | 		  while (1) | 
 | 		    { | 
 | 		      size_t n; | 
 |  | 
 | 		      n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL, | 
 | 				     buf, 1, &cstate); | 
 |  | 
 | 		      if (n == (size_t) -2) | 
 | 			{ | 
 | 			  /* Possibly correct character, just not enough | 
 | 			     input.  */ | 
 | 			  if (__glibc_unlikely (inchar () == EOF)) | 
 | 			    encode_error (); | 
 |  | 
 | 			  buf[0] = c; | 
 | 			  continue; | 
 | 			} | 
 |  | 
 | 		      if (__glibc_unlikely (n != 1)) | 
 | 			encode_error (); | 
 |  | 
 | 		      /* We have a match.  */ | 
 | 		      ++wstr; | 
 | 		      break; | 
 | 		    } | 
 |  | 
 | 		  if (!(flags & SUPPRESS) && (flags & MALLOC) | 
 | 		      && wstr == (wchar_t *) *strptr + strsize) | 
 | 		    { | 
 | 		      /* Enlarge the buffer.  */ | 
 | 		      wstr = (wchar_t *) realloc (*strptr, | 
 | 						  (2 * strsize | 
 | 						   * sizeof (wchar_t))); | 
 | 		      if (wstr == NULL) | 
 | 			{ | 
 | 			  /* Can't allocate that much.  Last-ditch effort.  */ | 
 | 			  wstr = (wchar_t *) realloc (*strptr, | 
 | 						      ((strsize + 1) | 
 | 						       * sizeof (wchar_t))); | 
 | 			  if (wstr == NULL) | 
 | 			    { | 
 | 			      if (flags & POSIX_MALLOC) | 
 | 				{ | 
 | 				  done = EOF; | 
 | 				  goto errout; | 
 | 				} | 
 | 			      /* We lose.  Oh well.  Terminate the | 
 | 				 string and stop converting, so at | 
 | 				 least we don't skip any input.  */ | 
 | 			      ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; | 
 | 			      strptr = NULL; | 
 | 			      ++done; | 
 | 			      conv_error (); | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = (char *) wstr; | 
 | 			      wstr += strsize; | 
 | 			      ++strsize; | 
 | 			    } | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  *strptr = (char *) wstr; | 
 | 			  wstr += strsize; | 
 | 			  strsize *= 2; | 
 | 			} | 
 | 		    } | 
 | 		} | 
 | #endif | 
 | 	      } | 
 | 	    while ((width <= 0 || --width > 0) && inchar () != EOF); | 
 |  | 
 | 	    if (!(flags & SUPPRESS)) | 
 | 	      { | 
 | 		*wstr++ = L'\0'; | 
 |  | 
 | 		if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize) | 
 | 		  { | 
 | 		    wchar_t *cp = (wchar_t *) realloc (*strptr, | 
 | 						       ((wstr | 
 | 							 - (wchar_t *) *strptr) | 
 | 							* sizeof(wchar_t))); | 
 | 		    if (cp != NULL) | 
 | 		      *strptr = (char *) cp; | 
 | 		  } | 
 | 		strptr = NULL; | 
 |  | 
 | 		++done; | 
 | 	      } | 
 | 	  } | 
 | 	  break; | 
 |  | 
 | 	case L_('x'):	/* Hexadecimal integer.  */ | 
 | 	case L_('X'):	/* Ditto.  */ | 
 | 	  base = 16; | 
 | 	  goto number; | 
 |  | 
 | 	case L_('o'):	/* Octal integer.  */ | 
 | 	  base = 8; | 
 | 	  goto number; | 
 |  | 
 | 	case L_('u'):	/* Unsigned decimal integer.  */ | 
 | 	  base = 10; | 
 | 	  goto number; | 
 |  | 
 | 	case L_('d'):	/* Signed decimal integer.  */ | 
 | 	  base = 10; | 
 | 	  flags |= NUMBER_SIGNED; | 
 | 	  goto number; | 
 |  | 
 | 	case L_('i'):	/* Generic number.  */ | 
 | 	  base = 0; | 
 | 	  flags |= NUMBER_SIGNED; | 
 |  | 
 | 	number: | 
 | 	  c = inchar (); | 
 | 	  if (__glibc_unlikely (c == EOF)) | 
 | 	    input_error (); | 
 |  | 
 | 	  /* Check for a sign.  */ | 
 | 	  if (c == L_('-') || c == L_('+')) | 
 | 	    { | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	      c = inchar (); | 
 | 	    } | 
 |  | 
 | 	  /* Look for a leading indication of base.  */ | 
 | 	  if (width != 0 && c == L_('0')) | 
 | 	    { | 
 | 	      if (width > 0) | 
 | 		--width; | 
 |  | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      c = inchar (); | 
 |  | 
 | 	      if (width != 0 && TOLOWER (c) == L_('x')) | 
 | 		{ | 
 | 		  if (base == 0) | 
 | 		    base = 16; | 
 | 		  if (base == 16) | 
 | 		    { | 
 | 		      if (width > 0) | 
 | 			--width; | 
 | 		      c = inchar (); | 
 | 		    } | 
 | 		} | 
 | 	      else if (base == 0) | 
 | 		base = 8; | 
 | 	    } | 
 |  | 
 | 	  if (base == 0) | 
 | 	    base = 10; | 
 |  | 
 | 	  if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0)) | 
 | 	    { | 
 | 	      int from_level; | 
 | 	      int to_level; | 
 | 	      int level; | 
 | #ifdef COMPILE_WSCANF | 
 | 	      const wchar_t *wcdigits[10]; | 
 | 	      const wchar_t *wcdigits_extended[10]; | 
 | #else | 
 | 	      const char *mbdigits[10]; | 
 | 	      const char *mbdigits_extended[10]; | 
 | #endif | 
 | 	      /*  "to_inpunct" is a map from ASCII digits to their | 
 | 		  equivalent in locale. This is defined for locales | 
 | 		  which use an extra digits set.  */ | 
 | 	      wctrans_t map = __wctrans ("to_inpunct"); | 
 | 	      int n; | 
 |  | 
 | 	      from_level = 0; | 
 | #ifdef COMPILE_WSCANF | 
 | 	      to_level = _NL_CURRENT_WORD (LC_CTYPE, | 
 | 					   _NL_CTYPE_INDIGITS_WC_LEN) - 1; | 
 | #else | 
 | 	      to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1; | 
 | #endif | 
 |  | 
 | 	      /* Get the alternative digit forms if there are any.  */ | 
 | 	      if (__glibc_unlikely (map != NULL)) | 
 | 		{ | 
 | 		  /*  Adding new level for extra digits set in locale file.  */ | 
 | 		  ++to_level; | 
 |  | 
 | 		  for (n = 0; n < 10; ++n) | 
 | 		    { | 
 | #ifdef COMPILE_WSCANF | 
 | 		      wcdigits[n] = (const wchar_t *) | 
 | 			_NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n); | 
 |  | 
 | 		      wchar_t *wc_extended = (wchar_t *) | 
 | 			alloca ((to_level + 2) * sizeof (wchar_t)); | 
 | 		      __wmemcpy (wc_extended, wcdigits[n], to_level); | 
 | 		      wc_extended[to_level] = __towctrans (L'0' + n, map); | 
 | 		      wc_extended[to_level + 1] = '\0'; | 
 | 		      wcdigits_extended[n] = wc_extended; | 
 | #else | 
 | 		      mbdigits[n] | 
 | 			= curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string; | 
 |  | 
 | 		      /*  Get the equivalent wide char in map.  */ | 
 | 		      wint_t extra_wcdigit = __towctrans (L'0' + n, map); | 
 |  | 
 | 		      /*  Convert it to multibyte representation.  */ | 
 | 		      mbstate_t state; | 
 | 		      memset (&state, '\0', sizeof (state)); | 
 |  | 
 | 		      char extra_mbdigit[MB_LEN_MAX]; | 
 | 		      size_t mblen | 
 | 			= __wcrtomb (extra_mbdigit, extra_wcdigit, &state); | 
 |  | 
 | 		      if (mblen == (size_t) -1) | 
 | 			{ | 
 | 			  /*  Ignore this new level.  */ | 
 | 			  map = NULL; | 
 | 			  break; | 
 | 			} | 
 |  | 
 | 		      /*  Calculate the length of mbdigits[n].  */ | 
 | 		      const char *last_char = mbdigits[n]; | 
 | 		      for (level = 0; level < to_level; ++level) | 
 | 			last_char = strchr (last_char, '\0') + 1; | 
 |  | 
 | 		      size_t mbdigits_len = last_char - mbdigits[n]; | 
 |  | 
 | 		      /*  Allocate memory for extended multibyte digit.  */ | 
 | 		      char *mb_extended; | 
 | 		      mb_extended = (char *) alloca (mbdigits_len + mblen + 1); | 
 |  | 
 | 		      /*  And get the mbdigits + extra_digit string.  */ | 
 | 		      *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n], | 
 | 						      mbdigits_len), | 
 | 					   extra_mbdigit, mblen) = '\0'; | 
 | 		      mbdigits_extended[n] = mb_extended; | 
 | #endif | 
 | 		    } | 
 | 		} | 
 |  | 
 | 	      /* Read the number into workspace.  */ | 
 | 	      while (c != EOF && width != 0) | 
 | 		{ | 
 | 		  /* In this round we get the pointer to the digit strings | 
 | 		     and also perform the first round of comparisons.  */ | 
 | 		  for (n = 0; n < 10; ++n) | 
 | 		    { | 
 | 		      /* Get the string for the digits with value N.  */ | 
 | #ifdef COMPILE_WSCANF | 
 |  | 
 | 		      /* wcdigits_extended[] is fully set in the loop | 
 | 			 above, but the test for "map != NULL" is done | 
 | 			 inside the loop here and outside the loop there.  */ | 
 | 		      DIAG_PUSH_NEEDS_COMMENT; | 
 | 		      DIAG_IGNORE_NEEDS_COMMENT (4.7, "-Wmaybe-uninitialized"); | 
 |  | 
 | 		      if (__glibc_unlikely (map != NULL)) | 
 | 			wcdigits[n] = wcdigits_extended[n]; | 
 | 		      else | 
 | 			wcdigits[n] = (const wchar_t *) | 
 | 			  _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n); | 
 | 		      wcdigits[n] += from_level; | 
 |  | 
 | 		      DIAG_POP_NEEDS_COMMENT; | 
 |  | 
 | 		      if (c == (wint_t) *wcdigits[n]) | 
 | 			{ | 
 | 			  to_level = from_level; | 
 | 			  break; | 
 | 			} | 
 |  | 
 | 		      /* Advance the pointer to the next string.  */ | 
 | 		      ++wcdigits[n]; | 
 | #else | 
 | 		      const char *cmpp; | 
 | 		      int avail = width > 0 ? width : INT_MAX; | 
 |  | 
 | 		      if (__glibc_unlikely (map != NULL)) | 
 | 			mbdigits[n] = mbdigits_extended[n]; | 
 | 		      else | 
 | 			mbdigits[n] | 
 | 			  = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string; | 
 |  | 
 | 		      for (level = 0; level < from_level; level++) | 
 | 			mbdigits[n] = strchr (mbdigits[n], '\0') + 1; | 
 |  | 
 | 		      cmpp = mbdigits[n]; | 
 | 		      while ((unsigned char) *cmpp == c && avail >= 0) | 
 | 			{ | 
 | 			  if (*++cmpp == '\0') | 
 | 			    break; | 
 | 			  else | 
 | 			    { | 
 | 			      if (avail == 0 || inchar () == EOF) | 
 | 				break; | 
 | 			      --avail; | 
 | 			    } | 
 | 			} | 
 |  | 
 | 		      if (*cmpp == '\0') | 
 | 			{ | 
 | 			  if (width > 0) | 
 | 			    width = avail; | 
 | 			  to_level = from_level; | 
 | 			  break; | 
 | 			} | 
 |  | 
 | 		      /* We are pushing all read characters back.  */ | 
 | 		      if (cmpp > mbdigits[n]) | 
 | 			{ | 
 | 			  ungetc (c, s); | 
 | 			  while (--cmpp > mbdigits[n]) | 
 | 			    ungetc_not_eof ((unsigned char) *cmpp, s); | 
 | 			  c = (unsigned char) *cmpp; | 
 | 			} | 
 |  | 
 | 		      /* Advance the pointer to the next string.  */ | 
 | 		      mbdigits[n] = strchr (mbdigits[n], '\0') + 1; | 
 | #endif | 
 | 		    } | 
 |  | 
 | 		  if (n == 10) | 
 | 		    { | 
 | 		      /* Have not yet found the digit.  */ | 
 | 		      for (level = from_level + 1; level <= to_level; ++level) | 
 | 			{ | 
 | 			  /* Search all ten digits of this level.  */ | 
 | 			  for (n = 0; n < 10; ++n) | 
 | 			    { | 
 | #ifdef COMPILE_WSCANF | 
 | 			      if (c == (wint_t) *wcdigits[n]) | 
 | 				break; | 
 |  | 
 | 			      /* Advance the pointer to the next string.  */ | 
 | 			      ++wcdigits[n]; | 
 | #else | 
 | 			      const char *cmpp; | 
 | 			      int avail = width > 0 ? width : INT_MAX; | 
 |  | 
 | 			      cmpp = mbdigits[n]; | 
 | 			      while ((unsigned char) *cmpp == c && avail >= 0) | 
 | 				{ | 
 | 				  if (*++cmpp == '\0') | 
 | 				    break; | 
 | 				  else | 
 | 				    { | 
 | 				      if (avail == 0 || inchar () == EOF) | 
 | 					break; | 
 | 				      --avail; | 
 | 				    } | 
 | 				} | 
 |  | 
 | 			      if (*cmpp == '\0') | 
 | 				{ | 
 | 				  if (width > 0) | 
 | 				    width = avail; | 
 | 				  break; | 
 | 				} | 
 |  | 
 | 			      /* We are pushing all read characters back.  */ | 
 | 			      if (cmpp > mbdigits[n]) | 
 | 				{ | 
 | 				  ungetc (c, s); | 
 | 				  while (--cmpp > mbdigits[n]) | 
 | 				    ungetc_not_eof ((unsigned char) *cmpp, s); | 
 | 				  c = (unsigned char) *cmpp; | 
 | 				} | 
 |  | 
 | 			      /* Advance the pointer to the next string.  */ | 
 | 			      mbdigits[n] = strchr (mbdigits[n], '\0') + 1; | 
 | #endif | 
 | 			    } | 
 |  | 
 | 			  if (n < 10) | 
 | 			    { | 
 | 			      /* Found it.  */ | 
 | 			      from_level = level; | 
 | 			      to_level = level; | 
 | 			      break; | 
 | 			    } | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  if (n < 10) | 
 | 		    c = L_('0') + n; | 
 | 		  else if (flags & GROUP) | 
 | 		    { | 
 | 		      /* Try matching against the thousands separator.  */ | 
 | #ifdef COMPILE_WSCANF | 
 | 		      if (c != thousands) | 
 | 			  break; | 
 | #else | 
 | 		      const char *cmpp = thousands; | 
 | 		      int avail = width > 0 ? width : INT_MAX; | 
 |  | 
 | 		      while ((unsigned char) *cmpp == c && avail >= 0) | 
 | 			{ | 
 | 			  char_buffer_add (&charbuf, c); | 
 | 			  if (*++cmpp == '\0') | 
 | 			    break; | 
 | 			  else | 
 | 			    { | 
 | 			      if (avail == 0 || inchar () == EOF) | 
 | 				break; | 
 | 			      --avail; | 
 | 			    } | 
 | 			} | 
 |  | 
 | 		      if (char_buffer_error (&charbuf)) | 
 | 			{ | 
 | 			  __set_errno (ENOMEM); | 
 | 			  done = EOF; | 
 | 			  goto errout; | 
 | 			} | 
 |  | 
 | 		      if (*cmpp != '\0') | 
 | 			{ | 
 | 			  /* We are pushing all read characters back.  */ | 
 | 			  if (cmpp > thousands) | 
 | 			    { | 
 | 			      charbuf.current -= cmpp - thousands; | 
 | 			      ungetc (c, s); | 
 | 			      while (--cmpp > thousands) | 
 | 				ungetc_not_eof ((unsigned char) *cmpp, s); | 
 | 			      c = (unsigned char) *cmpp; | 
 | 			    } | 
 | 			  break; | 
 | 			} | 
 |  | 
 | 		      if (width > 0) | 
 | 			width = avail; | 
 |  | 
 | 		      /* The last thousands character will be added back by | 
 | 			 the char_buffer_add below.  */ | 
 | 		      --charbuf.current; | 
 | #endif | 
 | 		    } | 
 | 		  else | 
 | 		    break; | 
 |  | 
 | 		  char_buffer_add (&charbuf, c); | 
 | 		  if (width > 0) | 
 | 		    --width; | 
 |  | 
 | 		  c = inchar (); | 
 | 		} | 
 | 	    } | 
 | 	  else | 
 | 	    /* Read the number into workspace.  */ | 
 | 	    while (c != EOF && width != 0) | 
 | 	      { | 
 | 		if (base == 16) | 
 | 		  { | 
 | 		    if (!ISXDIGIT (c)) | 
 | 		      break; | 
 | 		  } | 
 | 		else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base) | 
 | 		  { | 
 | 		    if (base == 10 && (flags & GROUP)) | 
 | 		      { | 
 | 			/* Try matching against the thousands separator.  */ | 
 | #ifdef COMPILE_WSCANF | 
 | 			if (c != thousands) | 
 | 			  break; | 
 | #else | 
 | 			const char *cmpp = thousands; | 
 | 			int avail = width > 0 ? width : INT_MAX; | 
 |  | 
 | 			while ((unsigned char) *cmpp == c && avail >= 0) | 
 | 			  { | 
 | 			    char_buffer_add (&charbuf, c); | 
 | 			    if (*++cmpp == '\0') | 
 | 			      break; | 
 | 			    else | 
 | 			      { | 
 | 				if (avail == 0 || inchar () == EOF) | 
 | 				  break; | 
 | 				--avail; | 
 | 			      } | 
 | 			  } | 
 |  | 
 | 			if (char_buffer_error (&charbuf)) | 
 | 			  { | 
 | 			    __set_errno (ENOMEM); | 
 | 			    done = EOF; | 
 | 			    goto errout; | 
 | 			  } | 
 |  | 
 | 			if (*cmpp != '\0') | 
 | 			  { | 
 | 			    /* We are pushing all read characters back.  */ | 
 | 			    if (cmpp > thousands) | 
 | 			      { | 
 | 				charbuf.current -= cmpp - thousands; | 
 | 				ungetc (c, s); | 
 | 				while (--cmpp > thousands) | 
 | 				  ungetc_not_eof ((unsigned char) *cmpp, s); | 
 | 				c = (unsigned char) *cmpp; | 
 | 			      } | 
 | 			    break; | 
 | 			  } | 
 |  | 
 | 			if (width > 0) | 
 | 			  width = avail; | 
 |  | 
 | 			/* The last thousands character will be added back by | 
 | 			   the char_buffer_add below.  */ | 
 | 			--charbuf.current; | 
 | #endif | 
 | 		      } | 
 | 		    else | 
 | 		      break; | 
 | 		  } | 
 | 		char_buffer_add (&charbuf, c); | 
 | 		if (width > 0) | 
 | 		  --width; | 
 |  | 
 | 		c = inchar (); | 
 | 	      } | 
 |  | 
 | 	  if (char_buffer_error (&charbuf)) | 
 | 	    { | 
 | 	      __set_errno (ENOMEM); | 
 | 	      done = EOF; | 
 | 	      goto errout; | 
 | 	    } | 
 |  | 
 | 	  if (char_buffer_size (&charbuf) == 0 | 
 | 	      || (char_buffer_size (&charbuf) == 1 | 
 | 		  && (char_buffer_start (&charbuf)[0] == L_('+') | 
 | 		      || char_buffer_start (&charbuf)[0] == L_('-')))) | 
 | 	    { | 
 | 	      /* There was no number.  If we are supposed to read a pointer | 
 | 		 we must recognize "(nil)" as well.  */ | 
 | 	      if (__builtin_expect (char_buffer_size (&charbuf) == 0 | 
 | 				    && (flags & READ_POINTER) | 
 | 				    && (width < 0 || width >= 5) | 
 | 				    && c == '(' | 
 | 				    && TOLOWER (inchar ()) == L_('n') | 
 | 				    && TOLOWER (inchar ()) == L_('i') | 
 | 				    && TOLOWER (inchar ()) == L_('l') | 
 | 				    && inchar () == L_(')'), 1)) | 
 | 		/* We must produce the value of a NULL pointer.  A single | 
 | 		   '0' digit is enough.  */ | 
 | 		  char_buffer_add (&charbuf, L_('0')); | 
 | 	      else | 
 | 		{ | 
 | 		  /* The last read character is not part of the number | 
 | 		     anymore.  */ | 
 | 		  ungetc (c, s); | 
 |  | 
 | 		  conv_error (); | 
 | 		} | 
 | 	    } | 
 | 	  else | 
 | 	    /* The just read character is not part of the number anymore.  */ | 
 | 	    ungetc (c, s); | 
 |  | 
 | 	  /* Convert the number.  */ | 
 | 	  char_buffer_add (&charbuf, L_('\0')); | 
 | 	  if (char_buffer_error (&charbuf)) | 
 | 	    { | 
 | 	      __set_errno (ENOMEM); | 
 | 	      done = EOF; | 
 | 	      goto errout; | 
 | 	    } | 
 | 	  if (need_longlong && (flags & LONGDBL)) | 
 | 	    { | 
 | 	      if (flags & NUMBER_SIGNED) | 
 | 		num.q = __strtoll_internal | 
 | 		  (char_buffer_start (&charbuf), &tw, base, flags & GROUP); | 
 | 	      else | 
 | 		num.uq = __strtoull_internal | 
 | 		  (char_buffer_start (&charbuf), &tw, base, flags & GROUP); | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      if (flags & NUMBER_SIGNED) | 
 | 		num.l = __strtol_internal | 
 | 		  (char_buffer_start (&charbuf), &tw, base, flags & GROUP); | 
 | 	      else | 
 | 		num.ul = __strtoul_internal | 
 | 		  (char_buffer_start (&charbuf), &tw, base, flags & GROUP); | 
 | 	    } | 
 | 	  if (__glibc_unlikely (char_buffer_start (&charbuf) == tw)) | 
 | 	    conv_error (); | 
 |  | 
 | 	  if (!(flags & SUPPRESS)) | 
 | 	    { | 
 | 	      if (flags & NUMBER_SIGNED) | 
 | 		{ | 
 | 		  if (need_longlong && (flags & LONGDBL)) | 
 | 		    *ARG (LONGLONG int *) = num.q; | 
 | 		  else if (need_long && (flags & LONG)) | 
 | 		    *ARG (long int *) = num.l; | 
 | 		  else if (flags & SHORT) | 
 | 		    *ARG (short int *) = (short int) num.l; | 
 | 		  else if (!(flags & CHAR)) | 
 | 		    *ARG (int *) = (int) num.l; | 
 | 		  else | 
 | 		    *ARG (signed char *) = (signed char) num.ul; | 
 | 		} | 
 | 	      else | 
 | 		{ | 
 | 		  if (need_longlong && (flags & LONGDBL)) | 
 | 		    *ARG (unsigned LONGLONG int *) = num.uq; | 
 | 		  else if (need_long && (flags & LONG)) | 
 | 		    *ARG (unsigned long int *) = num.ul; | 
 | 		  else if (flags & SHORT) | 
 | 		    *ARG (unsigned short int *) | 
 | 		      = (unsigned short int) num.ul; | 
 | 		  else if (!(flags & CHAR)) | 
 | 		    *ARG (unsigned int *) = (unsigned int) num.ul; | 
 | 		  else | 
 | 		    *ARG (unsigned char *) = (unsigned char) num.ul; | 
 | 		} | 
 | 	      ++done; | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case L_('e'):	/* Floating-point numbers.  */ | 
 | 	case L_('E'): | 
 | 	case L_('f'): | 
 | 	case L_('F'): | 
 | 	case L_('g'): | 
 | 	case L_('G'): | 
 | 	case L_('a'): | 
 | 	case L_('A'): | 
 | 	  c = inchar (); | 
 | 	  if (width > 0) | 
 | 	    --width; | 
 | 	  if (__glibc_unlikely (c == EOF)) | 
 | 	    input_error (); | 
 |  | 
 | 	  got_digit = got_dot = got_e = 0; | 
 |  | 
 | 	  /* Check for a sign.  */ | 
 | 	  if (c == L_('-') || c == L_('+')) | 
 | 	    { | 
 | 	      negative = c == L_('-'); | 
 | 	      if (__glibc_unlikely (width == 0 || inchar () == EOF)) | 
 | 		/* EOF is only an input error before we read any chars.  */ | 
 | 		conv_error (); | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	    } | 
 | 	  else | 
 | 	    negative = 0; | 
 |  | 
 | 	  /* Take care for the special arguments "nan" and "inf".  */ | 
 | 	  if (TOLOWER (c) == L_('n')) | 
 | 	    { | 
 | 	      /* Maybe "nan".  */ | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      if (__builtin_expect (width == 0 | 
 | 				    || inchar () == EOF | 
 | 				    || TOLOWER (c) != L_('a'), 0)) | 
 | 		conv_error (); | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      if (__builtin_expect (width == 0 | 
 | 				    || inchar () == EOF | 
 | 				    || TOLOWER (c) != L_('n'), 0)) | 
 | 		conv_error (); | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      /* It is "nan".  */ | 
 | 	      goto scan_float; | 
 | 	    } | 
 | 	  else if (TOLOWER (c) == L_('i')) | 
 | 	    { | 
 | 	      /* Maybe "inf" or "infinity".  */ | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      if (__builtin_expect (width == 0 | 
 | 				    || inchar () == EOF | 
 | 				    || TOLOWER (c) != L_('n'), 0)) | 
 | 		conv_error (); | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      if (__builtin_expect (width == 0 | 
 | 				    || inchar () == EOF | 
 | 				    || TOLOWER (c) != L_('f'), 0)) | 
 | 		conv_error (); | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      /* It is as least "inf".  */ | 
 | 	      if (width != 0 && inchar () != EOF) | 
 | 		{ | 
 | 		  if (TOLOWER (c) == L_('i')) | 
 | 		    { | 
 | 		      if (width > 0) | 
 | 			--width; | 
 | 		      /* Now we have to read the rest as well.  */ | 
 | 		      char_buffer_add (&charbuf, c); | 
 | 		      if (__builtin_expect (width == 0 | 
 | 					    || inchar () == EOF | 
 | 					    || TOLOWER (c) != L_('n'), 0)) | 
 | 			conv_error (); | 
 | 		      if (width > 0) | 
 | 			--width; | 
 | 		      char_buffer_add (&charbuf, c); | 
 | 		      if (__builtin_expect (width == 0 | 
 | 					    || inchar () == EOF | 
 | 					    || TOLOWER (c) != L_('i'), 0)) | 
 | 			conv_error (); | 
 | 		      if (width > 0) | 
 | 			--width; | 
 | 		      char_buffer_add (&charbuf, c); | 
 | 		      if (__builtin_expect (width == 0 | 
 | 					    || inchar () == EOF | 
 | 					    || TOLOWER (c) != L_('t'), 0)) | 
 | 			conv_error (); | 
 | 		      if (width > 0) | 
 | 			--width; | 
 | 		      char_buffer_add (&charbuf, c); | 
 | 		      if (__builtin_expect (width == 0 | 
 | 					    || inchar () == EOF | 
 | 					    || TOLOWER (c) != L_('y'), 0)) | 
 | 			conv_error (); | 
 | 		      if (width > 0) | 
 | 			--width; | 
 | 		      char_buffer_add (&charbuf, c); | 
 | 		    } | 
 | 		  else | 
 | 		    /* Never mind.  */ | 
 | 		    ungetc (c, s); | 
 | 		} | 
 | 	      goto scan_float; | 
 | 	    } | 
 |  | 
 | 	  exp_char = L_('e'); | 
 | 	  if (width != 0 && c == L_('0')) | 
 | 	    { | 
 | 	      char_buffer_add (&charbuf, c); | 
 | 	      c = inchar (); | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	      if (width != 0 && TOLOWER (c) == L_('x')) | 
 | 		{ | 
 | 		  /* It is a number in hexadecimal format.  */ | 
 | 		  char_buffer_add (&charbuf, c); | 
 |  | 
 | 		  flags |= HEXA_FLOAT; | 
 | 		  exp_char = L_('p'); | 
 |  | 
 | 		  /* Grouping is not allowed.  */ | 
 | 		  flags &= ~GROUP; | 
 | 		  c = inchar (); | 
 | 		  if (width > 0) | 
 | 		    --width; | 
 | 		} | 
 | 	      else | 
 | 		got_digit = 1; | 
 | 	    } | 
 |  | 
 | 	  while (1) | 
 | 	    { | 
 | 	      if (char_buffer_error (&charbuf)) | 
 | 		{ | 
 | 		  __set_errno (ENOMEM); | 
 | 		  done = EOF; | 
 | 		  goto errout; | 
 | 		} | 
 | 	      if (ISDIGIT (c)) | 
 | 		{ | 
 | 		  char_buffer_add (&charbuf, c); | 
 | 		  got_digit = 1; | 
 | 		} | 
 | 	      else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c)) | 
 | 		{ | 
 | 		  char_buffer_add (&charbuf, c); | 
 | 		  got_digit = 1; | 
 | 		} | 
 | 	      else if (got_e && charbuf.current[-1] == exp_char | 
 | 		       && (c == L_('-') || c == L_('+'))) | 
 | 		char_buffer_add (&charbuf, c); | 
 | 	      else if (got_digit && !got_e | 
 | 		       && (CHAR_T) TOLOWER (c) == exp_char) | 
 | 		{ | 
 | 		  char_buffer_add (&charbuf, exp_char); | 
 | 		  got_e = got_dot = 1; | 
 | 		} | 
 | 	      else | 
 | 		{ | 
 | #ifdef COMPILE_WSCANF | 
 | 		  if (! got_dot && c == decimal) | 
 | 		    { | 
 | 		      char_buffer_add (&charbuf, c); | 
 | 		      got_dot = 1; | 
 | 		    } | 
 | 		  else if ((flags & GROUP) != 0 && ! got_dot && c == thousands) | 
 | 		    char_buffer_add (&charbuf, c); | 
 | 		  else | 
 | 		    { | 
 | 		      /* The last read character is not part of the number | 
 | 			 anymore.  */ | 
 | 		      ungetc (c, s); | 
 | 		      break; | 
 | 		    } | 
 | #else | 
 | 		  const char *cmpp = decimal; | 
 | 		  int avail = width > 0 ? width : INT_MAX; | 
 |  | 
 | 		  if (! got_dot) | 
 | 		    { | 
 | 		      while ((unsigned char) *cmpp == c && avail >= 0) | 
 | 			if (*++cmpp == '\0') | 
 | 			  break; | 
 | 			else | 
 | 			  { | 
 | 			    if (avail == 0 || inchar () == EOF) | 
 | 			      break; | 
 | 			    --avail; | 
 | 			  } | 
 | 		    } | 
 |  | 
 | 		  if (*cmpp == '\0') | 
 | 		    { | 
 | 		      /* Add all the characters.  */ | 
 | 		      for (cmpp = decimal; *cmpp != '\0'; ++cmpp) | 
 | 			char_buffer_add (&charbuf, (unsigned char) *cmpp); | 
 | 		      if (width > 0) | 
 | 			width = avail; | 
 | 		      got_dot = 1; | 
 | 		    } | 
 | 		  else | 
 | 		    { | 
 | 		      /* Figure out whether it is a thousands separator. | 
 | 			 There is one problem: we possibly read more than | 
 | 			 one character.  We cannot push them back but since | 
 | 			 we know that parts of the `decimal' string matched, | 
 | 			 we can compare against it.  */ | 
 | 		      const char *cmp2p = thousands; | 
 |  | 
 | 		      if ((flags & GROUP) != 0 && ! got_dot) | 
 | 			{ | 
 | 			  while (cmp2p - thousands < cmpp - decimal | 
 | 				 && *cmp2p == decimal[cmp2p - thousands]) | 
 | 			    ++cmp2p; | 
 | 			  if (cmp2p - thousands == cmpp - decimal) | 
 | 			    { | 
 | 			      while ((unsigned char) *cmp2p == c && avail >= 0) | 
 | 				if (*++cmp2p == '\0') | 
 | 				  break; | 
 | 				else | 
 | 				  { | 
 | 				    if (avail == 0 || inchar () == EOF) | 
 | 				      break; | 
 | 				    --avail; | 
 | 				  } | 
 | 			    } | 
 | 			} | 
 |  | 
 | 		      if (cmp2p != NULL && *cmp2p == '\0') | 
 | 			{ | 
 | 			  /* Add all the characters.  */ | 
 | 			  for (cmpp = thousands; *cmpp != '\0'; ++cmpp) | 
 | 			    char_buffer_add (&charbuf, (unsigned char) *cmpp); | 
 | 			  if (width > 0) | 
 | 			    width = avail; | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  /* The last read character is not part of the number | 
 | 			     anymore.  */ | 
 | 			  ungetc (c, s); | 
 | 			  break; | 
 | 			} | 
 | 		    } | 
 | #endif | 
 | 		} | 
 |  | 
 | 	      if (width == 0 || inchar () == EOF) | 
 | 		break; | 
 |  | 
 | 	      if (width > 0) | 
 | 		--width; | 
 | 	    } | 
 |  | 
 | 	  if (char_buffer_error (&charbuf)) | 
 | 	    { | 
 | 	      __set_errno (ENOMEM); | 
 | 	      done = EOF; | 
 | 	      goto errout; | 
 | 	    } | 
 |  | 
 | 	  wctrans_t map; | 
 | 	  if (__builtin_expect ((flags & I18N) != 0, 0) | 
 | 	      /* Hexadecimal floats make no sense, fixing localized | 
 | 		 digits with ASCII letters.  */ | 
 | 	      && !(flags & HEXA_FLOAT) | 
 | 	      /* Minimum requirement.  */ | 
 | 	      && (char_buffer_size (&charbuf) == 0 || got_dot) | 
 | 	      && (map = __wctrans ("to_inpunct")) != NULL) | 
 | 	    { | 
 | 	      /* Reget the first character.  */ | 
 | 	      inchar (); | 
 |  | 
 | 	      /* Localized digits, decimal points, and thousands | 
 | 		 separator.  */ | 
 | 	      wint_t wcdigits[12]; | 
 |  | 
 | 	      /* First get decimal equivalent to check if we read it | 
 | 		 or not.  */ | 
 | 	      wcdigits[11] = __towctrans (L'.', map); | 
 |  | 
 | 	      /* If we have not read any character or have just read | 
 | 		 locale decimal point which matches the decimal point | 
 | 		 for localized FP numbers, then we may have localized | 
 | 		 digits.  Note, we test GOT_DOT above.  */ | 
 | #ifdef COMPILE_WSCANF | 
 | 	      if (char_buffer_size (&charbuf) == 0 | 
 | 		  || (char_buffer_size (&charbuf) == 1 | 
 | 		      && wcdigits[11] == decimal)) | 
 | #else | 
 | 	      char mbdigits[12][MB_LEN_MAX + 1]; | 
 |  | 
 | 	      mbstate_t state; | 
 | 	      memset (&state, '\0', sizeof (state)); | 
 |  | 
 | 	      bool match_so_far = char_buffer_size (&charbuf) == 0; | 
 | 	      size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &state); | 
 | 	      if (mblen != (size_t) -1) | 
 | 		{ | 
 | 		  mbdigits[11][mblen] = '\0'; | 
 | 		  match_so_far |= | 
 | 		    (char_buffer_size (&charbuf) == strlen (decimal) | 
 | 		     && strcmp (decimal, mbdigits[11]) == 0); | 
 | 		} | 
 | 	      else | 
 | 		{ | 
 | 		  size_t decimal_len = strlen (decimal); | 
 | 		  /* This should always be the case but the data comes | 
 | 		     from a file.  */ | 
 | 		  if (decimal_len <= MB_LEN_MAX) | 
 | 		    { | 
 | 		      match_so_far |= char_buffer_size (&charbuf) == decimal_len; | 
 | 		      memcpy (mbdigits[11], decimal, decimal_len + 1); | 
 | 		    } | 
 | 		  else | 
 | 		    match_so_far = false; | 
 | 		} | 
 |  | 
 | 	      if (match_so_far) | 
 | #endif | 
 | 		{ | 
 | 		  bool have_locthousands = (flags & GROUP) != 0; | 
 |  | 
 | 		  /* Now get the digits and the thousands-sep equivalents.  */ | 
 | 		  for (int n = 0; n < 11; ++n) | 
 | 		    { | 
 | 		      if (n < 10) | 
 | 			wcdigits[n] = __towctrans (L'0' + n, map); | 
 | 		      else if (n == 10) | 
 | 			{ | 
 | 			  wcdigits[10] = __towctrans (L',', map); | 
 | 			  have_locthousands &= wcdigits[10] != L'\0'; | 
 | 			} | 
 |  | 
 | #ifndef COMPILE_WSCANF | 
 | 		      memset (&state, '\0', sizeof (state)); | 
 |  | 
 | 		      size_t mblen = __wcrtomb (mbdigits[n], wcdigits[n], | 
 | 						&state); | 
 | 		      if (mblen == (size_t) -1) | 
 | 			{ | 
 | 			  if (n == 10) | 
 | 			    { | 
 | 			      if (have_locthousands) | 
 | 				{ | 
 | 				  size_t thousands_len = strlen (thousands); | 
 | 				  if (thousands_len <= MB_LEN_MAX) | 
 | 				    memcpy (mbdigits[10], thousands, | 
 | 					    thousands_len + 1); | 
 | 				  else | 
 | 				    have_locthousands = false; | 
 | 				} | 
 | 			    } | 
 | 			  else | 
 | 			    /* Ignore checking against localized digits.  */ | 
 | 			    goto no_i18nflt; | 
 | 			} | 
 | 		      else | 
 | 			mbdigits[n][mblen] = '\0'; | 
 | #endif | 
 | 		    } | 
 |  | 
 | 		  /* Start checking against localized digits, if | 
 | 		     conversion is done correctly. */ | 
 | 		  while (1) | 
 | 		    { | 
 | 		      if (char_buffer_error (&charbuf)) | 
 | 			{ | 
 | 			  __set_errno (ENOMEM); | 
 | 			  done = EOF; | 
 | 			  goto errout; | 
 | 			} | 
 | 		      if (got_e && charbuf.current[-1] == exp_char | 
 | 			  && (c == L_('-') || c == L_('+'))) | 
 | 			char_buffer_add (&charbuf, c); | 
 | 		      else if (char_buffer_size (&charbuf) > 0 && !got_e | 
 | 			       && (CHAR_T) TOLOWER (c) == exp_char) | 
 | 			{ | 
 | 			  char_buffer_add (&charbuf, exp_char); | 
 | 			  got_e = got_dot = 1; | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  /* Check against localized digits, decimal point, | 
 | 			     and thousands separator.  */ | 
 | 			  int n; | 
 | 			  for (n = 0; n < 12; ++n) | 
 | 			    { | 
 | #ifdef COMPILE_WSCANF | 
 | 			      if (c == wcdigits[n]) | 
 | 				{ | 
 | 				  if (n < 10) | 
 | 				    char_buffer_add (&charbuf, L_('0') + n); | 
 | 				  else if (n == 11 && !got_dot) | 
 | 				    { | 
 | 				      char_buffer_add (&charbuf, decimal); | 
 | 				      got_dot = 1; | 
 | 				    } | 
 | 				  else if (n == 10 && have_locthousands | 
 | 					   && ! got_dot) | 
 | 				    char_buffer_add (&charbuf, thousands); | 
 | 				  else | 
 | 				    /* The last read character is not part | 
 | 				       of the number anymore.  */ | 
 | 				    n = 12; | 
 |  | 
 | 				  break; | 
 | 				} | 
 | #else | 
 | 			      const char *cmpp = mbdigits[n]; | 
 | 			      int avail = width > 0 ? width : INT_MAX; | 
 |  | 
 | 			      while ((unsigned char) *cmpp == c && avail >= 0) | 
 | 				if (*++cmpp == '\0') | 
 | 				  break; | 
 | 				else | 
 | 				  { | 
 | 				    if (avail == 0 || inchar () == EOF) | 
 | 				      break; | 
 | 				    --avail; | 
 | 				  } | 
 | 			      if (*cmpp == '\0') | 
 | 				{ | 
 | 				  if (width > 0) | 
 | 				    width = avail; | 
 |  | 
 | 				  if (n < 10) | 
 | 				    char_buffer_add (&charbuf, L_('0') + n); | 
 | 				  else if (n == 11 && !got_dot) | 
 | 				    { | 
 | 				      /* Add all the characters.  */ | 
 | 				      for (cmpp = decimal; *cmpp != '\0'; | 
 | 					   ++cmpp) | 
 | 					char_buffer_add (&charbuf, | 
 | 							 (unsigned char) *cmpp); | 
 |  | 
 | 				      got_dot = 1; | 
 | 				    } | 
 | 				  else if (n == 10 && (flags & GROUP) != 0 | 
 | 					   && ! got_dot) | 
 | 				    { | 
 | 				      /* Add all the characters.  */ | 
 | 				      for (cmpp = thousands; *cmpp != '\0'; | 
 | 					   ++cmpp) | 
 | 					char_buffer_add (&charbuf, | 
 | 							 (unsigned char) *cmpp); | 
 | 				    } | 
 | 				  else | 
 | 				    /* The last read character is not part | 
 | 				       of the number anymore.  */ | 
 | 				      n = 12; | 
 |  | 
 | 				  break; | 
 | 				} | 
 |  | 
 | 			      /* We are pushing all read characters back.  */ | 
 | 			      if (cmpp > mbdigits[n]) | 
 | 				{ | 
 | 				  ungetc (c, s); | 
 | 				  while (--cmpp > mbdigits[n]) | 
 | 				    ungetc_not_eof ((unsigned char) *cmpp, s); | 
 | 				  c = (unsigned char) *cmpp; | 
 | 				} | 
 | #endif | 
 | 			    } | 
 |  | 
 | 			  if (n >= 12) | 
 | 			    { | 
 | 			      /* The last read character is not part | 
 | 				 of the number anymore.  */ | 
 | 			      ungetc (c, s); | 
 | 			      break; | 
 | 			    } | 
 | 			} | 
 |  | 
 | 		      if (width == 0 || inchar () == EOF) | 
 | 			break; | 
 |  | 
 | 		      if (width > 0) | 
 | 			--width; | 
 | 		    } | 
 | 		} | 
 |  | 
 | #ifndef COMPILE_WSCANF | 
 | 	    no_i18nflt: | 
 | 	      ; | 
 | #endif | 
 | 	    } | 
 |  | 
 | 	  if (char_buffer_error (&charbuf)) | 
 | 	    { | 
 | 	      __set_errno (ENOMEM); | 
 | 	      done = EOF; | 
 | 	      goto errout; | 
 | 	    } | 
 |  | 
 | 	  /* Have we read any character?  If we try to read a number | 
 | 	     in hexadecimal notation and we have read only the `0x' | 
 | 	     prefix this is an error.  */ | 
 | 	  if (__glibc_unlikely (char_buffer_size (&charbuf) == 0 | 
 | 				|| ((flags & HEXA_FLOAT) | 
 | 				    && char_buffer_size (&charbuf) == 2))) | 
 | 	    conv_error (); | 
 |  | 
 | 	scan_float: | 
 | 	  /* Convert the number.  */ | 
 | 	  char_buffer_add (&charbuf, L_('\0')); | 
 | 	  if (char_buffer_error (&charbuf)) | 
 | 	    { | 
 | 	      __set_errno (ENOMEM); | 
 | 	      done = EOF; | 
 | 	      goto errout; | 
 | 	    } | 
 | 	  if ((flags & LONGDBL) && !__ldbl_is_dbl) | 
 | 	    { | 
 | 	      long double d = __strtold_internal | 
 | 		(char_buffer_start (&charbuf), &tw, flags & GROUP); | 
 | 	      if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf)) | 
 | 		*ARG (long double *) = negative ? -d : d; | 
 | 	    } | 
 | 	  else if (flags & (LONG | LONGDBL)) | 
 | 	    { | 
 | 	      double d = __strtod_internal | 
 | 		(char_buffer_start (&charbuf), &tw, flags & GROUP); | 
 | 	      if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf)) | 
 | 		*ARG (double *) = negative ? -d : d; | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      float d = __strtof_internal | 
 | 		(char_buffer_start (&charbuf), &tw, flags & GROUP); | 
 | 	      if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf)) | 
 | 		*ARG (float *) = negative ? -d : d; | 
 | 	    } | 
 |  | 
 | 	  if (__glibc_unlikely (tw == char_buffer_start (&charbuf))) | 
 | 	    conv_error (); | 
 |  | 
 | 	  if (!(flags & SUPPRESS)) | 
 | 	    ++done; | 
 | 	  break; | 
 |  | 
 | 	case L_('['):	/* Character class.  */ | 
 | 	  if (flags & LONG) | 
 | 	    STRING_ARG (wstr, wchar_t, 100); | 
 | 	  else | 
 | 	    STRING_ARG (str, char, 100); | 
 |  | 
 | 	  if (*f == L_('^')) | 
 | 	    { | 
 | 	      ++f; | 
 | 	      not_in = 1; | 
 | 	    } | 
 | 	  else | 
 | 	    not_in = 0; | 
 |  | 
 | 	  if (width < 0) | 
 | 	    /* There is no width given so there is also no limit on the | 
 | 	       number of characters we read.  Therefore we set width to | 
 | 	       a very high value to make the algorithm easier.  */ | 
 | 	    width = INT_MAX; | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | 	  /* Find the beginning and the end of the scanlist.  We are not | 
 | 	     creating a lookup table since it would have to be too large. | 
 | 	     Instead we search each time through the string.  This is not | 
 | 	     a constant lookup time but who uses this feature deserves to | 
 | 	     be punished.  */ | 
 | 	  tw = (wchar_t *) f;	/* Marks the beginning.  */ | 
 |  | 
 | 	  if (*f == L']') | 
 | 	    ++f; | 
 |  | 
 | 	  while ((fc = *f++) != L'\0' && fc != L']'); | 
 |  | 
 | 	  if (__glibc_unlikely (fc == L'\0')) | 
 | 	    conv_error (); | 
 | 	  wchar_t *twend = (wchar_t *) f - 1; | 
 | #else | 
 | 	  /* Fill WP with byte flags indexed by character. | 
 | 	     We will use this flag map for matching input characters.  */ | 
 | 	  if (!scratch_buffer_set_array_size | 
 | 	      (&charbuf.scratch, UCHAR_MAX + 1, 1)) | 
 | 	    { | 
 | 	      done = EOF; | 
 | 	      goto errout; | 
 | 	    } | 
 | 	  memset (charbuf.scratch.data, '\0', UCHAR_MAX + 1); | 
 |  | 
 | 	  fc = *f; | 
 | 	  if (fc == ']' || fc == '-') | 
 | 	    { | 
 | 	      /* If ] or - appears before any char in the set, it is not | 
 | 		 the terminator or separator, but the first char in the | 
 | 		 set.  */ | 
 | 	      ((char *)charbuf.scratch.data)[fc] = 1; | 
 | 	      ++f; | 
 | 	    } | 
 |  | 
 | 	  while ((fc = *f++) != '\0' && fc != ']') | 
 | 	    if (fc == '-' && *f != '\0' && *f != ']' | 
 | 		&& (unsigned char) f[-2] <= (unsigned char) *f) | 
 | 	      { | 
 | 		/* Add all characters from the one before the '-' | 
 | 		   up to (but not including) the next format char.  */ | 
 | 		for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc) | 
 | 		  ((char *)charbuf.scratch.data)[fc] = 1; | 
 | 	      } | 
 | 	    else | 
 | 	      /* Add the character to the flag map.  */ | 
 | 	      ((char *)charbuf.scratch.data)[fc] = 1; | 
 |  | 
 | 	  if (__glibc_unlikely (fc == '\0')) | 
 | 	    conv_error(); | 
 | #endif | 
 |  | 
 | 	  if (flags & LONG) | 
 | 	    { | 
 | 	      size_t now = read_in; | 
 | #ifdef COMPILE_WSCANF | 
 | 	      if (__glibc_unlikely (inchar () == WEOF)) | 
 | 		input_error (); | 
 |  | 
 | 	      do | 
 | 		{ | 
 | 		  wchar_t *runp; | 
 |  | 
 | 		  /* Test whether it's in the scanlist.  */ | 
 | 		  runp = tw; | 
 | 		  while (runp < twend) | 
 | 		    { | 
 | 		      if (runp[0] == L'-' && runp[1] != '\0' | 
 | 			  && runp + 1 != twend | 
 | 			  && runp != tw | 
 | 			  && (unsigned int) runp[-1] <= (unsigned int) runp[1]) | 
 | 			{ | 
 | 			  /* Match against all characters in between the | 
 | 			     first and last character of the sequence.  */ | 
 | 			  wchar_t wc; | 
 |  | 
 | 			  for (wc = runp[-1] + 1; wc <= runp[1]; ++wc) | 
 | 			    if ((wint_t) wc == c) | 
 | 			      break; | 
 |  | 
 | 			  if (wc <= runp[1] && !not_in) | 
 | 			    break; | 
 | 			  if (wc <= runp[1] && not_in) | 
 | 			    { | 
 | 			      /* The current character is not in the | 
 | 				 scanset.  */ | 
 | 			      ungetc (c, s); | 
 | 			      goto out; | 
 | 			    } | 
 |  | 
 | 			  runp += 2; | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  if ((wint_t) *runp == c && !not_in) | 
 | 			    break; | 
 | 			  if ((wint_t) *runp == c && not_in) | 
 | 			    { | 
 | 			      ungetc (c, s); | 
 | 			      goto out; | 
 | 			    } | 
 |  | 
 | 			  ++runp; | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  if (runp == twend && !not_in) | 
 | 		    { | 
 | 		      ungetc (c, s); | 
 | 		      goto out; | 
 | 		    } | 
 |  | 
 | 		  if (!(flags & SUPPRESS)) | 
 | 		    { | 
 | 		      *wstr++ = c; | 
 |  | 
 | 		      if ((flags & MALLOC) | 
 | 			  && wstr == (wchar_t *) *strptr + strsize) | 
 | 			{ | 
 | 			  /* Enlarge the buffer.  */ | 
 | 			  wstr = (wchar_t *) realloc (*strptr, | 
 | 						      (2 * strsize) | 
 | 						      * sizeof (wchar_t)); | 
 | 			  if (wstr == NULL) | 
 | 			    { | 
 | 			      /* Can't allocate that much.  Last-ditch | 
 | 				 effort.  */ | 
 | 			      wstr = (wchar_t *) | 
 | 				realloc (*strptr, (strsize + 1) | 
 | 						  * sizeof (wchar_t)); | 
 | 			      if (wstr == NULL) | 
 | 				{ | 
 | 				  if (flags & POSIX_MALLOC) | 
 | 				    { | 
 | 				      done = EOF; | 
 | 				      goto errout; | 
 | 				    } | 
 | 				  /* We lose.  Oh well.  Terminate the string | 
 | 				     and stop converting, so at least we don't | 
 | 				     skip any input.  */ | 
 | 				  ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; | 
 | 				  strptr = NULL; | 
 | 				  ++done; | 
 | 				  conv_error (); | 
 | 				} | 
 | 			      else | 
 | 				{ | 
 | 				  *strptr = (char *) wstr; | 
 | 				  wstr += strsize; | 
 | 				  ++strsize; | 
 | 				} | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = (char *) wstr; | 
 | 			      wstr += strsize; | 
 | 			      strsize *= 2; | 
 | 			    } | 
 | 			} | 
 | 		    } | 
 | 		} | 
 | 	      while (--width > 0 && inchar () != WEOF); | 
 | 	    out: | 
 | #else | 
 | 	      char buf[MB_LEN_MAX]; | 
 | 	      size_t cnt = 0; | 
 | 	      mbstate_t cstate; | 
 |  | 
 | 	      if (__glibc_unlikely (inchar () == EOF)) | 
 | 		input_error (); | 
 |  | 
 | 	      memset (&cstate, '\0', sizeof (cstate)); | 
 |  | 
 | 	      do | 
 | 		{ | 
 | 		  if (((char *) charbuf.scratch.data)[c] == not_in) | 
 | 		    { | 
 | 		      ungetc_not_eof (c, s); | 
 | 		      break; | 
 | 		    } | 
 |  | 
 | 		  /* This is easy.  */ | 
 | 		  if (!(flags & SUPPRESS)) | 
 | 		    { | 
 | 		      size_t n; | 
 |  | 
 | 		      /* Convert it into a wide character.  */ | 
 | 		      buf[0] = c; | 
 | 		      n = __mbrtowc (wstr, buf, 1, &cstate); | 
 |  | 
 | 		      if (n == (size_t) -2) | 
 | 			{ | 
 | 			  /* Possibly correct character, just not enough | 
 | 			     input.  */ | 
 | 			  ++cnt; | 
 | 			  assert (cnt < MB_CUR_MAX); | 
 | 			  continue; | 
 | 			} | 
 | 		      cnt = 0; | 
 |  | 
 | 		      ++wstr; | 
 | 		      if ((flags & MALLOC) | 
 | 			  && wstr == (wchar_t *) *strptr + strsize) | 
 | 			{ | 
 | 			  /* Enlarge the buffer.  */ | 
 | 			  wstr = (wchar_t *) realloc (*strptr, | 
 | 						      (2 * strsize | 
 | 						       * sizeof (wchar_t))); | 
 | 			  if (wstr == NULL) | 
 | 			    { | 
 | 			      /* Can't allocate that much.  Last-ditch | 
 | 				 effort.  */ | 
 | 			      wstr = (wchar_t *) | 
 | 				realloc (*strptr, ((strsize + 1) | 
 | 						   * sizeof (wchar_t))); | 
 | 			      if (wstr == NULL) | 
 | 				{ | 
 | 				  if (flags & POSIX_MALLOC) | 
 | 				    { | 
 | 				      done = EOF; | 
 | 				      goto errout; | 
 | 				    } | 
 | 				  /* We lose.  Oh well.  Terminate the | 
 | 				     string and stop converting, | 
 | 				     so at least we don't skip any input.  */ | 
 | 				  ((wchar_t *) (*strptr))[strsize - 1] = L'\0'; | 
 | 				  strptr = NULL; | 
 | 				  ++done; | 
 | 				  conv_error (); | 
 | 				} | 
 | 			      else | 
 | 				{ | 
 | 				  *strptr = (char *) wstr; | 
 | 				  wstr += strsize; | 
 | 				  ++strsize; | 
 | 				} | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = (char *) wstr; | 
 | 			      wstr += strsize; | 
 | 			      strsize *= 2; | 
 | 			    } | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  if (--width <= 0) | 
 | 		    break; | 
 | 		} | 
 | 	      while (inchar () != EOF); | 
 |  | 
 | 	      if (__glibc_unlikely (cnt != 0)) | 
 | 		/* We stopped in the middle of recognizing another | 
 | 		   character.  That's a problem.  */ | 
 | 		encode_error (); | 
 | #endif | 
 |  | 
 | 	      if (__glibc_unlikely (now == read_in)) | 
 | 		/* We haven't succesfully read any character.  */ | 
 | 		conv_error (); | 
 |  | 
 | 	      if (!(flags & SUPPRESS)) | 
 | 		{ | 
 | 		  *wstr++ = L'\0'; | 
 |  | 
 | 		  if ((flags & MALLOC) | 
 | 		      && wstr - (wchar_t *) *strptr != strsize) | 
 | 		    { | 
 | 		      wchar_t *cp = (wchar_t *) | 
 | 			realloc (*strptr, ((wstr - (wchar_t *) *strptr) | 
 | 					   * sizeof(wchar_t))); | 
 | 		      if (cp != NULL) | 
 | 			*strptr = (char *) cp; | 
 | 		    } | 
 | 		  strptr = NULL; | 
 |  | 
 | 		  ++done; | 
 | 		} | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      size_t now = read_in; | 
 |  | 
 | 	      if (__glibc_unlikely (inchar () == EOF)) | 
 | 		input_error (); | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 |  | 
 | 	      memset (&state, '\0', sizeof (state)); | 
 |  | 
 | 	      do | 
 | 		{ | 
 | 		  wchar_t *runp; | 
 | 		  size_t n; | 
 |  | 
 | 		  /* Test whether it's in the scanlist.  */ | 
 | 		  runp = tw; | 
 | 		  while (runp < twend) | 
 | 		    { | 
 | 		      if (runp[0] == L'-' && runp[1] != '\0' | 
 | 			  && runp + 1 != twend | 
 | 			  && runp != tw | 
 | 			  && (unsigned int) runp[-1] <= (unsigned int) runp[1]) | 
 | 			{ | 
 | 			  /* Match against all characters in between the | 
 | 			     first and last character of the sequence.  */ | 
 | 			  wchar_t wc; | 
 |  | 
 | 			  for (wc = runp[-1] + 1; wc <= runp[1]; ++wc) | 
 | 			    if ((wint_t) wc == c) | 
 | 			      break; | 
 |  | 
 | 			  if (wc <= runp[1] && !not_in) | 
 | 			    break; | 
 | 			  if (wc <= runp[1] && not_in) | 
 | 			    { | 
 | 			      /* The current character is not in the | 
 | 				 scanset.  */ | 
 | 			      ungetc (c, s); | 
 | 			      goto out2; | 
 | 			    } | 
 |  | 
 | 			  runp += 2; | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  if ((wint_t) *runp == c && !not_in) | 
 | 			    break; | 
 | 			  if ((wint_t) *runp == c && not_in) | 
 | 			    { | 
 | 			      ungetc (c, s); | 
 | 			      goto out2; | 
 | 			    } | 
 |  | 
 | 			  ++runp; | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  if (runp == twend && !not_in) | 
 | 		    { | 
 | 		      ungetc (c, s); | 
 | 		      goto out2; | 
 | 		    } | 
 |  | 
 | 		  if (!(flags & SUPPRESS)) | 
 | 		    { | 
 | 		      if ((flags & MALLOC) | 
 | 			  && str + MB_CUR_MAX >= *strptr + strsize) | 
 | 			{ | 
 | 			  /* Enlarge the buffer.  */ | 
 | 			  size_t strleng = str - *strptr; | 
 | 			  char *newstr; | 
 |  | 
 | 			  newstr = (char *) realloc (*strptr, 2 * strsize); | 
 | 			  if (newstr == NULL) | 
 | 			    { | 
 | 			      /* Can't allocate that much.  Last-ditch | 
 | 				 effort.  */ | 
 | 			      newstr = (char *) realloc (*strptr, | 
 | 							 strleng + MB_CUR_MAX); | 
 | 			      if (newstr == NULL) | 
 | 				{ | 
 | 				  if (flags & POSIX_MALLOC) | 
 | 				    { | 
 | 				      done = EOF; | 
 | 				      goto errout; | 
 | 				    } | 
 | 				  /* We lose.  Oh well.  Terminate the string | 
 | 				     and stop converting, so at least we don't | 
 | 				     skip any input.  */ | 
 | 				  ((char *) (*strptr))[strleng] = '\0'; | 
 | 				  strptr = NULL; | 
 | 				  ++done; | 
 | 				  conv_error (); | 
 | 				} | 
 | 			      else | 
 | 				{ | 
 | 				  *strptr = newstr; | 
 | 				  str = newstr + strleng; | 
 | 				  strsize = strleng + MB_CUR_MAX; | 
 | 				} | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = newstr; | 
 | 			      str = newstr + strleng; | 
 | 			      strsize *= 2; | 
 | 			    } | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state); | 
 | 		  if (__glibc_unlikely (n == (size_t) -1)) | 
 | 		    encode_error (); | 
 |  | 
 | 		  assert (n <= MB_CUR_MAX); | 
 | 		  str += n; | 
 | 		} | 
 | 	      while (--width > 0 && inchar () != WEOF); | 
 | 	    out2: | 
 | #else | 
 | 	      do | 
 | 		{ | 
 | 		  if (((char *) charbuf.scratch.data)[c] == not_in) | 
 | 		    { | 
 | 		      ungetc_not_eof (c, s); | 
 | 		      break; | 
 | 		    } | 
 |  | 
 | 		  /* This is easy.  */ | 
 | 		  if (!(flags & SUPPRESS)) | 
 | 		    { | 
 | 		      *str++ = c; | 
 | 		      if ((flags & MALLOC) | 
 | 			  && (char *) str == *strptr + strsize) | 
 | 			{ | 
 | 			  /* Enlarge the buffer.  */ | 
 | 			  size_t newsize = 2 * strsize; | 
 |  | 
 | 			allocagain: | 
 | 			  str = (char *) realloc (*strptr, newsize); | 
 | 			  if (str == NULL) | 
 | 			    { | 
 | 			      /* Can't allocate that much.  Last-ditch | 
 | 				 effort.  */ | 
 | 			      if (newsize > strsize + 1) | 
 | 				{ | 
 | 				  newsize = strsize + 1; | 
 | 				  goto allocagain; | 
 | 				} | 
 | 			      if (flags & POSIX_MALLOC) | 
 | 				{ | 
 | 				  done = EOF; | 
 | 				  goto errout; | 
 | 				} | 
 | 			      /* We lose.  Oh well.  Terminate the | 
 | 				 string and stop converting, | 
 | 				 so at least we don't skip any input.  */ | 
 | 			      ((char *) (*strptr))[strsize - 1] = '\0'; | 
 | 			      strptr = NULL; | 
 | 			      ++done; | 
 | 			      conv_error (); | 
 | 			    } | 
 | 			  else | 
 | 			    { | 
 | 			      *strptr = (char *) str; | 
 | 			      str += strsize; | 
 | 			      strsize = newsize; | 
 | 			    } | 
 | 			} | 
 | 		    } | 
 | 		} | 
 | 	      while (--width > 0 && inchar () != EOF); | 
 | #endif | 
 |  | 
 | 	      if (__glibc_unlikely (now == read_in)) | 
 | 		/* We haven't succesfully read any character.  */ | 
 | 		conv_error (); | 
 |  | 
 | 	      if (!(flags & SUPPRESS)) | 
 | 		{ | 
 | #ifdef COMPILE_WSCANF | 
 | 		  /* We have to emit the code to get into the initial | 
 | 		     state.  */ | 
 | 		  char buf[MB_LEN_MAX]; | 
 | 		  size_t n = __wcrtomb (buf, L'\0', &state); | 
 | 		  if (n > 0 && (flags & MALLOC) | 
 | 		      && str + n >= *strptr + strsize) | 
 | 		    { | 
 | 		      /* Enlarge the buffer.  */ | 
 | 		      size_t strleng = str - *strptr; | 
 | 		      char *newstr; | 
 |  | 
 | 		      newstr = (char *) realloc (*strptr, strleng + n + 1); | 
 | 		      if (newstr == NULL) | 
 | 			{ | 
 | 			  if (flags & POSIX_MALLOC) | 
 | 			    { | 
 | 			      done = EOF; | 
 | 			      goto errout; | 
 | 			    } | 
 | 			  /* We lose.  Oh well.  Terminate the string | 
 | 			     and stop converting, so at least we don't | 
 | 			     skip any input.  */ | 
 | 			  ((char *) (*strptr))[strleng] = '\0'; | 
 | 			  strptr = NULL; | 
 | 			  ++done; | 
 | 			  conv_error (); | 
 | 			} | 
 | 		      else | 
 | 			{ | 
 | 			  *strptr = newstr; | 
 | 			  str = newstr + strleng; | 
 | 			  strsize = strleng + n + 1; | 
 | 			} | 
 | 		    } | 
 |  | 
 | 		  str = __mempcpy (str, buf, n); | 
 | #endif | 
 | 		  *str++ = '\0'; | 
 |  | 
 | 		  if ((flags & MALLOC) && str - *strptr != strsize) | 
 | 		    { | 
 | 		      char *cp = (char *) realloc (*strptr, str - *strptr); | 
 | 		      if (cp != NULL) | 
 | 			*strptr = cp; | 
 | 		    } | 
 | 		  strptr = NULL; | 
 |  | 
 | 		  ++done; | 
 | 		} | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case L_('p'):	/* Generic pointer.  */ | 
 | 	  base = 16; | 
 | 	  /* A PTR must be the same size as a `long int'.  */ | 
 | 	  flags &= ~(SHORT|LONGDBL); | 
 | 	  if (need_long) | 
 | 	    flags |= LONG; | 
 | 	  flags |= READ_POINTER; | 
 | 	  goto number; | 
 |  | 
 | 	default: | 
 | 	  /* If this is an unknown format character punt.  */ | 
 | 	  conv_error (); | 
 | 	} | 
 |     } | 
 |  | 
 |   /* The last thing we saw int the format string was a white space. | 
 |      Consume the last white spaces.  */ | 
 |   if (skip_space) | 
 |     { | 
 |       do | 
 | 	c = inchar (); | 
 |       while (ISSPACE (c)); | 
 |       ungetc (c, s); | 
 |     } | 
 |  | 
 |  errout: | 
 |   /* Unlock stream.  */ | 
 |   UNLOCK_STREAM (s); | 
 |  | 
 |   scratch_buffer_free (&charbuf.scratch); | 
 |   if (errp != NULL) | 
 |     *errp |= errval; | 
 |  | 
 |   if (__glibc_unlikely (done == EOF)) | 
 |     { | 
 |       if (__glibc_unlikely (ptrs_to_free != NULL)) | 
 | 	{ | 
 | 	  struct ptrs_to_free *p = ptrs_to_free; | 
 | 	  while (p != NULL) | 
 | 	    { | 
 | 	      for (size_t cnt = 0; cnt < p->count; ++cnt) | 
 | 		{ | 
 | 		  free (*p->ptrs[cnt]); | 
 | 		  *p->ptrs[cnt] = NULL; | 
 | 		} | 
 | 	      p = p->next; | 
 | 	      ptrs_to_free = p; | 
 | 	    } | 
 | 	} | 
 |     } | 
 |   else if (__glibc_unlikely (strptr != NULL)) | 
 |     { | 
 |       free (*strptr); | 
 |       *strptr = NULL; | 
 |     } | 
 |   return done; | 
 | } | 
 |  | 
 | #ifdef COMPILE_WSCANF | 
 | int | 
 | __vfwscanf (FILE *s, const wchar_t *format, va_list argptr) | 
 | { | 
 |   return _IO_vfwscanf (s, format, argptr, NULL); | 
 | } | 
 | ldbl_weak_alias (__vfwscanf, vfwscanf) | 
 | #else | 
 | int | 
 | ___vfscanf (FILE *s, const char *format, va_list argptr) | 
 | { | 
 |   return _IO_vfscanf_internal (s, format, argptr, NULL); | 
 | } | 
 | ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf) | 
 | ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf) | 
 | ldbl_strong_alias (___vfscanf, __vfscanf) | 
 | ldbl_hidden_def (___vfscanf, __vfscanf) | 
 | ldbl_weak_alias (___vfscanf, vfscanf) | 
 | #endif |