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

📄 vfscanf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#if defined(LIBC_SCCS) && !defined(lint)static char sccsid[] = "@(#)vfscanf.c	8.1 (Berkeley) 6/4/93";#endif /* LIBC_SCCS and not lint */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#if __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#include "local.h"#define FLOATING_POINT#include "floatio.h"#define	BUF		513	/* Maximum length of numeric string. *//* * 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 */#define u_char unsigned char#define u_long unsigned longstatic u_char *__sccl();/* * vfscanf */__svfscanf(fp, fmt0, ap)	register FILE *fp;	char const *fmt0;	va_list ap;{	register u_char *fmt = (u_char *)fmt0;	register int c;		/* character from format, or conversion */	register size_t width;	/* field width, or 0 */	register char *p;	/* points into all kinds of strings */	register int n;		/* handy integer */	register int flags;	/* flags as defined above */	register 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;		/* base argument to strtol/strtoul */	u_long (*ccfn)();	/* conversion function (strtol/strtoul) */	char ccltab[256];	/* character class table for %[...] */	char buf[BUF];		/* buffer for numeric conversions */	/* `basefix' is used to avoid `if' tests in the integer scanner */	static short basefix[17] =		{ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };	nassigned = 0;	nread = 0;	base = 0;		/* XXX just to keep gcc happy */	ccfn = NULL;		/* XXX just to keep gcc happy */	for (;;) {		c = *fmt++;		if (c == 0)			return (nassigned);		if (isspace(c)) {			for (;;) {				if (fp->_r <= 0 && __srefill(fp))					return (nassigned);				if (!isspace(*fp->_p))					break;				nread++, fp->_r--, fp->_p++;			}			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 (fp->_r <= 0 && __srefill(fp))				goto input_failure;			if (*fp->_p != c)				goto match_failure;			fp->_r--, fp->_p++;			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 = (u_long (*)())strtol;			base = 10;			break;		case 'i':			c = CT_INT;			ccfn = (u_long (*)())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 */			flags |= LONG;			/* FALLTHROUGH */		case 'x':			flags |= PFXOK;	/* enable 0x prefixing */			c = CT_INT;			ccfn = strtoul;			base = 16;			break;#ifdef FLOATING_POINT		case 'E':	/* compat   XXX */		case 'F':	/* compat */			flags |= LONG;			/* FALLTHROUGH */		case 'e': case 'f': case 'g':			c = CT_FLOAT;			break;#endif		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)				*va_arg(ap, short *) = nread;			else if (flags & LONG)				*va_arg(ap, long *) = nread;			else				*va_arg(ap, int *) = nread;			continue;		/*		 * Disgusting backwards compatibility hacks.	XXX		 */		case '\0':	/* compat */			return (EOF);		default:	/* compat */			if (isupper(c))				flags |= LONG;			c = CT_INT;			ccfn = (u_long (*)())strtol;			base = 10;			break;		}		/*		 * We have a conversion that requires input.		 */		if (fp->_r <= 0 && __srefill(fp))			goto input_failure;		/*		 * Consume leading white space, except for formats		 * that suppress this.		 */		if ((flags & NOSKIP) == 0) {			while (isspace(*fp->_p)) {				nread++;				if (--fp->_r > 0)					fp->_p++;				else if (__srefill(fp))					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 = fp->_r) < width) {						sum += n;						width -= n;						fp->_p += n;						if (__srefill(fp)) {							if (sum == 0)							    goto input_failure;							break;						}					} else {						sum += width;						fp->_r -= width;						fp->_p += width;						break;					}				}				nread += sum;			} else {				size_t r = fread((void *)va_arg(ap, char *), 1,				    width, fp);				if (r == 0)					goto input_failure;				nread += r;				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 */			if (flags & SUPPRESS) {				n = 0;				while (ccltab[*fp->_p]) {					n++, fp->_r--, fp->_p++;					if (--width == 0)						break;					if (fp->_r <= 0 && __srefill(fp)) {						if (n == 0)							goto input_failure;						break;					}				}				if (n == 0)					goto match_failure;			} else {				p0 = p = va_arg(ap, char *);				while (ccltab[*fp->_p]) {					fp->_r--;					*p++ = *fp->_p++;					if (--width == 0)						break;					if (fp->_r <= 0 && __srefill(fp)) {						if (p == p0)							goto input_failure;						break;

⌨️ 快捷键说明

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