update for HEAD-2003091401
[reactos.git] / lib / crtdll / stdio / vfscanf.c
diff --git a/lib/crtdll/stdio/vfscanf.c b/lib/crtdll/stdio/vfscanf.c
deleted file mode 100644 (file)
index 0b357d3..0000000
+++ /dev/null
@@ -1,1198 +0,0 @@
-/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-
-#include <msvcrt/errno.h>
-#include <limits.h>
-#include <msvcrt/ctype.h>
-#include <stdarg.h>
-#include <msvcrt/stdio.h>
-#include <msvcrt/stdlib.h>
-#include <msvcrt/string.h>
-#include <msvcrt/wchar.h>
-#include <msvcrt/malloc.h>
-#include <msvcrt/internal/file.h>
-#include <msvcrt/mbstring.h>
-/* The internal entry points for `strtoX' take an extra flag argument
-   saying whether or not to parse locale-dependent number grouping.  */
-
-double __strtod_internal  (const char *__nptr,char **__endptr, int __group);
-float __strtof_internal (const char *__nptr, char **__endptr,int __group);
-long double __strtold_internal  (const char *__nptr,char **__endptr, int __group);
-long int __strtol_internal (const char *__nptr, char **__endptr,       int __base, int __group);
-unsigned long int __strtoul_internal  (const char *__nptr,  char **__endptr, int __base, int __group);
-
-
-
-#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: LONGLONG 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)
-
-
-# define ungetc(c, s)  ((void) (c != EOF && --read_in), ungetc (c, s))
-# define inchar()      ((c = getc (s)), (void) (c != EOF && ++read_in), c)
-# define encode_error()        do {                                                  \
-                         funlockfile (s);                                    \
-                         __set_errno (EILSEQ);                               \
-                         return done;                                        \
-                       } while (0)
-# define conv_error()  do {                                                  \
-                         funlockfile (s);                                    \
-                         return done;                                        \
-                       } while (0)
-# define input_error() do {                                                  \
-                         funlockfile (s);                                    \
-                         return done ? 0 : EOF;                                      \
-                       } while (0)
-# define memory_error()        do {                                                  \
-                         funlockfile (s);                                    \
-                         __set_errno (ENOMEM);                               \
-                         return EOF;                                         \
-                       } while (0)
-# define ARGCHECK(s, format)                                                 \
-  do                                                                         \
-    {                                                                        \
-      /* Check file argument for consistence.  */                            \
-      if (!__validfp (s) || !s->__mode.__read)                               \
-       {                                                                     \
-         __set_errno (EBADF);                                                \
-         return EOF;                                                         \
-       }                                                                     \
-      else if (format == NULL)                                               \
-       {                                                                     \
-         __set_errno (EINVAL);                                               \
-         return EOF;                                                         \
-       }                                                                     \
-    } while (0)
-
-# define flockfile(S) /* nothing */
-# define funlockfile(S) /* nothing */
-
-  char *wp = NULL;             /* Workspace.  */
-  size_t wpmax = 0;            /* Maximal size of workspace.  */
-  size_t wpsize = 0;           /* Currently used bytes in workspace.  */
-
-
-void ADDW(int Ch)                                                                                                                              \
-{                                                                                  
-      if (wpsize == wpmax)                                             
-       {                                                                               
-         char *old = wp;                                                   
-         wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax;            
-         wp = (char *) malloc (wpmax);                                     
-         if (old != NULL) {                                        
-           memcpy (wp, old, wpsize);
-           free(old);
-         }                                         
-       }                                                                   
-      wp[wpsize++] = (Ch);                                                 
-                                                                           
-}
-
-
-int __vfscanf (FILE *s, const char *format, va_list argptr)
-{
-  va_list arg;
-  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 = 0;          /* 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.  */
-  char *str = NULL;
-  wchar_t *wstr = NULL;
-  char **strptr = NULL;
-  size_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 *tw;                    /* Temporary pointer.  */
-
-#ifdef __va_copy
-  __va_copy (arg, argptr);
-#else
-  arg = (va_list) argptr;
-#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.  */
-#define ARG(type)      va_arg(argptr,type)
-
-      if (!isascii (*f))
-       {
-         /* Non-ASCII, may be a multibyte.  */
-        // int len = mblen (f, strlen (f));
-       int len =1;
-         if (len > 0)
-           {
-             do
-               {
-                 c = inchar ();
-                 if (c == EOF)
-                   input_error ();
-                 else if (c != *f++)
-                   {
-                     ungetc (c, s);
-                     conv_error ();
-                   }
-               }
-             while (--len > 0);
-             continue;
-           }
-       }
-
-      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 (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 (inchar () == EOF && errno == EINTR)
-                 conv_error ();
-             skip_space = 0;
-           }
-
-         if (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.  */
-      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-suppressing 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 LONGLONG 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 ();
-
-      /* We must take care for EINTR errors.  */
-      if (c == EOF && errno == EINTR)
-       input_error ();
-
-      /* Find the conversion specifier.  */
-      fc = *f++;
-      if (skip_space || (fc != '[' && fc != 'c' && fc != 'C' && fc != 'n'))
-       {
-         /* Eat whitespace.  */
-         do
-           if (inchar () == EOF && errno == EINTR)
-             input_error ();
-         while (isspace (c));
-         ungetc (c, s);
-         skip_space = 0;
-       }
-
-      switch (fc)
-       {
-       case '%':       /* Must match a literal '%'.  */
-         c = inchar ();
-         if (c != fc)
-           {
-             ungetc (c, s);
-             conv_error ();
-           }
-         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 int *) = read_in;
-             else if (flags & LONG)
-               *ARG (long int *) = read_in;
-             else if (flags & SHORT)
-               *ARG (short int *) = read_in;
-             else
-               *ARG (int *) = 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 fro 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 'c':       /* Match characters.  */
-         if ((flags & LONG) == 0)
-           {
-             if (!(flags & SUPPRESS))
-               {
-                 str = ARG (char *);
-                 if (str == NULL)
-                   conv_error ();
-               }
-
-             c = inchar ();
-             if (c == EOF)
-               input_error ();
-
-             if (width == -1)
-               width = 1;
-
-             if (!(flags & SUPPRESS))
-               {
-                 do
-                   *str++ = c;
-                 while (--width > 0 && inchar () != EOF);
-               }
-             else
-               while (--width > 0 && inchar () != EOF);
-
-             if (width > 0)
-               /* I.e., EOF was read.  */
-               --read_in;
-
-             if (!(flags & SUPPRESS))
-               ++done;
-
-             break;
-           }
-         /* FALLTHROUGH */
-       case 'C':
-         /* Get UTF-8 encoded wide character.  Here we assume (as in
-            other parts of the libc) that we only have to handle
-            UTF-8.  */
-         {
-           wint_t val;
-           size_t cnt = 0;
-           int first = 1;
-
-           if (!(flags & SUPPRESS))
-             {
-               wstr = ARG (wchar_t *);
-               if (str == NULL)
-                 conv_error ();
-             }
-
-           do
-             {
-#define NEXT_WIDE_CHAR(First)                                                \
-               c = inchar ();                                                \
-               if (c == EOF)   {                                             \
-                 /* EOF is only an error for the first character.  */        \
-                 if (First) {                                                \
-                   input_error ();                                           \
-                 }                                                           \
-                 else                                                        \
-                   {                                                         \
-                     --read_in;                                              \
-                     break;                                                  \
-                   }                                                   \
-               }                                                     \
-               val = c;                                                      \
-               if (val >= 0x80)                                              \
-                 {                                                           \
-                   if ((c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe)             \
-                     encode_error ();                                        \
-                   if ((c & 0xe0) == 0xc0)                                   \
-                     {                                                       \
-                       /* We expect two bytes.  */                           \
-                       cnt = 1;                                              \
-                       val &= 0x1f;                                          \
-                     }                                                       \
-                   else if ((c & 0xf0) == 0xe0)                              \
-                     {                                                       \
-                       /* We expect three bytes.  */                         \
-                       cnt = 2;                                              \
-                       val &= 0x0f;                                          \
-                     }                                                       \
-                   else if ((c & 0xf8) == 0xf0)                              \
-                     {                                                       \
-                       /* We expect four bytes.  */                          \
-                       cnt = 3;                                              \
-                       val &= 0x07;                                          \
-                     }                                                       \
-                   else if ((c & 0xfc) == 0xf8)                              \
-                     {                                                       \
-                       /* We expect five bytes.  */                          \
-                       cnt = 4;                                              \
-                       val &= 0x03;                                          \
-                     }                                                       \
-                   else                                                      \
-                     {                                                       \
-                       /* We expect six bytes.  */                           \
-                       cnt = 5;                                              \
-                       val &= 0x01;                                          \
-                     }                                                       \
-                                                                             \
-                   do                                                        \
-                     {                                                       \
-                       c = inchar ();                                        \
-                       if (c == EOF                                          \
-                           || (c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe)      \
-                         encode_error ();                                    \
-                       val <<= 6;                                            \
-                       val |= c & 0x3f;                                      \
-                     }                                                       \
-                   while (--cnt > 0);                                        \
-                 }                                                           \
-                                                                             \
-               if (!(flags & SUPPRESS))                                      \
-                 *wstr++ = val;                                              \
-               first = 0
-
-               NEXT_WIDE_CHAR (first);
-             }
-           while (--width > 0);
-
-           if (width > 0)
-             /* I.e., EOF was read.  */
-             --read_in;
-
-           if (!(flags & SUPPRESS))
-             ++done;
-         }
-         break;
-
-       case 's':               /* Read a string.  */
-         if (flags & LONG)
-           /* We have to process a wide character string.  */
-           goto wide_char_string;
-
-#define STRING_ARG(Str, Type)                                                \
-         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 = malloc (strsize * sizeof (Type));                 \
-                 Str = (Type *) *strptr;                                     \
-               }                                                             \
-             else                                                            \
-               Str = ARG (Type *);                                           \
-             if (Str == NULL)                                                \
-               conv_error ();                                                \
-           }
-         STRING_ARG (str, char);
-
-         c = inchar ();
-         if (c == EOF)
-           input_error ();
-
-         do
-           {
-             if (isspace (c))
-               {
-                 ungetc (c, s);
-                 break;
-               }
-#define        STRING_ADD_CHAR(Str, c, Type)                                         \
-             if (!(flags & SUPPRESS))                                        \
-               {                                                             \
-                 *Str++ = c;                                                 \
-                 if ((flags & MALLOC) && (char *) Str == *strptr + strsize)  \
-                   {                                                         \
-                     /* Enlarge the buffer.  */                              \
-                     Str = realloc (*strptr, strsize * 2 * sizeof (Type));   \
-                     if (Str == NULL)                                        \
-                       {                                                     \
-                         /* Can't allocate that much.  Last-ditch effort.  */\
-                         Str = realloc (*strptr,                             \
-                                        (strsize + 1) * sizeof (Type));      \
-                         if (Str == NULL)                                    \
-                           {                                                 \
-                             /* We lose.  Oh well.                           \
-                                Terminate the string and stop converting,    \
-                                so at least we don't skip any input.  */     \
-                             ((Type *) (*strptr))[strsize] = '\0';           \
-                             ++done;                                         \
-                             conv_error ();                                  \
-                           }                                                 \
-                         else                                                \
-                           {                                                 \
-                             *strptr = (char *) Str;                         \
-                             Str = ((Type *) *strptr) + strsize;             \
-                             ++strsize;                                      \
-                           }                                                 \
-                       }                                                     \
-                     else                                                    \
-                       {                                                     \
-                         *strptr = (char *) Str;                             \
-                         Str = ((Type *) *strptr) + strsize;                 \
-                         strsize *= 2;                                       \
-                       }                                                     \
-                   }                                                         \
-               }
-             STRING_ADD_CHAR (str, c, char);
-           } while ((width <= 0 || --width > 0) && inchar () != EOF);
-
-         if (!(flags & SUPPRESS))
-           {
-             *str = '\0';
-             ++done;
-           }
-         break;
-
-       case 'S':
-         /* Wide character string.  */
-       wide_char_string:
-         {
-           wint_t val;
-           int first = 1;
-           STRING_ARG (wstr, wchar_t);
-
-           do
-             {
-               size_t cnt = 0;
-               NEXT_WIDE_CHAR (first);
-
-               if (iswspace (val))
-                 {
-                   /* XXX We would have to push back the whole wide char
-                      with possibly many bytes.  But since scanf does
-                      not make a difference for white space characters
-                      we can simply push back a simple <SP> which is
-                      guaranteed to be in the [:space:] class.  */
-                   ungetc (' ', s);
-                   break;
-                 }
-
-               STRING_ADD_CHAR (wstr, val, wchar_t);
-               first = 0;
-             }
-           while (width <= 0 || --width > 0);
-
-           if (!(flags & SUPPRESS))
-             {
-               *wstr = L'\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:
-         c = inchar ();
-         if (c == EOF)
-           input_error ();
-
-         /* Check for a sign.  */
-         if (c == '-' || c == '+')
-           {
-             ADDW (c);
-             if (width > 0)
-               --width;
-             c = inchar ();
-           }
-
-         /* Look for a leading indication of base.  */
-         if (width != 0 && c == '0')
-           {
-             if (width > 0)
-               --width;
-
-             ADDW (c);
-             c = inchar ();
-
-             if (width != 0 && tolower (c) == '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;
-
-         /* 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;
-
-             c = inchar ();
-           }
-
-         /* The just read character is not part of the number anymore.  */
-         ungetc (c, s);
-
-         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':
-         c = inchar ();
-         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
-               {
-                 /* The last read character is not part of the number
-                    anymore.  */
-                 ungetc (c, s);
-                 break;
-               }
-             if (width > 0)
-               --width;
-           }
-         while (width != 0 && inchar () != EOF);
-
-         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.  */
-         if (flags & LONG)
-           {
-             STRING_ARG (wstr, wchar_t);
-             c = '\0';         /* This is to keep gcc quiet.  */
-           }
-         else
-           {
-             STRING_ARG (str, char);
-
-             c = inchar ();
-             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')
-           {
-             if (!(flags & LONG))
-               ungetc (c, s);
-             conv_error();
-           }
-
-         if (flags & LONG)
-           {
-             wint_t val;
-             int first = 1;
-
-             do
-               {
-                 size_t cnt = 0;
-                 NEXT_WIDE_CHAR (first);
-                 if (val > 255 || wp[val] == not_in)
-                   {
-                     /* XXX We have a problem here.  We read a wide
-                        character and this possibly took several
-                        bytes.  But we can only push back one single
-                        character.  To be sure we don't create wrong
-                        input we push it back only in case it is
-                        representable within one byte.  */
-                     if (val < 0x80)
-                       ungetc (val, s);
-                     break;
-                   }
-                 STRING_ADD_CHAR (wstr, val, wchar_t);
-                 if (width > 0)
-                   --width;
-                 first = 0;
-               }
-             while (width != 0);
-
-             if (first)
-               conv_error ();
-
-             if (!(flags & SUPPRESS))
-               {
-                 *wstr = L'\0';
-                 ++done;
-               }
-           }
-         else
-           {
-             num.ul = read_in - 1; /* -1 because we already read one char.  */
-             do
-               {
-                 if (wp[c] == not_in)
-                   {
-                     ungetc (c, s);
-                     break;
-                   }
-                 STRING_ADD_CHAR (str, c, char);
-                 if (width > 0)
-                   --width;
-               }
-             while (width != 0 && inchar () != EOF);
-
-             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)
-    {
-      do
-       c = inchar ();
-      while (isspace (c));
-      ungetc (c, s);
-    }
-
-
-  return done;
-}
-
-
-
-int
-xfscanf(FILE *f, const char *fmt, ...)
-{
-  int r;
-  va_list a=0;
-  va_start(a, fmt);
-  r = __vfscanf(f, fmt, a);
-  va_end(a);
-  return r;
-}
-
-
-double __strtod_internal  (const char *__nptr,char **__endptr, int __group)
-{
-       return strtod(__nptr,__endptr);
-}
-float __strtof_internal (const char *__nptr, char **__endptr,int __group)
-{
-       return (float)strtod(__nptr,__endptr);
-}
-static double powten[] =
-{
-  1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L,
-  1e512L, 1e512L*1e512L, 1e2048L, 1e4096L
-};
-
-long double __strtold_internal  (const char *s,char **sret, int __group)
-{
-       
-  long double r;               /* result */
-  int e, ne;                   /* exponent */
-  int sign;                    /* +- 1.0 */
-  int esign;
-  int flags=0;
-  int l2powm1;
-
-  r = 0.0L;
-  sign = 1;
-  e = ne = 0;
-  esign = 1;
-
-  while(*s && isspace(*s))
-    s++;
-
-  if (*s == '+')
-    s++;
-  else if (*s == '-')
-  {
-    sign = -1;
-    s++;
-  }
-
-  while ((*s >= '0') && (*s <= '9'))
-  {
-    flags |= 1;
-    r *= 10.0L;
-    r += *s - '0';
-    s++;
-  }
-
-  if (*s == '.')
-  {
-    s++;
-    while ((*s >= '0') && (*s <= '9'))
-    {
-      flags |= 2;
-      r *= 10.0L;
-      r += *s - '0';
-      s++;
-      ne++;
-    }
-  }
-  if (flags == 0)
-  {
-    if (sret)
-      *sret = (char *)s;
-    return 0.0L;
-  }
-
-  if ((*s == 'e') || (*s == 'E'))
-  {
-    s++;
-    if (*s == '+')
-      s++;
-    else if (*s == '-')
-    {
-      s++;
-      esign = -1;
-    }
-    while ((*s >= '0') && (*s <= '9'))
-    {
-      e *= 10;
-      e += *s - '0';
-      s++;
-    }
-  }
-  if (esign < 0)
-  {
-    esign = -esign;
-    e = -e;
-  }
-  e = e - ne;
-  if (e < -4096)
-  {
-    /* possibly subnormal number, 10^e would overflow */
-    r *= 1.0e-2048L;
-    e += 2048;
-  }
-  if (e < 0)
-  {
-    e = -e;
-    esign = -esign;
-  }
-  if (e >= 8192)
-    e = 8191;
-  if (e)
-  {
-    double d = 1.0L;
-    l2powm1 = 0;
-    while (e)
-    {
-      if (e & 1)
-       d *= powten[l2powm1];
-      e >>= 1;
-      l2powm1++;
-    }
-    if (esign > 0)
-      r *= d;
-    else
-      r /= d;
-  }
-  if (sret)
-    *sret = (char *)s;
-  return r * sign;
-
-  return 0;
-}
-long int __strtol_internal (const char *__nptr, char **__endptr,       int __base, int __group)
-{
-       return strtol(__nptr,__endptr, __base);
-}
-unsigned long int __strtoul_internal  (const char *__nptr,  char **__endptr, int __base, int __group)
-{
-       return strtoul(__nptr,__endptr, __base);
-}
-
-
-
-
-
-
-
-
-