OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc1/] [newlib/] [libc/] [machine/] [powerpc/] [vfscanf.c] - Diff between revs 207 and 345

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 345
/*
/*
FUNCTION
FUNCTION
<<vscanf>>, <<vfscanf>>, <<vsscanf>>---format argument list
<<vscanf>>, <<vfscanf>>, <<vsscanf>>---format argument list
 
 
INDEX
INDEX
        vscanf
        vscanf
INDEX
INDEX
        vfscanf
        vfscanf
INDEX
INDEX
        vsscanf
        vsscanf
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
        #include <stdio.h>
        #include <stdio.h>
        #include <stdarg.h>
        #include <stdarg.h>
        int vscanf(const char *<[fmt]>, va_list <[list]>);
        int vscanf(const char *<[fmt]>, va_list <[list]>);
        int vfscanf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
        int vfscanf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
        int vsscanf(const char *<[str]>, const char *<[fmt]>, va_list <[list]>);
        int vsscanf(const char *<[str]>, const char *<[fmt]>, va_list <[list]>);
 
 
        int _vscanf_r(void *<[reent]>, const char *<[fmt]>,
        int _vscanf_r(void *<[reent]>, const char *<[fmt]>,
                       va_list <[list]>);
                       va_list <[list]>);
        int _vfscanf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
        int _vfscanf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
                       va_list <[list]>);
                       va_list <[list]>);
        int _vsscanf_r(void *<[reent]>, const char *<[str]>, const char *<[fmt]>,
        int _vsscanf_r(void *<[reent]>, const char *<[str]>, const char *<[fmt]>,
                       va_list <[list]>);
                       va_list <[list]>);
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
        #include <stdio.h>
        #include <stdio.h>
        #include <varargs.h>
        #include <varargs.h>
        int vscanf( <[fmt]>, <[ist]>)
        int vscanf( <[fmt]>, <[ist]>)
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int vfscanf( <[fp]>, <[fmt]>, <[list]>)
        int vfscanf( <[fp]>, <[fmt]>, <[list]>)
        FILE *<[fp]>;
        FILE *<[fp]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int vsscanf( <[str]>, <[fmt]>, <[list]>)
        int vsscanf( <[str]>, <[fmt]>, <[list]>)
        char *<[str]>;
        char *<[str]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int _vscanf_r( <[reent]>, <[fmt]>, <[ist]>)
        int _vscanf_r( <[reent]>, <[fmt]>, <[ist]>)
        char *<[reent]>;
        char *<[reent]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int _vfscanf_r( <[reent]>, <[fp]>, <[fmt]>, <[list]>)
        int _vfscanf_r( <[reent]>, <[fp]>, <[fmt]>, <[list]>)
        char *<[reent]>;
        char *<[reent]>;
        FILE *<[fp]>;
        FILE *<[fp]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int _vsscanf_r( <[reent]>, <[str]>, <[fmt]>, <[list]>)
        int _vsscanf_r( <[reent]>, <[str]>, <[fmt]>, <[list]>)
        char *<[reent]>;
        char *<[reent]>;
        char *<[str]>;
        char *<[str]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
DESCRIPTION
DESCRIPTION
<<vscanf>>, <<vfscanf>>, and <<vsscanf>> are (respectively) variants
<<vscanf>>, <<vfscanf>>, and <<vsscanf>> are (respectively) variants
of <<scanf>>, <<fscanf>>, and <<sscanf>>.  They differ only in
of <<scanf>>, <<fscanf>>, and <<sscanf>>.  They differ only in
allowing their caller to pass the variable argument list as a
allowing their caller to pass the variable argument list as a
<<va_list>> object (initialized by <<va_start>>) rather than
<<va_list>> object (initialized by <<va_start>>) rather than
directly accepting a variable number of arguments.
directly accepting a variable number of arguments.
 
 
RETURNS
RETURNS
The return values are consistent with the corresponding functions:
The return values are consistent with the corresponding functions:
<<vscanf>> returns the number of input fields successfully scanned,
<<vscanf>> returns the number of input fields successfully scanned,
converted, and stored; the return value does not include scanned
converted, and stored; the return value does not include scanned
fields which were not stored.
fields which were not stored.
 
 
If <<vscanf>> attempts to read at end-of-file, the return value
If <<vscanf>> attempts to read at end-of-file, the return value
is <<EOF>>.
is <<EOF>>.
 
 
If no fields were stored, the return value is <<0>>.
If no fields were stored, the return value is <<0>>.
 
 
The routines <<_vscanf_r>>, <<_vfscanf_f>>, and <<_vsscanf_r>> are
The routines <<_vscanf_r>>, <<_vfscanf_f>>, and <<_vsscanf_r>> are
reentrant versions which take an additional first parameter which points to the
reentrant versions which take an additional first parameter which points to the
reentrancy structure.
reentrancy structure.
 
 
PORTABILITY
PORTABILITY
These are GNU extensions.
These are GNU extensions.
 
 
Supporting OS subroutines required:
Supporting OS subroutines required:
*/
*/
 
 
/*-
/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 * All rights reserved.
 *
 *
 * Redistribution and use in source and binary forms are permitted
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
 */
 
 
#include <_ansi.h>
#include <_ansi.h>
#include <reent.h>
#include <reent.h>
#include <newlib.h>
#include <newlib.h>
#include <ctype.h>
#include <ctype.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <limits.h>
#include <limits.h>
#include <wchar.h>
#include <wchar.h>
#include <string.h>
#include <string.h>
#ifdef _HAVE_STDC
#ifdef _HAVE_STDC
#include <stdarg.h>
#include <stdarg.h>
#else
#else
#include <varargs.h>
#include <varargs.h>
#endif
#endif
#include "local.h"
#include "local.h"
 
 
#ifndef NO_FLOATING_POINT
#ifndef NO_FLOATING_POINT
#define FLOATING_POINT
#define FLOATING_POINT
#endif
#endif
 
 
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
#include <float.h>
#include <float.h>
 
 
/* Currently a test is made to see if long double processing is warranted.
/* Currently a test is made to see if long double processing is warranted.
   This could be changed in the future should the _ldtoa_r code be
   This could be changed in the future should the _ldtoa_r code be
   preferred over _dtoa_r.  */
   preferred over _dtoa_r.  */
#define _NO_LONGDBL
#define _NO_LONGDBL
#if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
#if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
#undef _NO_LONGDBL
#undef _NO_LONGDBL
extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
#endif
#endif
 
 
#define _NO_LONGLONG
#define _NO_LONGLONG
#if defined _WANT_IO_LONG_LONG && defined __GNUC__
#if defined _WANT_IO_LONG_LONG && defined __GNUC__
# undef _NO_LONGLONG
# undef _NO_LONGLONG
#endif
#endif
 
 
#include "floatio.h"
#include "floatio.h"
#define BUF     (MAXEXP+MAXFRACT+3)     /* 3 = sign + decimal point + NUL */
#define BUF     (MAXEXP+MAXFRACT+3)     /* 3 = sign + decimal point + NUL */
/* An upper bound for how long a long prints in decimal.  4 / 13 approximates
/* An upper bound for how long a long prints in decimal.  4 / 13 approximates
   log (2).  Add one char for roundoff compensation and one for the sign.  */
   log (2).  Add one char for roundoff compensation and one for the sign.  */
#define MAX_LONG_LEN ((CHAR_BIT * sizeof (long)  - 1) * 4 / 13 + 2)
#define MAX_LONG_LEN ((CHAR_BIT * sizeof (long)  - 1) * 4 / 13 + 2)
#else
#else
#define BUF     40
#define BUF     40
#endif
#endif
 
 
/*
/*
 * Flags used during conversion.
 * Flags used during conversion.
 */
 */
 
 
