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

📄 vfscanf.cxx

📁 eCos1.31版
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//========================================================================////      vfscanf.cxx////      I/O routines for vfscanf() for use with ANSI C library////========================================================================//####COPYRIGHTBEGIN####//                                                                          // -------------------------------------------                              // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in         // compliance with the License.  You may obtain a copy of the License at    // http://www.redhat.com/                                                   //                                                                          // Software distributed under the License is distributed on an "AS IS"      // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the // License for the specific language governing rights and limitations under // the License.                                                             //                                                                          // The Original Code is eCos - Embedded Configurable Operating System,      // released September 30, 1998.                                             //                                                                          // The Initial Developer of the Original Code is Red Hat.                   // Portions created by Red Hat are                                          // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     jlarmour// Contributors:  jlarmour// Date:          1998-02-13// 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.h>   // Configuration header// Include the C library? And do we want the stdio stuff? And we have to// have ungetc for this to work#if defined(CYGPKG_LIBC) && defined(CYGPKG_LIBC_STDIO) && \    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 "clibincl/stream.hxx"    // C library streams#include "clibincl/stdiosupp.hxx" // Support for stdio functions// EXPORTED SYMBOLSexternC intvfscanf (FILE *fp, const char *fmt0, va_list ap)    CYGPRI_LIBC_WEAK_ALIAS("_vfscanf");#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)) )externC int_vfscanf (FILE *fp, const char *fmt0, va_list ap){    u_char *fmt = (u_char *) fmt0;    int c;              /* character from format, or conversion */    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 */    int nassigned;      /* number of fields assigned */    int nread;          /* number of characters consumed from fp */    int base = 0;       /* base argument to strtol/strtoul */        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};    nassigned = 0;    nread = 0;    for (;;)    {        c = *fmt++;        if (c == 0)            return nassigned;        if (isspace (c))        {            for (;;)            {                if (BufferEmpty)                    return nassigned;                if (!isspace (*CURR_POS))                    break;                nread++, INC_CURR_POS;            }            continue;        }        if (c != '%')            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:            if (BufferEmpty)                goto input_failure;            if (*CURR_POS != c)                goto match_failure;            INC_CURR_POS;            nread++;        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)                {                    *dest++ = *CURR_POS;                    INC_CURR_POS;                    n--;                    nread++;                }                nassigned++;            }            break;        case CT_CCL:            /* scan a (nonempty) character class (sets NOSKIP) */            if (width == 0)                width = ~0;             /* `infinity' */            /* take only those things in the class */

⌨️ 快捷键说明

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