/* Copyright (C) 1991, 92, 93, 94, 95, 96 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include "../locale/localeinfo.h"
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
#define HAVE_LONGLONG
#define LONGLONG long long
#else
#define LONGLONG long
#endif
/* Those are flags in the conversion format. */
# define LONG 0x001 /* l: long or double */
# define LONGDBL 0x002 /* L: long long or long double */
# define SHORT 0x004 /* h: short */
# define SUPPRESS 0x008 /* *: suppress assignment */
# define POINTER 0x010 /* weird %p pointer (`fake hex') */
# define NOSKIP 0x020 /* do not skip blanks */
# define WIDTH 0x040 /* width was given */
# define GROUP 0x080 /* ': group numbers */
# define MALLOC 0x100 /* a: malloc strings */
# define TYPEMOD (LONG|LONGDBL|SHORT)
#ifdef USE_IN_LIBIO
# include <libioP.h>
# include <libio.h>
# define va_list _IO_va_list
# define ungetc(c, s) _IO_ungetc (c, s)
# define inchar() ((c = _IO_getc (s)), (void) ++read_in, c)
# define conv_error() return ((void) (errp != NULL && (*errp |= 2)), \
(void) (c == EOF || _IO_ungetc (c, s)), done)
# define input_error() return ((void) (errp != NULL && (*errp |= 1)), \
done == 0 ? EOF : done)
# define memory_error() return ((void) (errno = ENOMEM), EOF)
# define ARGCHECK(s, format) \
do \
{ \
/* Check file argument for consistence. */ \
CHECK_FILE (s, -1); \
if (s->_flags & _IO_NO_READS || format == NULL) \
{ \
MAYBE_SET_EINVAL; \
return -1; \
} \
} while (0)
#else
# define inchar() ((c = getc (s)), (void) ++read_in, c)
# define conv_error() return ((void) ungetc (c, s), done)
# define input_error() return (done == 0 ? EOF : done)
# define memory_error() return ((void) (errno = ENOMEM), EOF)
# define ARGCHECK(s, format) \
do \
{ \
/* Check file argument for consistence. */ \
if (!__validfp (s) || !s->__mode.__read || format == NULL) \
{ \
errno = EINVAL; \
return -1; \
} \
} while (0)
#endif
/* 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 USE_IN_LIBIO
int
_IO_vfscanf (s, format, argptr, errp)
_IO_FILE *s;
const char *format;
_IO_va_list argptr;
int *errp;
#else
int
__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. */