#define LONG            0x01    /* l: long or double */
#define LONG            0x01    /* l: long or double */
#define LONGDBL         0x02    /* L: long double or long long */
#define LONGDBL         0x02    /* L: long double or long long */
#define SHORT           0x04    /* h: short */
#define SHORT           0x04    /* h: short */
#define SUPPRESS        0x10    /* suppress assignment */
#define SUPPRESS        0x10    /* suppress assignment */
#define POINTER         0x20    /* weird %p pointer (`fake hex') */
#define POINTER         0x20    /* weird %p pointer (`fake hex') */
#define NOSKIP          0x40    /* do not skip blanks */
#define NOSKIP          0x40    /* do not skip blanks */
 
 
/*
/*
 * The following are used in numeric conversions only:
 * The following are used in numeric conversions only:
 * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
 * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
 */
 */
 
 
#define SIGNOK          0x80    /* +/- is (still) legal */
#define SIGNOK          0x80    /* +/- is (still) legal */
#define NDIGITS         0x100   /* no digits detected */
#define NDIGITS         0x100   /* no digits detected */
 
 
#define DPTOK           0x200   /* (float) decimal point is still legal */
#define DPTOK           0x200   /* (float) decimal point is still legal */
#define EXPOK           0x400   /* (float) exponent (e+3, etc) still legal */
#define EXPOK           0x400   /* (float) exponent (e+3, etc) still legal */
 
 
#define PFXOK           0x200   /* 0x prefix is (still) legal */
#define PFXOK           0x200   /* 0x prefix is (still) legal */
#define NZDIGITS        0x400   /* no zero digits detected */
#define NZDIGITS        0x400   /* no zero digits detected */
#define NNZDIGITS       0x800   /* no non-zero digits detected */
#define NNZDIGITS       0x800   /* no non-zero digits detected */
 
 
#define VECTOR          0x2000  /* v: vector */
#define VECTOR          0x2000  /* v: vector */
#define FIXEDPOINT      0x4000  /* r/R: fixed-point */
#define FIXEDPOINT      0x4000  /* r/R: fixed-point */
#define SIGNED          0x8000  /* r: signed fixed-point */
#define SIGNED          0x8000  /* r: signed fixed-point */
 
 
/*
/*
 * Conversion types.
 * Conversion types.
 */
 */
 
 
#define CT_CHAR         0        /* %c conversion */
#define CT_CHAR         0        /* %c conversion */
#define CT_CCL          1       /* %[...] conversion */
#define CT_CCL          1       /* %[...] conversion */
#define CT_STRING       2       /* %s conversion */
#define CT_STRING       2       /* %s conversion */
#define CT_INT          3       /* integer, i.e., strtol or strtoul */
#define CT_INT          3       /* integer, i.e., strtol or strtoul */
#define CT_FLOAT        4       /* floating, i.e., strtod */
#define CT_FLOAT        4       /* floating, i.e., strtod */
 
 
#if 0
#if 0
#define u_char unsigned char
#define u_char unsigned char
#endif
#endif
#define u_char char
#define u_char char
#define u_long unsigned long
#define u_long unsigned long
 
 
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
typedef unsigned long long u_long_long;
typedef unsigned long long u_long_long;
#endif
#endif
 
 
typedef union
typedef union
{
{
  char c[16] __attribute__ ((__aligned__ (16)));
  char c[16] __attribute__ ((__aligned__ (16)));
  short h[8];
  short h[8];
  long l[4];
  long l[4];
  int i[4];
  int i[4];
  float f[4];
  float f[4];
} vec_union;
} vec_union;
 
 
/*
/*
 * vfscanf
 * vfscanf
 */
 */
 
 
