} while (inchar () != EOF && (width <= 0 || --width > 0));
} while ((width <= 0 || --width > 0) && inchar () != EOF);
__vfscanf (FILE *s, const char *format, va_list argptr)#endif{  va_list arg = (va_list) argptr;  register const char *f = format;  register unsigned char fc;	/* Current character of the format.  */  register size_t done = 0;	/* Assignments done.  */  register size_t read_in = 0;	/* Chars read in.  */  register int c;		/* Last char read.  */  register int width;		/* Maximum field width.  */  register int flags;		/* Modifiers for current format element.  */  /* Status for reading F-P nums.  */  char got_dot, got_e, negative;  /* If a [...] is a [^...].  */  char not_in;  /* Base for integral numbers.  */  int base;  /* Signedness for integral numbers.  */  int number_signed;  /* Decimal point character.  */  wchar_t decimal;  /* The thousands character of the current locale.  */  wchar_t thousands;  /* Integral holding variables.  */  union    {      long long int q;      unsigned long long int uq;      long int l;      unsigned long int ul;    } num;  /* Character-buffer pointer.  */  register char *str, **strptr;  size_t strsize;  /* 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 *tw;			/* Temporary pointer.  */  char *wp = NULL;		/* Workspace.  */  size_t wpmax = 0;		/* Maximal size of workspace.  */  size_t wpsize;		/* Currently used bytes in workspace.  */#define ADDW(Ch)							    \  do									    \    {									    \      if (wpsize == wpmax)						    \	{								    \	  char *old = wp;						    \	  wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax;	    \	  wp = (char *) alloca (wpmax);					    \	  if (old != NULL)						    \	    memcpy (wp, old, wpsize);					    \	}								    \      wp[wpsize++] = (Ch);						    \    }									    \  while (0)  ARGCHECK (s, format);  /* Figure out the decimal point character.  */  if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),	      strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)    decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);  /* Figure out the thousands separator character.  */  if (mbtowc (&thousands, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),	      strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)    thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);  /* Lock the stream.  */  flockfile (s);  c = inchar ();  /* 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.  */#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      if (!isascii (*f))	{	  /* Non-ASCII, may be a multibyte.  */	  int len = mblen (f, strlen (f));	  if (len > 0)	    {	      while (len-- > 0)		if (c == EOF)		  input_error ();		else if (c == *f++)		  (void) inchar ();		else		  conv_error ();	      continue;	    }	}      fc = *f++;      if (fc != '%')	{	  /* Remember to skip spaces.  */	  if (isspace (fc))	    {	      skip_space = 1;	      continue;	    }	  /* Characters other than format specs must just match.  */	  if (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))		(void) inchar ();	      skip_space = 0;	    }	  if (c == fc)	    (void) inchar ();	  else	    conv_error ();	  continue;	}      /* This is the start of the conversion string. */      flags = 0;      /* Initialize state of modifiers.  */      argpos = 0;      /* Prepare temporary buffer.  */      wpsize = 0;      /* Check for a positional parameter specification.  */      if (isdigit (*f))	{	  argpos = *f++ - '0';	  while (isdigit (*f))	    argpos = argpos * 10 + (*f++ - '0');	  if (*f == '$')	    ++f;	  else	    {	      /* Oops; that was actually the field width.  */	      width = argpos;	      flags |= WIDTH;	      argpos = 0;	      goto got_width;	    }	}      /* Check for the assignment-suppressant and the number grouping flag.  */      while (*f == '*' || *f == '\'')	switch (*f++)	  {	  case '*':	    flags |= SUPPRESS;	    break;	  case '\'':	    flags |= GROUP;	    break;	  }      /* We have seen width. */      if (isdigit (*f))	flags |= WIDTH;      /* Find the maximum field width.  */      width = 0;      while (isdigit (*f))	{	  width *= 10;	  width += *f++ - '0';	}    got_width:      if (width == 0)	width = -1;      /* Check for type modifiers.  */      while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a' || *f == 'q')	switch (*f++)	  {	  case 'h':	    /* int's are short int's.  */	    if (flags & TYPEMOD)	      /* Signal illegal format element.  */	      conv_error ();	    flags |= SHORT;	    break;	  case 'l':	    if (flags & (SHORT|LONGDBL))	      conv_error ();	    else if (flags & LONG)	      {		/* A double `l' is equivalent to an `L'.  */		flags &= ~LONG;		flags |= LONGDBL;	      }	    else	      /* int's are long int's.  */	      flags |= LONG;	    break;	  case 'q':	  case 'L':	    /* double's are long double's, and int's are long long int's.  */	    if (flags & TYPEMOD)	      /* Signal illegal format element.  */	      conv_error ();	    flags |= LONGDBL;	    break;	  case 'a':	    if (flags & TYPEMOD)	      /* Signal illegal format element.  */	      conv_error ();	    /* String conversions (%s, %[) take a `char **'	       arg and fill it in with a malloc'd pointer.  */	    flags |= MALLOC;	    break;	  }      /* End of the format string?  */      if (*f == '\0')	conv_error ();      /* Find the conversion specifier.  */      fc = *f++;      if (skip_space || (fc != '[' && fc != 'c' && fc != 'n'))	{	  /* Eat whitespace.  */	  while (isspace (c))	    (void) inchar ();	  skip_space = 0;	}      switch (fc)	{	case '%':	/* Must match a literal '%'.  */	  if (c != fc)	    conv_error ();	  inchar ();	  break;	case '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 (flags & LONGDBL)	      *ARG (long long int *) = read_in - 1;	    else if (flags & LONG)	      *ARG (long int *) = read_in - 1;	    else if (flags & SHORT)	      *ARG (short int *) = read_in - 1;	    else	      *ARG (int *) = read_in - 1;	  break;	case 'c':	/* Match characters.  */	  if (!(flags & SUPPRESS))	    {	      str = ARG (char *);	      if (str == NULL)		conv_error ();	    }	  if (c == EOF)	    input_error ();	  if (width == -1)	    width = 1;	  if (!(flags & SUPPRESS))	    {	      do		*str++ = c;	      while (inchar () != EOF && --width > 0);	    }	  else	    while (inchar () != EOF && --width > 0);	  if (!(flags & SUPPRESS))	    ++done;	  break;	case 's':		/* Read a string.  */#define STRING_ARG							      \	  if (!(flags & SUPPRESS))					      \	    {								      \	      if (flags & MALLOC)					      \		{							      \		  /* The string is to be stored in a malloc'd buffer.  */     \		  strptr = ARG (char **);				      \		  if (strptr == NULL)					      \		    conv_error ();					      \		  /* Allocate an initial buffer.  */			      \		  strsize = 100;					      \		  *strptr = str = malloc (strsize);			      \		}							      \	      else							      \		str = ARG (char *);					      \	      if (str == NULL)						      \		conv_error ();						      \	    }	  STRING_ARG;	  if (c == EOF)	    input_error ();	  do	    {	      if (isspace (c))		break;#define	STRING_ADD_CHAR(c)						      \	      if (!(flags & SUPPRESS))					      \		{							      \		  *str++ = c;						      \		  if ((flags & MALLOC) && str == *strptr + strsize)	      \		    {							      \		      /* Enlarge the buffer.  */			      \		      str = realloc (*strptr, strsize * 2);		      \		      if (str == NULL)					      \			{						      \			  /* Can't allocate that much.  Last-ditch effort.  */\			  str = realloc (*strptr, strsize + 1);		      \			  if (str == NULL)				      \			    {						      \			      /* We lose.  Oh well.			      \				 Terminate the string and stop converting,    \				 so at least we don't skip any input.  */     \			      (*strptr)[strsize] = '\0';		      \			      ++done;					      \			      conv_error ();				      \			    }						      \			  else						      \			    {						      \			      *strptr = str;				      \			      str += strsize;				      \			      ++strsize;				      \			    }						      \			}						      \		      else						      \			{						      \			  *strptr = str;				      \			  str += strsize;				      \			  strsize *= 2;					      \			}						      \		    }							      \		}	      STRING_ADD_CHAR (c);	    } while (inchar () != EOF && (width <= 0 || --width > 0));	  if (!(flags & SUPPRESS))	    {	      *str = '\0';	      ++done;	    }	  break;	case 'x':	/* Hexadecimal integer.  */	case 'X':	/* Ditto.  */	  base = 16;	  number_signed = 0;	  goto number;	case 'o':	/* Octal integer.  */	  base = 8;	  number_signed = 0;	  goto number;	case 'u':	/* Unsigned decimal integer.  */	  base = 10;	  number_signed = 0;	  goto number;	case 'd':	/* Signed decimal integer.  */	  base = 10;	  number_signed = 1;	  goto number;	case 'i':	/* Generic number.  */	  base = 0;	  number_signed = 1;	number:	  if (c == EOF)	    input_error ();	  /* Check for a sign.  */	  if (c == '-' || c == '+')	    {	      ADDW (c);	      if (width > 0)		--width;	      (void) inchar ();	    }	  /* Look for a leading indication of base.  */	  if (width != 0 && c == '0')	    {	      if (width > 0)		--width;	      ADDW (c);	      (void) inchar ();	      if (width != 0 && tolower (c) == 'x')		{		  if (base == 0)		    base = 16;		  if (base == 16)		    {		      if (width > 0)			--width;		      (void) inchar ();		    }		}	      else if (base == 0)		base = 8;	    }	  if (base == 0)	    base = 10;	  /* Read the number into workspace.  */	  while (c != EOF && width != 0)	    {	      if (base == 16 ? !isxdigit (c) :		  ((!isdigit (c) || c - '0' >= base) &&		   !((flags & GROUP) && base == 10 && c == thousands)))		break;	      ADDW (c);	      if (width > 0)		--width;	      (void) inchar ();	    }	  if (wpsize == 0 ||	      (wpsize == 1 && (wp[0] == '+' || wp[0] == '-')))	    /* There was no number.  */	    conv_error ();	  /* Convert the number.  */	  ADDW ('\0');	  if (flags & LONGDBL)	    {	      if (number_signed)		num.q = __strtoq_internal (wp, &tw, base, flags & GROUP);	      else		num.uq = __strtouq_internal (wp, &tw, base, flags & GROUP);	    }	  else	    {	      if (number_signed)		num.l = __strtol_internal (wp, &tw, base, flags & GROUP);	      else		num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);	    }	  if (wp == tw)	    conv_error ();	  if (!(flags & SUPPRESS))	    {	      if (! number_signed)		{		  if (flags & LONGDBL)		    *ARG (unsigned LONGLONG int *) = num.uq;		  else if (flags & LONG)		    *ARG (unsigned long int *) = num.ul;		  else if (flags & SHORT)		    *ARG (unsigned short int *)		      = (unsigned short int) num.ul;		  else		    *ARG (unsigned int *) = (unsigned int) num.ul;		}	      else		{		  if (flags & LONGDBL)		    *ARG (LONGLONG int *) = num.q;		  else if (flags & LONG)		    *ARG (long int *) = num.l;		  else if (flags & SHORT)		    *ARG (short int *) = (short int) num.l;		  else		    *ARG (int *) = (int) num.l;		}	      ++done;	    }	  break;	case 'e':	/* Floating-point numbers.  */	case 'E':	case 'f':	case 'g':	case 'G':	  if (c == EOF)	    input_error ();	  /* Check for a sign.  */	  if (c == '-' || c == '+')	    {	      negative = c == '-';	      if (inchar () == EOF)		/* EOF is only an input error before we read any chars.  */		conv_error ();	      if (width > 0)		--width;	    }	  else	    negative = 0;	  got_dot = got_e = 0;	  do	    {	      if (isdigit (c))		ADDW (c);	      else if (got_e && wp[wpsize - 1] == 'e'		       && (c == '-' || c == '+'))		ADDW (c);	      else if (wpsize > 0 && !got_e && tolower (c) == 'e')		{		  ADDW ('e');		  got_e = got_dot = 1;		}	      else if (c == decimal && !got_dot)		{		  ADDW (c);		  got_dot = 1;		}	      else if ((flags & GROUP) && c == thousands && !got_dot)		ADDW (c);	      else		break;	      if (width > 0)		--width;	    }	  while (inchar () != EOF && width != 0);	  if (wpsize == 0)	    conv_error ();	  /* Convert the number.  */	  ADDW ('\0');	  if (flags & LONGDBL)	    {	      long double d = __strtold_internal (wp, &tw, flags & GROUP);	      if (!(flags & SUPPRESS) && tw != wp)		*ARG (long double *) = negative ? -d : d;	    }	  else if (flags & LONG)	    {	      double d = __strtod_internal (wp, &tw, flags & GROUP);	      if (!(flags & SUPPRESS) && tw != wp)		*ARG (double *) = negative ? -d : d;	    }	  else	    {	      float d = __strtof_internal (wp, &tw, flags & GROUP);	      if (!(flags & SUPPRESS) && tw != wp)		*ARG (float *) = negative ? -d : d;	    }	  if (tw == wp)	    conv_error ();	  if (!(flags & SUPPRESS))	    ++done;	  break;	case '[':	/* Character class.  */	  STRING_ARG;	  if (c == EOF)	    input_error();	  if (*f == '^')	    {	      ++f;	      not_in = 1;	    }	  else	    not_in = 0;	  /* Fill WP with byte flags indexed by character.	     We will use this flag map for matching input characters.  */	  if (wpmax < UCHAR_MAX)	    {	      wpmax = UCHAR_MAX;	      wp = (char *) alloca (wpmax);	    }	  memset (wp, 0, UCHAR_MAX);	  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.  */	      wp[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 = f[-2]; fc < *f; ++fc)		    wp[fc] = 1;		}	      else		/* Add the character to the flag map.  */		wp[fc] = 1;	    }	  if (fc == '\0')	    conv_error();	  num.ul = read_in;	  do	    {	      if (wp[c] == not_in)		break;	      STRING_ADD_CHAR (c);	      if (width > 0)		--width;	    }	  while (inchar () != EOF && width != 0);	  if (read_in == num.ul)	    conv_error ();	  if (!(flags & SUPPRESS))	    {	      *str = '\0';	      ++done;	    }	  break;	case 'p':	/* Generic pointer.  */	  base = 16;	  /* A PTR must be the same size as a `long int'.  */	  flags &= ~(SHORT|LONGDBL);	  flags |= LONG;	  number_signed = 0;	  goto number;	}    }  /* The last thing we saw int the format string was a white space.     Consume the last white spaces.  */  if (skip_space)    while (isspace (c))      (void) inchar ();  /* Unlock stream.  */  funlockfile (s);  return ((void) (c == EOF || ungetc (c, s)), done);}