⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfscanf.cxx

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
//========================================================================
//
//      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 + -