#define BufferEmpty (fp->_r <= 0 && __srefill(fp))
#define BufferEmpty (fp->_r <= 0 && __srefill(fp))
 
 
#ifndef _REENT_ONLY
#ifndef _REENT_ONLY
 
 
int
int
_DEFUN (vfscanf, (fp, fmt, ap),
_DEFUN (vfscanf, (fp, fmt, ap),
    register FILE *fp _AND
    register FILE *fp _AND
    _CONST char *fmt _AND
    _CONST char *fmt _AND
    va_list ap)
    va_list ap)
{
{
  CHECK_INIT(_REENT, fp);
  CHECK_INIT(_REENT, fp);
  return __svfscanf_r (_REENT, fp, fmt, ap);
  return __svfscanf_r (_REENT, fp, fmt, ap);
}
}
 
 
int
int
__svfscanf (fp, fmt0, ap)
__svfscanf (fp, fmt0, ap)
     register FILE *fp;
     register FILE *fp;
     char _CONST *fmt0;
     char _CONST *fmt0;
     va_list ap;
     va_list ap;
{
{
  return __svfscanf_r (_REENT, fp, fmt0, ap);
  return __svfscanf_r (_REENT, fp, fmt0, ap);
}
}
 
 
#endif /* !_REENT_ONLY */
#endif /* !_REENT_ONLY */
 
 
int
int
_DEFUN (_vfscanf_r, (data, fp, fmt, ap),
_DEFUN (_vfscanf_r, (data, fp, fmt, ap),
    struct _reent *data _AND
    struct _reent *data _AND
    register FILE *fp _AND
    register FILE *fp _AND
    _CONST char *fmt _AND
    _CONST char *fmt _AND
    va_list ap)
    va_list ap)
{
{
  return __svfscanf_r (data, fp, fmt, ap);
  return __svfscanf_r (data, fp, fmt, ap);
}
}
 
 
 
 
int
int
__svfscanf_r (rptr, fp, fmt0, ap)
__svfscanf_r (rptr, fp, fmt0, ap)
     struct _reent *rptr;
     struct _reent *rptr;
     register FILE *fp;
     register FILE *fp;
     char _CONST *fmt0;
     char _CONST *fmt0;
     va_list ap;
     va_list ap;
{
{
  register u_char *fmt = (u_char *) fmt0;
  register u_char *fmt = (u_char *) fmt0;
  register int c;               /* character from format, or conversion */
  register int c;               /* character from format, or conversion */
  register int type;            /* conversion type */
  register int type;            /* conversion type */
  register size_t width;        /* field width, or 0 */
  register size_t width;        /* field width, or 0 */
  register char *p;             /* points into all kinds of strings */
  register char *p;             /* points into all kinds of strings */
  register int n;               /* handy integer */
  register int n;               /* handy integer */
  register int flags;           /* flags as defined above */
  register int flags;           /* flags as defined above */
  register char *p0;            /* saves original value of p when necessary */
  register char *p0;            /* saves original value of p when necessary */
  int orig_flags;               /* saved flags used when processing vector */
  int orig_flags;               /* saved flags used when processing vector */
  int int_width;                /* tmp area to store width when processing int */
  int int_width;                /* tmp area to store width when processing int */
  int nassigned;                /* number of fields assigned */
  int nassigned;                /* number of fields assigned */
  int nread;                    /* number of characters consumed from fp */
  int nread;                    /* number of characters consumed from fp */
  int base = 0;                  /* base argument to strtol/strtoul */
  int base = 0;                  /* base argument to strtol/strtoul */
  int nbytes = 1;               /* number of bytes read from fmt string */
  int nbytes = 1;               /* number of bytes read from fmt string */
  wchar_t wc;                   /* wchar to use to read format string */
  wchar_t wc;                   /* wchar to use to read format string */
  char vec_sep;                 /* vector separator char */
  char vec_sep;                 /* vector separator char */
  char last_space_char;         /* last white-space char eaten - needed for vec support */
  char last_space_char;         /* last white-space char eaten - needed for vec support */
  int vec_read_count;           /* number of vector items to read separately */
  int vec_read_count;           /* number of vector items to read separately */
  int looped;                   /* has vector processing looped */
  int looped;                   /* has vector processing looped */
  u_long (*ccfn) () = 0; /* conversion function (strtol/strtoul) */
  u_long (*ccfn) () = 0; /* conversion function (strtol/strtoul) */
  char ccltab[256];             /* character class table for %[...] */
  char ccltab[256];             /* character class table for %[...] */
  char buf[BUF];                /* buffer for numeric conversions */
  char buf[BUF];                /* buffer for numeric conversions */
  vec_union vec_buf;
  vec_union vec_buf;
  char *lptr;                   /* literal pointer */
  char *lptr;                   /* literal pointer */
#ifdef _MB_CAPABLE
#ifdef _MB_CAPABLE
  mbstate_t state;                /* value to keep track of multibyte state */
  mbstate_t state;                /* value to keep track of multibyte state */
#endif
#endif
 
 
  char *ch_dest;
  char *ch_dest;
  short *sp;
  short *sp;
  int *ip;
  int *ip;
  float *flp;
  float *flp;
  _LONG_DOUBLE *ldp;
  _LONG_DOUBLE *ldp;
  double *dp;
  double *dp;
  long *lp;
  long *lp;
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
  long long *llp;
  long long *llp;
#else
#else
        u_long _uquad;
        u_long _uquad;
#endif
#endif
 
 
  /* `basefix' is used to avoid `if' tests in the integer scanner */
  /* `basefix' is used to avoid `if' tests in the integer scanner */
  static _CONST short basefix[17] =
  static _CONST short basefix[17] =
    {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
    {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
 
 
  nassigned = 0;
  nassigned = 0;
  nread = 0;
  nread = 0;
  for (;;)
  for (;;)
    {
    {
#ifndef _MB_CAPABLE
#ifndef _MB_CAPABLE
      wc = *fmt;
      wc = *fmt;
#else
#else
      memset (&state, '\0', sizeof (state));
      memset (&state, '\0', sizeof (state));
      nbytes = _mbtowc_r (rptr, &wc, fmt, MB_CUR_MAX, &state);
      nbytes = _mbtowc_r (rptr, &wc, fmt, MB_CUR_MAX, &state);
#endif
#endif
      fmt += nbytes;
      fmt += nbytes;
      if (wc == 0)
      if (wc == 0)
        return nassigned;
        return nassigned;
      if (nbytes == 1 && isspace (wc))
      if (nbytes == 1 && isspace (wc))
        {
        {
          for (;;)
          for (;;)
            {
            {
              if (BufferEmpty)
              if (BufferEmpty)
                return nassigned;
                return nassigned;
              if (!isspace (*fp->_p))
              if (!isspace (*fp->_p))
                break;
                break;
              nread++, fp->_r--, fp->_p++;
              nread++, fp->_r--, fp->_p++;
            }
            }
          continue;
          continue;
        }
        }
      if (wc != '%')
      if (wc != '%')
        goto literal;
        goto literal;
      width = 0;
      width = 0;
      flags = 0;
      flags = 0;
      vec_sep = ' ';
      vec_sep = ' ';
      vec_read_count = 0;
      vec_read_count = 0;
      looped = 0;
      looped = 0;
 
 
      /*
      /*
       * switch on the format.  continue if done; break once format
       * switch on the format.  continue if done; break once format
       * type is derived.
       * type is derived.
       */
       */
 
 
    again:
    again:
      c = *fmt++;
      c = *fmt++;
 
 
      switch (c)
      switch (c)
        {
        {
        case '%':
        case '%':
        literal:
        literal:
          lptr = fmt - nbytes;
          lptr = fmt - nbytes;
          for (n = 0; n < nbytes; ++n)
          for (n = 0; n < nbytes; ++n)
            {
            {
              if (BufferEmpty)
              if (BufferEmpty)
                goto input_failure;
                goto input_failure;
              if (*fp->_p != *lptr)
              if (*fp->_p != *lptr)
                goto match_failure;
                goto match_failure;
              fp->_r--, fp->_p++;
              fp->_r--, fp->_p++;
              nread++;
              nread++;
              ++lptr;
              ++lptr;
            }
            }
          continue;
          continue;
 
 
        case '*':
        case '*':
          flags |= SUPPRESS;
          flags |= SUPPRESS;
          goto again;
          goto again;
        case ',':
        case ',':
        case ';':
        case ';':
        case ':':
        case ':':
        case '_':
        case '_':
          if (flags == SUPPRESS || flags == 0)
          if (flags == SUPPRESS || flags == 0)
            vec_sep = c;
            vec_sep = c;
          goto again;
          goto again;
        case 'l':
        case 'l':
          if (flags & SHORT)
          if (flags & SHORT)
            continue; /* invalid format, don't process any further */
            continue; /* invalid format, don't process any further */
          if (flags & LONG)
          if (flags & LONG)
            {
            {
              flags &= ~LONG;
              flags &= ~LONG;
              flags &= ~VECTOR;
              flags &= ~VECTOR;
              flags |= LONGDBL;
              flags |= LONGDBL;
            }
            }
          else
          else
            {
            {
              flags |= LONG;
              flags |= LONG;
              if (flags & VECTOR)
              if (flags & VECTOR)
                vec_read_count = 4;
                vec_read_count = 4;
            }
            }
          goto again;
          goto again;
        case 'L':
        case 'L':
          flags |= LONGDBL;
          flags |= LONGDBL;
          flags &= ~VECTOR;
          flags &= ~VECTOR;
          goto again;
          goto again;
        case 'h':
        case 'h':
          flags |= SHORT;
          flags |= SHORT;
          if (flags & LONG)
          if (flags & LONG)
            continue;  /* invalid format, don't process any further */
            continue;  /* invalid format, don't process any further */
          if (flags & VECTOR)
          if (flags & VECTOR)
            vec_read_count = 8;
            vec_read_count = 8;
          goto again;
          goto again;
#ifdef __ALTIVEC__
#ifdef __ALTIVEC__
        case 'v':
        case 'v':
          flags |= VECTOR;
          flags |= VECTOR;
          vec_read_count = (flags & SHORT) ? 8 : ((flags & LONG) ? 4 : 16);
          vec_read_count = (flags & SHORT) ? 8 : ((flags & LONG) ? 4 : 16);
          goto again;
          goto again;
#endif
#endif
        case '0':
        case '0':
        case '1':
        case '1':
        case '2':
        case '2':
        case '3':
        case '3':
        case '4':
        case '4':
        case '5':
        case '5':
        case '6':
        case '6':
        case '7':
        case '7':
        case '8':
        case '8':
        case '9':
        case '9':
          width = width * 10 + c - '0';
          width = width * 10 + c - '0';
          goto again;
          goto again;
 
 
          /*
          /*
           * Conversions. Those marked `compat' are for
           * Conversions. Those marked `compat' are for
           * 4.[123]BSD compatibility.
           * 4.[123]BSD compatibility.
           *
           *
           * (According to ANSI, E and X formats are supposed to
           * (According to ANSI, E and X formats are supposed to
           * the same as e and x.  Sorry about that.)
           * the same as e and x.  Sorry about that.)
           */
           */
 
 
        case 'D':               /* compat */
        case 'D':               /* compat */
          flags |= LONG;
          flags |= LONG;
          /* FALLTHROUGH */
          /* FALLTHROUGH */
        case 'd':
        case 'd':
          type = CT_INT;
          type = CT_INT;
          ccfn = (u_long (*)())_strtol_r;
          ccfn = (u_long (*)())_strtol_r;
          base = 10;
          base = 10;
          break;
          break;
 
 
        case 'i':
        case 'i':
          type = CT_INT;
          type = CT_INT;
          ccfn = (u_long (*)())_strtol_r;
          ccfn = (u_long (*)())_strtol_r;
          base = 0;
          base = 0;
          break;
          break;
 
 
        case 'O':               /* compat */
        case 'O':               /* compat */
          flags |= LONG;
          flags |= LONG;
          /* FALLTHROUGH */
          /* FALLTHROUGH */
        case 'o':
        case 'o':
          type = CT_INT;
          type = CT_INT;
          ccfn = _strtoul_r;
          ccfn = _strtoul_r;
          base = 8;
          base = 8;
          break;
          break;
 
 
        case 'u':
        case 'u':
          type = CT_INT;
          type = CT_INT;
          ccfn = _strtoul_r;
          ccfn = _strtoul_r;
          base = 10;
          base = 10;
          break;
          break;
 
 
        case 'X':               /* compat   XXX */
        case 'X':               /* compat   XXX */
        case 'x':
        case 'x':
          flags |= PFXOK;       /* enable 0x prefixing */
          flags |= PFXOK;       /* enable 0x prefixing */
          type = CT_INT;
          type = CT_INT;
          ccfn = _strtoul_r;
          ccfn = _strtoul_r;
          base = 16;
          base = 16;
          break;
          break;
 
 
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
        case 'E':               /* compat   XXX */
        case 'E':               /* compat   XXX */
        case 'G':               /* compat   XXX */
        case 'G':               /* compat   XXX */
/* ANSI says that E,G and X behave the same way as e,g,x */
/* ANSI says that E,G and X behave the same way as e,g,x */
          /* FALLTHROUGH */
          /* FALLTHROUGH */
        case 'e':
        case 'e':
        case 'f':
        case 'f':
        case 'g':
        case 'g':
          type = CT_FLOAT;
          type = CT_FLOAT;
          if (flags & VECTOR)
          if (flags & VECTOR)
            vec_read_count = 4;
            vec_read_count = 4;
          break;
          break;
 
 
# ifdef __SPE__
# ifdef __SPE__
          /* treat fixed-point like %f floating point */
          /* treat fixed-point like %f floating point */
        case 'r':
        case 'r':
          flags |= SIGNED;
          flags |= SIGNED;
          /* fallthrough */
          /* fallthrough */
        case 'R':
        case 'R':
          flags |= FIXEDPOINT;
          flags |= FIXEDPOINT;
          type = CT_FLOAT;
          type = CT_FLOAT;
          break;
          break;
# endif
# endif
#endif
#endif
 
 
        case 's':
        case 's':
          flags &= ~VECTOR;
          flags &= ~VECTOR;
          type = CT_STRING;
          type = CT_STRING;
          break;
          break;
 
 
        case '[':
        case '[':
          fmt = __sccl (ccltab, fmt);
          fmt = __sccl (ccltab, fmt);
          flags |= NOSKIP;
          flags |= NOSKIP;
          flags &= ~VECTOR;
          flags &= ~VECTOR;
          type = CT_CCL;
          type = CT_CCL;
          break;
          break;
 
 
        case 'c':
        case 'c':
          flags |= NOSKIP;
          flags |= NOSKIP;
          type = CT_CHAR;
          type = CT_CHAR;
          if (flags & VECTOR)
          if (flags & VECTOR)
            {
            {
              /* not allowed to have h or l with c specifier */
              /* not allowed to have h or l with c specifier */
              if (flags & (LONG | SHORT))
              if (flags & (LONG | SHORT))
                continue;  /* invalid format don't process any further */
                continue;  /* invalid format don't process any further */
              width = 0;
              width = 0;
              vec_read_count = 16;
              vec_read_count = 16;
            }
            }
          break;
          break;
 
 
        case 'p':               /* pointer format is like hex */
        case 'p':               /* pointer format is like hex */
          flags |= POINTER | PFXOK;
          flags |= POINTER | PFXOK;
          type = CT_INT;
          type = CT_INT;
          ccfn = _strtoul_r;
          ccfn = _strtoul_r;
          base = 16;
          base = 16;
          break;
          break;
 
 
        case 'n':
        case 'n':
          if (flags & SUPPRESS) /* ??? */
          if (flags & SUPPRESS) /* ??? */
            continue;
            continue;
          flags &= ~VECTOR;
          flags &= ~VECTOR;
          if (flags & SHORT)
          if (flags & SHORT)
            {
            {
              sp = va_arg (ap, short *);
              sp = va_arg (ap, short *);
              *sp = nread;
              *sp = nread;
            }
            }
          else if (flags & LONG)
          else if (flags & LONG)
            {
            {
              lp = va_arg (ap, long *);
              lp = va_arg (ap, long *);
              *lp = nread;
              *lp = nread;
            }
            }
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
          else if (flags & LONGDBL)
          else if (flags & LONGDBL)
            {
            {
              llp = va_arg (ap, long long*);
              llp = va_arg (ap, long long*);
              *llp = nread;
              *llp = nread;
            }
            }
#endif
#endif
          else
          else
            {
            {
              ip = va_arg (ap, int *);
              ip = va_arg (ap, int *);
              *ip = nread;
              *ip = nread;
            }
            }
          continue;
          continue;
 
 
          /*
          /*
           * Disgusting backwards compatibility hacks.  XXX
           * Disgusting backwards compatibility hacks.  XXX
           */
           */
        case '\0':              /* compat */
        case '\0':              /* compat */
          return EOF;
          return EOF;
 
 
        default:                /* compat */
        default:                /* compat */
          if (isupper (c))
          if (isupper (c))
            flags |= LONG;
            flags |= LONG;
          type = CT_INT;
          type = CT_INT;
          ccfn = (u_long (*)())_strtol_r;
          ccfn = (u_long (*)())_strtol_r;
          base = 10;
          base = 10;
          break;
          break;
        }
        }
 
 
    process:
    process:
      /*
      /*
       * We have a conversion that requires input.
       * We have a conversion that requires input.
       */
       */
      if (BufferEmpty)
      if (BufferEmpty)
        goto input_failure;
        goto input_failure;
 
 
      /*
      /*
       * Consume leading white space, except for formats that
       * Consume leading white space, except for formats that
       * suppress this.
       * suppress this.
       */
       */
      last_space_char = '\0';
      last_space_char = '\0';
 
 
      if ((flags & NOSKIP) == 0)
      if ((flags & NOSKIP) == 0)
        {
        {
          while (isspace (*fp->_p))
          while (isspace (*fp->_p))
            {
            {
              last_space_char = *fp->_p;
              last_space_char = *fp->_p;
              nread++;
              nread++;
              if (--fp->_r > 0)
              if (--fp->_r > 0)
                fp->_p++;
                fp->_p++;
              else
              else
#ifndef CYGNUS_NEC
#ifndef CYGNUS_NEC
              if (__srefill (fp))
              if (__srefill (fp))
#endif
#endif
                goto input_failure;
                goto input_failure;
            }
            }
          /*
          /*
           * Note that there is at least one character in the
           * Note that there is at least one character in the
           * buffer, so conversions that do not set NOSKIP ca
           * buffer, so conversions that do not set NOSKIP ca
           * no longer result in an input failure.
           * no longer result in an input failure.
           */
           */
        }
        }
 
 
      /* for vector formats process separator characters after first loop */
      /* for vector formats process separator characters after first loop */
      if (looped && (flags & VECTOR))
      if (looped && (flags & VECTOR))
        {
        {
          flags = orig_flags;
          flags = orig_flags;
          /* all formats other than default char have a separator char */
          /* all formats other than default char have a separator char */
          if (vec_sep != ' ' || type != CT_CHAR)
          if (vec_sep != ' ' || type != CT_CHAR)
            {
            {
              if (vec_sep == ' ' && last_space_char != ' ' ||
              if (vec_sep == ' ' && last_space_char != ' ' ||
                  vec_sep != ' ' && *fp->_p != vec_sep)
                  vec_sep != ' ' && *fp->_p != vec_sep)
                goto match_failure;
                goto match_failure;
              if (vec_sep != ' ')
              if (vec_sep != ' ')
                {
                {
                  nread++;
                  nread++;
                  if (--fp->_r > 0)
                  if (--fp->_r > 0)
                    fp->_p++;
                    fp->_p++;
                  else
                  else
#ifndef CYGNUS_NEC
#ifndef CYGNUS_NEC
                    if (__srefill (fp))
                    if (__srefill (fp))
#endif
#endif
                      goto input_failure;
                      goto input_failure;
                }
                }
            }
            }
          /* after eating the separator char, we must eat any white-space
          /* after eating the separator char, we must eat any white-space
             after the separator char that precedes the data to convert */
             after the separator char that precedes the data to convert */
          if ((flags & NOSKIP) == 0)
          if ((flags & NOSKIP) == 0)
            {
            {
              while (isspace (*fp->_p))
              while (isspace (*fp->_p))
                {
                {
                  last_space_char = *fp->_p;
                  last_space_char = *fp->_p;
                  nread++;
                  nread++;
                  if (--fp->_r > 0)
                  if (--fp->_r > 0)
                    fp->_p++;
                    fp->_p++;
                  else
                  else
#ifndef CYGNUS_NEC
#ifndef CYGNUS_NEC
                    if (__srefill (fp))
                    if (__srefill (fp))
#endif
#endif
                      goto input_failure;
                      goto input_failure;
                }
                }
            }
            }
 
 
        }
        }
      else /* save to counter-act changes made to flags when processing */
      else /* save to counter-act changes made to flags when processing */
        orig_flags = flags;
        orig_flags = flags;
 
 
      /*
      /*
       * Do the conversion.
       * Do the conversion.
       */
       */
      switch (type)
      switch (type)
        {
        {
 
 
        case CT_CHAR:
        case CT_CHAR:
          /* scan arbitrary characters (sets NOSKIP) */
          /* scan arbitrary characters (sets NOSKIP) */
          if (width == 0)
          if (width == 0)
            width = 1;
            width = 1;
          if (flags & SUPPRESS)
          if (flags & SUPPRESS)
            {
            {
              size_t sum = 0;
              size_t sum = 0;
 
 
              for (;;)
              for (;;)
                {
                {
                  if ((n = fp->_r) < (int)width)
                  if ((n = fp->_r) < (int)width)
                    {
                    {
                      sum += n;
                      sum += n;
                      width -= n;
                      width -= n;
                      fp->_p += n;
                      fp->_p += n;
#ifndef CYGNUS_NEC
#ifndef CYGNUS_NEC
                      if (__srefill (fp))
                      if (__srefill (fp))
                        {
                        {
#endif
#endif
                          if (sum == 0)
                          if (sum == 0)
                            goto input_failure;
                            goto input_failure;
                          break;
                          break;
#ifndef CYGNUS_NEC
#ifndef CYGNUS_NEC
                        }
                        }
#endif
#endif
                    }
                    }
                  else
                  else
                    {
                    {
                      sum += width;
                      sum += width;
                      fp->_r -= width;
                      fp->_r -= width;
                      fp->_p += width;
                      fp->_p += width;
                      break;
                      break;
                    }
                    }
                }
                }
              nread += sum;
              nread += sum;
            }
            }
          else
          else
            {
            {
              int n = width;
              int n = width;
              if (!looped)
              if (!looped)
                {
                {
                  if (flags & VECTOR)
                  if (flags & VECTOR)
                    ch_dest = vec_buf.c;
                    ch_dest = vec_buf.c;
                  else
                  else
                    ch_dest = va_arg (ap, char *);
                    ch_dest = va_arg (ap, char *);
                }
                }
#ifdef CYGNUS_NEC
#ifdef CYGNUS_NEC
              /* Kludge city for the moment */
              /* Kludge city for the moment */
              if (fp->_r == 0)
              if (fp->_r == 0)
                goto input_failure;
                goto input_failure;
 
 
              while (n && fp->_r)
              while (n && fp->_r)
                {
                {
                  *ch_dest++ = *(fp->_p++);
                  *ch_dest++ = *(fp->_p++);
                  n--;
                  n--;
                  fp->_r--;
                  fp->_r--;
                  nread++;
                  nread++;
                }
                }
#else
#else
              size_t r = fread (ch_dest, 1, width, fp);
              size_t r = fread (ch_dest, 1, width, fp);
 
 
              if (r == 0)
              if (r == 0)
                goto input_failure;
                goto input_failure;
              nread += r;
              nread += r;
              ch_dest += r;
              ch_dest += r;
#endif
#endif
              if (!(flags & VECTOR))
              if (!(flags & VECTOR))
                nassigned++;
                nassigned++;
            }
            }
          break;
          break;
 
 
        case CT_CCL:
        case CT_CCL:
          /* scan a (nonempty) character class (sets NOSKIP) */
          /* scan a (nonempty) character class (sets NOSKIP) */
          if (width == 0)
          if (width == 0)
            width = ~0;          /* `infinity' */
            width = ~0;          /* `infinity' */
          /* take only those things in the class */
          /* take only those things in the class */
          if (flags & SUPPRESS)
          if (flags & SUPPRESS)
            {
            {
              n = 0;
              n = 0;
              while (ccltab[*fp->_p])
              while (ccltab[*fp->_p])
                {
                {
                  n++, fp->_r--, fp->_p++;
                  n++, fp->_r--, fp->_p++;
                  if (--width == 0)
                  if (--width == 0)
                    break;
                    break;
                  if (BufferEmpty)
                  if (BufferEmpty)
                    {
                    {
                      if (n == 0)
                      if (n == 0)
                        goto input_failure;
                        goto input_failure;
                      break;
                      break;
                    }
                    }
                }
                }
              if (n == 0)
              if (n == 0)
                goto match_failure;
                goto match_failure;
            }
            }
          else
          else
            {
            {
              p0 = p = va_arg (ap, char *);
              p0 = p = va_arg (ap, char *);
              while (ccltab[*fp->_p])
              while (ccltab[*fp->_p])
                {
                {
                  fp->_r--;
                  fp->_r--;
                  *p++ = *fp->_p++;
                  *p++ = *fp->_p++;
                  if (--width == 0)
                  if (--width == 0)
                    break;
                    break;
                  if (BufferEmpty)
                  if (BufferEmpty)
                    {
                    {
                      if (p == p0)
                      if (p == p0)
                        goto input_failure;
                        goto input_failure;
                      break;
                      break;
                    }
                    }
                }
                }
              n = p - p0;
              n = p - p0;
              if (n == 0)
              if (n == 0)
                goto match_failure;
                goto match_failure;
              *p = 0;
              *p = 0;
              nassigned++;
              nassigned++;
            }
            }
          nread += n;
          nread += n;
          break;
          break;
 
 
        case CT_STRING:
        case CT_STRING:
          /* like CCL, but zero-length string OK, & no NOSKIP */
          /* like CCL, but zero-length string OK, & no NOSKIP */
          if (width == 0)
          if (width == 0)
            width = ~0;
            width = ~0;
          if (flags & SUPPRESS)
          if (flags & SUPPRESS)
            {
            {
              n = 0;
              n = 0;
              while (!isspace (*fp->_p))
              while (!isspace (*fp->_p))
                {
                {
                  n++, fp->_r--, fp->_p++;
                  n++, fp->_r--, fp->_p++;
                  if (--width == 0)
                  if (--width == 0)
                    break;
                    break;
                  if (BufferEmpty)
                  if (BufferEmpty)
                    break;
                    break;
                }
                }
              nread += n;
              nread += n;
            }
            }
          else
          else
            {
            {
              p0 = p = va_arg (ap, char *);
              p0 = p = va_arg (ap, char *);
              while (!isspace (*fp->_p))
              while (!isspace (*fp->_p))
                {
                {
                  fp->_r--;
                  fp->_r--;
                  *p++ = *fp->_p++;
                  *p++ = *fp->_p++;
                  if (--width == 0)
                  if (--width == 0)
                    break;
                    break;
                  if (BufferEmpty)
                  if (BufferEmpty)
                    break;
                    break;
                }
                }
              *p = 0;
              *p = 0;
              nread += p - p0;
              nread += p - p0;
              nassigned++;
              nassigned++;
            }
            }
          continue;
          continue;
 
 
        case CT_INT:
        case CT_INT:
          {
          {
          unsigned int_width_left = 0;
          unsigned int_width_left = 0;
          int skips = 0;
          int skips = 0;
          int_width = width;
          int_width = width;
#ifdef hardway
#ifdef hardway
          if (int_width == 0 || int_width > sizeof (buf) - 1)
          if (int_width == 0 || int_width > sizeof (buf) - 1)
#else
#else
          /* size_t is unsigned, hence this optimisation */
          /* size_t is unsigned, hence this optimisation */
          if (int_width - 1 > sizeof (buf) - 2)
          if (int_width - 1 > sizeof (buf) - 2)
#endif
#endif
            {
            {
              int_width_left = width - (sizeof (buf) - 1);
              int_width_left = width - (sizeof (buf) - 1);
              int_width = sizeof (buf) - 1;
              int_width = sizeof (buf) - 1;
            }
            }
          flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;
          flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;
          for (p = buf; int_width; int_width--)
          for (p = buf; int_width; int_width--)
            {
            {
              c = *fp->_p;
              c = *fp->_p;
              /*
              /*
               * Switch on the character; `goto ok' if we
               * Switch on the character; `goto ok' if we
               * accept it as a part of number.
               * accept it as a part of number.
               */
               */
              switch (c)
              switch (c)
                {
                {
                  /*
                  /*
                   * The digit 0 is always legal, but is special.
                   * The digit 0 is always legal, but is special.
                   * For %i conversions, if no digits (zero or nonzero)
                   * For %i conversions, if no digits (zero or nonzero)
                   * have been scanned (only signs), we will have base==0.
                   * have been scanned (only signs), we will have base==0.
                   * In that case, we should set it to 8 and enable 0x
                   * In that case, we should set it to 8 and enable 0x
                   * prefixing. Also, if we have not scanned zero digits
                   * prefixing. Also, if we have not scanned zero digits
                   * before this, do not turn off prefixing (someone else
                   * before this, do not turn off prefixing (someone else
                   * will turn it off if we have scanned any nonzero digits).
                   * will turn it off if we have scanned any nonzero digits).
                   */
                   */
                case '0':
                case '0':
                  if (! (flags & NNZDIGITS))
                  if (! (flags & NNZDIGITS))
                    goto ok;
                    goto ok;
                  if (base == 0)
                  if (base == 0)
                    {
                    {
                      base = 8;
                      base = 8;
                      flags |= PFXOK;
                      flags |= PFXOK;
                    }
                    }
                  if (flags & NZDIGITS)
                  if (flags & NZDIGITS)
                    {
                    {
                      flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
                      flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
                      goto ok;
                      goto ok;
                    }
                    }
                  flags &= ~(SIGNOK | PFXOK | NDIGITS);
                  flags &= ~(SIGNOK | PFXOK | NDIGITS);
                  if (int_width_left)
                  if (int_width_left)
                    {
                    {
                      int_width_left--;
                      int_width_left--;
                      int_width++;
                      int_width++;
                    }
                    }
                  ++skips;
                  ++skips;
                  goto skip;
                  goto skip;
 
 
                  /* 1 through 7 always legal */
                  /* 1 through 7 always legal */
                case '1':
                case '1':
                case '2':
                case '2':
                case '3':
                case '3':
                case '4':
                case '4':
                case '5':
                case '5':
                case '6':
                case '6':
                case '7':
                case '7':
                  base = basefix[base];
                  base = basefix[base];
                  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
                  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
                  goto ok;
                  goto ok;
 
 
                  /* digits 8 and 9 ok iff decimal or hex */
                  /* digits 8 and 9 ok iff decimal or hex */
                case '8':
                case '8':
                case '9':
                case '9':
                  base = basefix[base];
                  base = basefix[base];
                  if (base <= 8)
                  if (base <= 8)
                    break;      /* not legal here */
                    break;      /* not legal here */
                  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
                  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
                  goto ok;
                  goto ok;
 
 
                  /* letters ok iff hex */
                  /* letters ok iff hex */
                case 'A':
                case 'A':
                case 'B':
                case 'B':
                case 'C':
                case 'C':
                case 'D':
                case 'D':
                case 'E':
                case 'E':
                case 'F':
                case 'F':
                case 'a':
                case 'a':
                case 'b':
                case 'b':
                case 'c':
                case 'c':
                case 'd':
                case 'd':
                case 'e':
                case 'e':
                case 'f':
                case 'f':
                  /* no need to fix base here */
                  /* no need to fix base here */
                  if (base <= 10)
                  if (base <= 10)
                    break;      /* not legal here */
                    break;      /* not legal here */
                  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
                  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
                  goto ok;
                  goto ok;
 
 
                  /* sign ok only as first character */
                  /* sign ok only as first character */
                case '+':
                case '+':
                case '-':
                case '-':
                  if (flags & SIGNOK)
                  if (flags & SIGNOK)
                    {
                    {
                      flags &= ~SIGNOK;
                      flags &= ~SIGNOK;
                      goto ok;
                      goto ok;
                    }
                    }
                  break;
                  break;
 
 
                  /* x ok iff flag still set & 2nd char */
                  /* x ok iff flag still set & 2nd char */
                case 'x':
                case 'x':
                case 'X':
                case 'X':
                  if (flags & PFXOK && p == buf + 1)
                  if (flags & PFXOK && p == buf + 1)
                    {
                    {
                      base = 16;/* if %i */
                      base = 16;/* if %i */
                      flags &= ~PFXOK;
                      flags &= ~PFXOK;
                      /* We must reset the NZDIGITS and NDIGITS
                      /* We must reset the NZDIGITS and NDIGITS
                         flags that would have been unset by seeing
                         flags that would have been unset by seeing
                         the zero that preceded the X or x.  */
                         the zero that preceded the X or x.  */
                      flags |= NZDIGITS | NDIGITS;
                      flags |= NZDIGITS | NDIGITS;
                      goto ok;
                      goto ok;
                    }
                    }
                  break;
                  break;
                }
                }
 
 
              /*
              /*
               * If we got here, c is not a legal character
               * If we got here, c is not a legal character
               * for a number.  Stop accumulating digits.
               * for a number.  Stop accumulating digits.
               */
               */
              break;
              break;
            ok:
            ok:
              /*
              /*
               * c is legal: store it and look at the next.
               * c is legal: store it and look at the next.
               */
               */
              *p++ = c;
              *p++ = c;
            skip:
            skip:
              if (--fp->_r > 0)
              if (--fp->_r > 0)
                fp->_p++;
                fp->_p++;
              else
              else
#ifndef CYGNUS_NEC
#ifndef CYGNUS_NEC
              if (__srefill (fp))
              if (__srefill (fp))
#endif
#endif
                break;          /* EOF */
                break;          /* EOF */
            }
            }
          /*
          /*
           * If we had only a sign, it is no good; push back the sign.
           * If we had only a sign, it is no good; push back the sign.
           * If the number ends in `x', it was [sign] '0' 'x', so push back
           * If the number ends in `x', it was [sign] '0' 'x', so push back
           * the x and treat it as [sign] '0'.
           * the x and treat it as [sign] '0'.
           */
           */
          if (flags & NDIGITS)
          if (flags & NDIGITS)
            {
            {
              if (p > buf)
              if (p > buf)
                _CAST_VOID ungetc (*(u_char *)-- p, fp);
                _CAST_VOID ungetc (*(u_char *)-- p, fp);
              goto match_failure;
              goto match_failure;
            }
            }
          c = ((u_char *) p)[-1];
          c = ((u_char *) p)[-1];
          if (c == 'x' || c == 'X')
          if (c == 'x' || c == 'X')
            {
            {
              --p;
              --p;
              /*(void)*/ ungetc (c, fp);
              /*(void)*/ ungetc (c, fp);
            }
            }
          if ((flags & SUPPRESS) == 0)
          if ((flags & SUPPRESS) == 0)
            {
            {
              u_long res;
              u_long res;
 
 
              *p = 0;
              *p = 0;
              res = (*ccfn) (rptr, buf, (char **) NULL, base);
              res = (*ccfn) (rptr, buf, (char **) NULL, base);
              if ((flags & POINTER) && !(flags & VECTOR))
              if ((flags & POINTER) && !(flags & VECTOR))
                *(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
                *(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
              else if (flags & SHORT)
              else if (flags & SHORT)
                {
                {
                  if (!(flags & VECTOR))
                  if (!(flags & VECTOR))
                    sp = va_arg (ap, short *);
                    sp = va_arg (ap, short *);
                  else if (!looped)
                  else if (!looped)
                    sp = vec_buf.h;
                    sp = vec_buf.h;
                  *sp++ = res;
                  *sp++ = res;
                }
                }
              else if (flags & LONG)
              else if (flags & LONG)
                {
                {
                  if (!(flags & VECTOR))
                  if (!(flags & VECTOR))
                    lp = va_arg (ap, long *);
                    lp = va_arg (ap, long *);
                  else if (!looped)
                  else if (!looped)
                    lp = vec_buf.l;
                    lp = vec_buf.l;
                  *lp++ = res;
                  *lp++ = res;
                }
                }
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
              else if (flags & LONGDBL)
              else if (flags & LONGDBL)
                {
                {
                  u_long_long resll;
                  u_long_long resll;
                  if (ccfn == _strtoul_r)
                  if (ccfn == _strtoul_r)
                    resll = _strtoull_r (rptr, buf, (char **) NULL, base);
                    resll = _strtoull_r (rptr, buf, (char **) NULL, base);
                  else
                  else
                    resll = _strtoll_r (rptr, buf, (char **) NULL, base);
                    resll = _strtoll_r (rptr, buf, (char **) NULL, base);
                  llp = va_arg (ap, long long*);
                  llp = va_arg (ap, long long*);
                  *llp = resll;
                  *llp = resll;
                }
                }
#endif
#endif
              else
              else
                {
                {
                  if (!(flags & VECTOR))
                  if (!(flags & VECTOR))
                    {
                    {
                      ip = va_arg (ap, int *);
                      ip = va_arg (ap, int *);
                      *ip++ = res;
                      *ip++ = res;
                    }
                    }
                  else
                  else
                    {
                    {
                      if (!looped)
                      if (!looped)
                        ch_dest = vec_buf.c;
                        ch_dest = vec_buf.c;
                      *ch_dest++ = (char)res;
                      *ch_dest++ = (char)res;
                    }
                    }
                }
                }
              if (!(flags & VECTOR))
              if (!(flags & VECTOR))
                nassigned++;
                nassigned++;
            }
            }
          nread += p - buf + skips;
          nread += p - buf + skips;
          break;
          break;
          }
          }
 
 
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
        case CT_FLOAT:
        case CT_FLOAT:
        {
        {
          /* scan a floating point number as if by strtod */
          /* scan a floating point number as if by strtod */
          /* This code used to assume that the number of digits is reasonable.
          /* This code used to assume that the number of digits is reasonable.
             However, ANSI / ISO C makes no such stipulation; we have to get
             However, ANSI / ISO C makes no such stipulation; we have to get
             exact results even when there is an unreasonable amount of
             exact results even when there is an unreasonable amount of
             leading zeroes.  */
             leading zeroes.  */
          long leading_zeroes = 0;
          long leading_zeroes = 0;
          long zeroes, exp_adjust;
          long zeroes, exp_adjust;
          char *exp_start = NULL;
          char *exp_start = NULL;
          unsigned fl_width = width;
          unsigned fl_width = width;
          unsigned width_left = 0;
          unsigned width_left = 0;
#ifdef hardway
#ifdef hardway
          if (fl_width == 0 || fl_width > sizeof (buf) - 1)
          if (fl_width == 0 || fl_width > sizeof (buf) - 1)
#else
#else
          /* size_t is unsigned, hence this optimisation */
          /* size_t is unsigned, hence this optimisation */
          if (fl_width - 1 > sizeof (buf) - 2)
          if (fl_width - 1 > sizeof (buf) - 2)
#endif
#endif
            {
            {
              width_left = fl_width - (sizeof (buf) - 1);
              width_left = fl_width - (sizeof (buf) - 1);
              fl_width = sizeof (buf) - 1;
              fl_width = sizeof (buf) - 1;
            }
            }
          flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
          flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
          zeroes = 0;
          zeroes = 0;
          exp_adjust = 0;
          exp_adjust = 0;
          for (p = buf; fl_width; )
          for (p = buf; fl_width; )
            {
            {
              c = *fp->_p;
              c = *fp->_p;
              /*
              /*
               * This code mimicks the integer conversion
               * This code mimicks the integer conversion
               * code, but is much simpler.
               * code, but is much simpler.
               */
               */
              switch (c)
              switch (c)
                {
                {
 
 
                case '0':
                case '0':
                  if (flags & NDIGITS)
                  if (flags & NDIGITS)
                    {
                    {
                      flags &= ~SIGNOK;
                      flags &= ~SIGNOK;
                      zeroes++;
                      zeroes++;
                      if (width_left)
                      if (width_left)
                        {
                        {
                          width_left--;
                          width_left--;
                          fl_width++;
                          fl_width++;
                        }
                        }
                      goto fskip;
                      goto fskip;
                    }
                    }
                  /* Fall through.  */
                  /* Fall through.  */
                case '1':
                case '1':
                case '2':
                case '2':
                case '3':
                case '3':
                case '4':
                case '4':
                case '5':
                case '5':
                case '6':
                case '6':
                case '7':
                case '7':
                case '8':
                case '8':
                case '9':
                case '9':
                  flags &= ~(SIGNOK | NDIGITS);
                  flags &= ~(SIGNOK | NDIGITS);
                  goto fok;
                  goto fok;
 
 
                case '+':
                case '+':
                case '-':
                case '-':
                  if (flags & SIGNOK)
                  if (flags & SIGNOK)
                    {
                    {
                      flags &= ~SIGNOK;
                      flags &= ~SIGNOK;
                      goto fok;
                      goto fok;
                    }
                    }
                  break;
                  break;
                case '.':
                case '.':
                  if (flags & DPTOK)
                  if (flags & DPTOK)
                    {
                    {
                      flags &= ~(SIGNOK | DPTOK);
                      flags &= ~(SIGNOK | DPTOK);
                      leading_zeroes = zeroes;
                      leading_zeroes = zeroes;
                      goto fok;
                      goto fok;
                    }
                    }
                  break;
                  break;
                case 'e':
                case 'e':
                case 'E':
                case 'E':
                  /* no exponent without some digits */
                  /* no exponent without some digits */
                  if ((flags & (NDIGITS | EXPOK)) == EXPOK
                  if ((flags & (NDIGITS | EXPOK)) == EXPOK
                      || ((flags & EXPOK) && zeroes))
                      || ((flags & EXPOK) && zeroes))
                    {
                    {
                      if (! (flags & DPTOK))
                      if (! (flags & DPTOK))
                        {
                        {
                          exp_adjust = zeroes - leading_zeroes;
                          exp_adjust = zeroes - leading_zeroes;
                          exp_start = p;
                          exp_start = p;
                        }
                        }
                      flags =
                      flags =
                        (flags & ~(EXPOK | DPTOK)) |
                        (flags & ~(EXPOK | DPTOK)) |
                        SIGNOK | NDIGITS;
                        SIGNOK | NDIGITS;
                      zeroes = 0;
                      zeroes = 0;
                      goto fok;
                      goto fok;
                    }
                    }
                  break;
                  break;
                }
                }
              break;
              break;
            fok:
            fok:
              *p++ = c;
              *p++ = c;
            fskip:
            fskip:
              fl_width--;
              fl_width--;
              ++nread;
              ++nread;
              if (--fp->_r > 0)
              if (--fp->_r > 0)
                fp->_p++;
                fp->_p++;
              else
              else
#ifndef CYGNUS_NEC
#ifndef CYGNUS_NEC
              if (__srefill (fp))
              if (__srefill (fp))
#endif
#endif
                break;          /* EOF */
                break;          /* EOF */
            }
            }
          if (zeroes)
          if (zeroes)
            flags &= ~NDIGITS;
            flags &= ~NDIGITS;
          /*
          /*
           * If no digits, might be missing exponent digits
           * If no digits, might be missing exponent digits
           * (just give back the exponent) or might be missing
           * (just give back the exponent) or might be missing
           * regular digits, but had sign and/or decimal point.
           * regular digits, but had sign and/or decimal point.
           */
           */
          if (flags & NDIGITS)
          if (flags & NDIGITS)
            {
            {
              if (flags & EXPOK)
              if (flags & EXPOK)
                {
                {
                  /* no digits at all */
                  /* no digits at all */
                  while (p > buf)
                  while (p > buf)
                    {
                    {
                      ungetc (*(u_char *)-- p, fp);
                      ungetc (*(u_char *)-- p, fp);
                      --nread;
                      --nread;
                    }
                    }
                  goto match_failure;
                  goto match_failure;
                }
                }
              /* just a bad exponent (e and maybe sign) */
              /* just a bad exponent (e and maybe sign) */
              c = *(u_char *)-- p;
              c = *(u_char *)-- p;
              --nread;
              --nread;
              if (c != 'e' && c != 'E')
              if (c != 'e' && c != 'E')
                {
                {
                  _CAST_VOID ungetc (c, fp);    /* sign */
                  _CAST_VOID ungetc (c, fp);    /* sign */
                  c = *(u_char *)-- p;
                  c = *(u_char *)-- p;
                  --nread;
                  --nread;
                }
                }
              _CAST_VOID ungetc (c, fp);
              _CAST_VOID ungetc (c, fp);
            }
            }
          if ((flags & SUPPRESS) == 0)
          if ((flags & SUPPRESS) == 0)
            {
            {
#ifdef _NO_LONGDBL
#ifdef _NO_LONGDBL
              double res;
              double res;
#else  /* !_NO_LONG_DBL */
#else  /* !_NO_LONG_DBL */
              long double res;
              long double res;
#endif /* !_NO_LONG_DBL */
#endif /* !_NO_LONG_DBL */
              long new_exp = 0;
              long new_exp = 0;
 
 
              *p = 0;
              *p = 0;
              if ((flags & (DPTOK | EXPOK)) == EXPOK)
              if ((flags & (DPTOK | EXPOK)) == EXPOK)
                {
                {
                  exp_adjust = zeroes - leading_zeroes;
                  exp_adjust = zeroes - leading_zeroes;
                  new_exp = -exp_adjust;
                  new_exp = -exp_adjust;
                  exp_start = p;
                  exp_start = p;
                }
                }
              else if (exp_adjust)
              else if (exp_adjust)
                new_exp = _strtol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;
                new_exp = _strtol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;
              if (exp_adjust)
              if (exp_adjust)
                {
                {
 
 
                  /* If there might not be enough space for the new exponent,
                  /* If there might not be enough space for the new exponent,
                     truncate some trailing digits to make room.  */
                     truncate some trailing digits to make room.  */
                  if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)
                  if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)
                    exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
                    exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
                 sprintf (exp_start, "e%ld", new_exp);
                 sprintf (exp_start, "e%ld", new_exp);
                }
                }
#ifdef __SPE__
#ifdef __SPE__
              if (flags & FIXEDPOINT)
              if (flags & FIXEDPOINT)
                {
                {
                  __uint64_t ufix64;
                  __uint64_t ufix64;
                  if (flags & SIGNED)
                  if (flags & SIGNED)
                    ufix64 = (__uint64_t)_strtosfix64_r (rptr, buf, NULL);
                    ufix64 = (__uint64_t)_strtosfix64_r (rptr, buf, NULL);
                  else
                  else
                    ufix64 = _strtoufix64_r (rptr, buf, NULL);
                    ufix64 = _strtoufix64_r (rptr, buf, NULL);
                  if (flags & SHORT)
                  if (flags & SHORT)
                    {
                    {
                      __uint16_t *sp = va_arg (ap, __uint16_t *);
                      __uint16_t *sp = va_arg (ap, __uint16_t *);
                      *sp = (__uint16_t)(ufix64 >> 48);
                      *sp = (__uint16_t)(ufix64 >> 48);
                    }
                    }
                  else if (flags & LONG)
                  else if (flags & LONG)
                    {
                    {
                      __uint64_t *llp = va_arg (ap, __uint64_t *);
                      __uint64_t *llp = va_arg (ap, __uint64_t *);
                      *llp = ufix64;
                      *llp = ufix64;
                    }
                    }
                  else
                  else
                    {
                    {
                      __uint32_t *lp = va_arg (ap, __uint32_t *);
                      __uint32_t *lp = va_arg (ap, __uint32_t *);
                      *lp = (__uint32_t)(ufix64 >> 32);
                      *lp = (__uint32_t)(ufix64 >> 32);
                    }
                    }
                  nassigned++;
                  nassigned++;
                  break;
                  break;
                }
                }
 
 
#endif /* __SPE__ */
#endif /* __SPE__ */
#ifdef _NO_LONGDBL
#ifdef _NO_LONGDBL
              res = _strtod_r (rptr, buf, NULL);
              res = _strtod_r (rptr, buf, NULL);
#else  /* !_NO_LONGDBL */
#else  /* !_NO_LONGDBL */
              res = _strtold (buf, NULL);
              res = _strtold (buf, NULL);
#endif /* !_NO_LONGDBL */
#endif /* !_NO_LONGDBL */
              if (flags & LONG)
              if (flags & LONG)
                {
                {
                  dp = va_arg (ap, double *);
                  dp = va_arg (ap, double *);
                  *dp = res;
                  *dp = res;
                }
                }
              else if (flags & LONGDBL)
              else if (flags & LONGDBL)
                {
                {
                  ldp = va_arg (ap, _LONG_DOUBLE *);
                  ldp = va_arg (ap, _LONG_DOUBLE *);
                  *ldp = res;
                  *ldp = res;
                }
                }
              else
              else
                {
                {
                  if (!(flags & VECTOR))
                  if (!(flags & VECTOR))
                    flp = va_arg (ap, float *);
                    flp = va_arg (ap, float *);
                  else if (!looped)
                  else if (!looped)
                    flp = vec_buf.f;
                    flp = vec_buf.f;
                  *flp++ = res;
                  *flp++ = res;
                }
                }
              if (!(flags & VECTOR))
              if (!(flags & VECTOR))
                nassigned++;
                nassigned++;
            }
            }
          break;
          break;
        }
        }
#endif /* FLOATING_POINT */
#endif /* FLOATING_POINT */
        }
        }
      if (vec_read_count-- > 1)
      if (vec_read_count-- > 1)
        {
        {
          looped = 1;
          looped = 1;
          goto process;
          goto process;
        }
        }
      if (flags & VECTOR)
      if (flags & VECTOR)
        {
        {
          int i;
          int i;
          unsigned long *vp = va_arg (ap, unsigned long *);
          unsigned long *vp = va_arg (ap, unsigned long *);
          for (i = 0; i < 4; ++i)
          for (i = 0; i < 4; ++i)
            *vp++ = vec_buf.l[i];
            *vp++ = vec_buf.l[i];
          nassigned++;
          nassigned++;
        }
        }
    }
    }
input_failure:
input_failure:
  return nassigned ? nassigned : -1;
  return nassigned ? nassigned : -1;
match_failure:
match_failure:
  return nassigned;
  return nassigned;
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.