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

📄 vfscanf.cxx

📁 eCos操作系统源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//========================================================================////      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 longtypedef 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_REQUIREDtypedef int (*mbtowc_fn_type)(wchar_t *, const char *, size_t, int *);externC mbtowc_fn_type __get_current_locale_mbtowc_fn();#endifexternC intvfscanf (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;        case 'u':            c = CT_INT;            ccfn = strtoul;            base = 10;            break;        case 'X':               /* compat   XXX */        case 'x':            flags |= PFXOK;     /* enable 0x prefixing */            c = CT_INT;            ccfn = strtoul;            base = 16;            break;        case 'E':               /* compat   XXX */        case 'G':               /* compat   XXX *//* ANSI says that E,G and X behave the same way as e,g,x */            /* FALLTHROUGH */        case 'e':        case 'f':        case 'g':            c = CT_FLOAT;            break;        case 's':            c = CT_STRING;            break;        case '[':            fmt = __sccl (ccltab, fmt);            flags |= NOSKIP;            c = CT_CCL;            break;        case 'c':            flags |= NOSKIP;            c = CT_CHAR;            break;        case 'p':               /* pointer format is like hex */            flags |= POINTER | PFXOK;            c = CT_INT;            ccfn = strtoul;            base = 16;            break;        case 'n':            if (flags & SUPPRESS)       /* ??? */                continue;            if (flags & SHORT)            {                sp = va_arg (ap, short *);                *sp = nread;            }            else if (flags & LONG)            {                lp = va_arg (ap, long *);                *lp = nread;            }            else            {                ip = va_arg (ap, int *);                *ip = nread;            }            continue;            /*             * Disgusting backwards compatibility hacks.        XXX             */        case '\0':              /* compat */            return EOF;        default:                /* compat */            if (isupper (c))                flags |= LONG;            c = CT_INT;            ccfn = (strtoul_t)strtol;            base = 10;            break;        }        /*         * We have a conversion that requires input.         */        if (BufferEmpty)            goto input_failure;        /*         * Consume leading white space, except for formats that         * suppress this.         */        if ((flags & NOSKIP) == 0)        {            while (isspace (*CURR_POS))            {                nread++;                INC_CURR_POS;                if (SPACE_LEFT == 0)#ifndef REDHAT_NEC                    if (REFILL)#endif                        goto input_failure;            }            /*             * Note that there is at least one character in the             * buffer, so conversions that do not set NOSKIP ca             * no longer result in an input failure.             */        }        /*         * Do the conversion.         */        switch (c)        {        case CT_CHAR:            /* scan arbitrary characters (sets NOSKIP) */            if (width == 0)                width = 1;            if (flags & SUPPRESS)            {                size_t sum = 0;                for (;;)                {                    if ((n = SPACE_LEFT) < (signed)width)                    {                        sum += n;                        width -= n;                        MOVE_CURR_POS(n-1);                        INC_CURR_POS;#ifndef REDHAT_NEC                        if (REFILL)                        {#endif                            if (sum == 0)                                goto input_failure;                            break;#ifndef REDHAT_NEC                        }#endif                    }                    else                    {                        sum += width;                        MOVE_CURR_POS(width - 1);                        INC_CURR_POS;                        break;                    }                }                nread += sum;            }            else            {                /* Kludge city for the moment */                char *dest = va_arg (ap, char *);                int n = width;                if (SPACE_LEFT == 0)#ifndef REDHAT_NEC                    if (REFILL)#endif                        goto input_failure;                while (n && !BufferEmpty)                {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -