📄 vfscanf.cxx
字号:
//========================================================================
//
// vfscanf.cxx
//
// I/O routines for vfscanf() for use with ANSI C library
//
//========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): jlarmour
// Contributors:
// Date: 2000-04-20
// Purpose:
// Description:
// Usage:
//
//####DESCRIPTIONEND####
//
//========================================================================
//
// This code is based on original code with the following copyright:
//
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
// CONFIGURATION
#include <pkgconf/libc_stdio.h> // Configuration header
#include <pkgconf/libc_i18n.h> // Configuration header for mb support
// We have to have ungetc for this to work
#if defined(CYGFUN_LIBC_STDIO_ungetc)
// INCLUDES
#include <cyg/infra/cyg_type.h> // Common type definitions and support
#include <stdarg.h> // Variable argument definitions
#include <stdio.h> // Standard header for all stdio files
#include <ctype.h> // isspace() and isupper()
#include <stdlib.h> // standard utility functions e.g. strtol
#include <cyg/libc/stdio/stream.hxx> // C library streams
#ifdef CYGSEM_LIBC_STDIO_SCANF_FLOATING_POINT
#include <float.h>
# define MAXFRACT DBL_DIG
# define MAXEXP DBL_MAX_10_EXP
# define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
#else // ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
# define BUF 40
#endif // ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
/*
* Flags used during conversion.
*/
#define LONG 0x01 /* l: long or double */
#define LONGDBL 0x02 /* L: long double; unimplemented */
#define SHORT 0x04 /* h: short */
#define SUPPRESS 0x08 /* suppress assignment */
#define POINTER 0x10 /* weird %p pointer (`fake hex') */
#define NOSKIP 0x20 /* do not skip blanks */
/*
* The following are used in numeric conversions only:
* SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
* SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
*/
#define SIGNOK 0x40 /* +/- is (still) legal */
#define NDIGITS 0x80 /* no digits detected */
#define DPTOK 0x100 /* (float) decimal point is still legal */
#define EXPOK 0x200 /* (float) exponent (e+3, etc) still
legal */
#define PFXOK 0x100 /* 0x prefix is (still) legal */
#define NZDIGITS 0x200 /* no zero digits detected */
/*
* Conversion types.
*/
#define CT_CHAR 0 /* %c conversion */
#define CT_CCL 1 /* %[...] conversion */
#define CT_STRING 2 /* %s conversion */
#define CT_INT 3 /* integer, i.e., strtol or strtoul */
#define CT_FLOAT 4 /* floating, i.e., strtod */
#if 0
#define u_char unsigned char
#endif
#define u_char char
#define u_long unsigned long
typedef unsigned long (*strtoul_t)(const char *, char **endptr, int base);
static u_char *
__sccl (char *tab, u_char *fmt);
/*
* vfscanf
*/
#define _CAST_VOID
#define CURR_POS (file->peek_byte( (cyg_uint8 *)&curr_byte),&curr_byte )
#define INC_CURR_POS ( file->read_byte( (cyg_uint8 *)&curr_byte ) )
#define MOVE_CURR_POS(x) (file->set_position( (x), SEEK_CUR ))
#define SPACE_LEFT (file->bytes_available_to_read())
#define REFILL (file->refill_read_buffer())
#define BufferEmpty ( !SPACE_LEFT && \ (REFILL, (!SPACE_LEFT)) )
#ifdef CYGINT_LIBC_I18N_MB_REQUIRED
typedef int (*mbtowc_fn_type)(wchar_t *, const char *, size_t, int *);
externC mbtowc_fn_type __get_current_locale_mbtowc_fn();
#endif
externC int
vfscanf (FILE *fp, const char *fmt0, va_list ap) __THROW
{
u_char *fmt = (u_char *) fmt0;
int c; /* character from format, or conversion */
wchar_t wc; /* wide character from format */
size_t width; /* field width, or 0 */
char *p; /* points into all kinds of strings */
int n; /* handy integer */
int flags; /* flags as defined above */
char *p0; /* saves original value of p when necessary */
char *lptr; /* literal pointer */
int nassigned; /* number of fields assigned */
int nread; /* number of characters consumed from fp */
int base = 0; /* base argument to strtol/strtoul */
int nbytes = 1; /* number of bytes processed */
#ifdef CYGINT_LIBC_I18N_MB_REQUIRED
mbtowc_fn_type mbtowc_fn;
int state = 0; /* used for mbtowc_fn */
#endif
strtoul_t ccfn = NULL; /* conversion function (strtol/strtoul) */
char ccltab[256]; /* character class table for %[...] */
char buf[BUF]; /* buffer for numeric conversions */
Cyg_StdioStream *file = (Cyg_StdioStream *)fp;
char curr_byte;
short *sp;
int *ip;
float *flp;
long double *ldp;
double *dp;
long *lp;
/* `basefix' is used to avoid `if' tests in the integer scanner */
static const short basefix[17] =
{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
#ifdef CYGINT_LIBC_I18N_MB_REQUIRED
mbtowc_fn = __get_current_locale_mbtowc_fn();
#endif
nassigned = 0;
nread = 0;
for (;;)
{
#ifndef CYGINT_LIBC_I18N_MB_REQUIRED
wc = *fmt;
#else
nbytes = mbtowc_fn (&wc, fmt, MB_CUR_MAX, &state);
#endif
fmt += nbytes;
if (wc == 0)
return nassigned;
if (nbytes == 1 && isspace (wc))
{
for (;;)
{
if (BufferEmpty)
return nassigned;
if (!isspace (*CURR_POS))
break;
nread++, INC_CURR_POS;
}
continue;
}
if (wc != '%')
goto literal;
width = 0;
flags = 0;
/*
* switch on the format. continue if done; break once format
* type is derived.
*/
again:
c = *fmt++;
switch (c)
{
case '%':
literal:
lptr = fmt - nbytes;
for (n = 0; n < nbytes; ++n)
{
if (BufferEmpty)
goto input_failure;
if (*CURR_POS != *lptr)
goto match_failure;
INC_CURR_POS;
nread++;
++lptr;
}
continue;
case '*':
flags |= SUPPRESS;
goto again;
case 'l':
flags |= LONG;
goto again;
case 'L':
flags |= LONGDBL;
goto again;
case 'h':
flags |= SHORT;
goto again;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
width = width * 10 + c - '0';
goto again;
/*
* Conversions. Those marked `compat' are for
* 4.[123]BSD compatibility.
*
* (According to ANSI, E and X formats are supposed to
* the same as e and x. Sorry about that.)
*/
case 'D': /* compat */
flags |= LONG;
/* FALLTHROUGH */
case 'd':
c = CT_INT;
ccfn = (strtoul_t)strtol;
base = 10;
break;
case 'i':
c = CT_INT;
ccfn = (strtoul_t)strtol;
base = 0;
break;
case 'O': /* compat */
flags |= LONG;
/* FALLTHROUGH */
case 'o':
c = CT_INT;
ccfn = strtoul;
base = 8;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -