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

📄 doscan.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic	char	*sccsid = "@(#)doscan.c	4.3	ULTRIX	2/28/91";#endif/************************************************************************ *									* *			Copyright (c) 1985, 1988, 1989 by		* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  AT&T.		* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History * *	Brian Mahoney * 007	Change behavior of %n when eof is encountered * *	Jon Reeves, 15-Nov-1989 * 006	Treat X like x for POSIX/X/Open. * *      Linda Wilson, 05-oct-1989 * 005  For X/Open conformance, treat E/F/G as floats rather than doubles. *	When %n encountered, do not increment the assignment count. * *	Jon Reeves, 14 Jun 1989 * 004	Added %p (same as %8x) and L modifier (treated as l) for ANSI. * *	Jon Reeves, 12 Apr 1989 * 003	Corrected problems with short counts for %n, not counting the *	'e' for %#e, not scanning space in "1e 1", not counting leading *	0 or 0x for %#i. * *	Andy Gadsby, 27-Nov-1986 * INTL	Modified to use external _lc_radix to detect decimal point.  * *	David L Ballenger, 7-Jun-1985 * 001	Use modifyied version of System V doscan().  Upgraded from System *	V release 2 to conform to System V interface definition.  Now *	handles %i and %n.  Based on doscan.c 2.6. * ************************************************************************//*LINTLIBRARY*/#include <stdio.h>#include <ctype.h>#include <varargs.h>#include <values.h>#define NCHARS	(1 << BITSPERBYTE)extern double atof();extern char *memset();extern int ungetc();static unsigned char *setup(fmt, tab)register unsigned char *fmt;register char *tab;{	register int b, c, d, t = 0;	if(*fmt == '^') {		t++;		fmt++;	}	(void)memset(tab, !t, NCHARS);	if((c = *fmt) == ']' || c == '-') { /* first char is special */		tab[c] = t;		fmt++;	}	while((c = *fmt++) != ']') {		if(c == '\0')			return(NULL); /* unexpected end of format */		if(c == '-' && (d = *fmt) != ']' && (b = fmt[-2]) < d) {			(void)memset(&tab[b], t, d - b + 1);			fmt++;		} else			tab[c] = t;	}	return(fmt);}static voidstore_int(value,length,arg_list)	long 	value;	int	length;	va_list	*arg_list ;{	switch(length) {	case 'l': *va_arg(*arg_list, long *)  = value ;		  break ;	case 'h': *va_arg(*arg_list, short *) = (short)value ;		  break ;	default:  *va_arg(*arg_list, int *)   = (int)value ;		  break ;	}}int_doscan(iop, fmt, va_alist)register FILE *iop;register unsigned char *fmt;va_list va_alist;{	char tab[NCHARS];	register int ch;	int 	nmatch = 0,		len,		inchar,		stow,		size,		chars_scanned = 0 ;	/*******************************************************	 * Main loop: reads format to determine a pattern,	 *		and then goes to read input stream	 *		in attempt to match the pattern.	 *******************************************************/	for( ; ; ) {		if((ch = *fmt++) == '\0')			return(nmatch); /* end of format */		if(isspace(ch)) {			while(isspace(inchar = getc(iop)))				chars_scanned++;			if(ungetc(inchar, iop) != EOF)				continue;			break;		}		if(ch != '%' || (ch = *fmt++) == '%') {			if((inchar = getc(iop)) == ch) {				chars_scanned++;				continue;			}			if(ungetc(inchar, iop) != EOF)				return(nmatch); /* failed to match input */			break;		}		if(ch == '*') {			stow = 0;			ch = *fmt++;		} else			stow = 1;		for(len = 0; isdigit(ch); ch = *fmt++)			len = len * 10 + ch - '0';		if(len == 0)			len = MAXINT;		if((size = ch) == 'l' || size == 'h' || size == 'L')			ch = *fmt++;		if(ch == '\0' ||		    ch == '[' && (fmt = setup(fmt, tab)) == NULL)			return(EOF); /* unexpected end of format */		if(isupper(ch)) { /* no longer documented */#ifdef _POSIX_SOURCE		  /* 005 */			if(ch != 'E' && ch != 'F' && ch != 'G' && ch != 'X')#endif				size = 'l';			ch = _tolower(ch);		}		if (ch == 'n') {			if (stow) {				store_int((long)chars_scanned,size,&va_alist);			}			continue;		}		if (ch == 'p') { /* pointer - convert to %8x */			ch = 'x';			len = 8;		}		if(ch != 'c' && ch != '[') {			while(isspace(inchar = getc(iop)))				chars_scanned++;			if(ungetc(inchar, iop) == EOF)				break;		}		if((size = (ch == 'c' || ch == 's' || ch == '[') ?		    string(stow,ch,len,tab,iop,&chars_scanned,&va_alist) :		    number(stow,ch,len,size,iop,&chars_scanned,&va_alist))		   != 0)			nmatch += stow;		if(va_alist == NULL) /* end of input */			break;		if(size == 0)			return(nmatch); /* failed to match input */	}	return(nmatch != 0 ? nmatch : EOF); /* end of input */}/*************************************************************** * Functions to read the input stream in an attempt to match incoming * data to the current pattern from the main loop of _doscan(). ***************************************************************/static intnumber(stow, type, len, size, iop, chars_scanned, listp)int stow, type, len, size;register FILE *iop;register int *chars_scanned ;va_list *listp;{	char numbuf[64];	register char *np = numbuf;	register int c, base;	int	digitseen = 0,		dotseen = 0,		expseen = 0,		floater = 0,		negflg = 0;	long lcval = 0;	extern char _lc_radix;	/* INTL. the international radix character */	switch(type) {	case 'e':	case 'f':	case 'g':		floater++;		/* FALLTHROUGH */	case 'd':	case 'u':		base = 10;		break;	case 'o':		base = 8;		break;	case 'x':		base = 16;		break;	case 'i':		base = 0;	/* General integer */		break ;	default:		return(0); /* unrecognized conversion character */	}	switch(c = getc(iop)) {	case '-':		negflg++;	case '+': /* fall-through */		len--;		c = getc(iop);		(*chars_scanned)++ ;	}	if (base == 0) {	/* general integer, test format */		if (c == '0') {			c = getc(iop) ;			if (c == 'x' || c == 'X') {				/* 0x or 0X mean hex, get next digit and				 * mark the 0[Xx] as scanned.				 */				base = 16 ;				len -= 2;				c = getc(iop);				*chars_scanned += 2 ;			} else if (isdigit(c)) {				/* 0 followed by a digit is octal,				 * mark 0 as scanned.				 */				base = 8 ;				len--;				(*chars_scanned)++ ;			} else {				/* Decimal 0, restart scan at 0.				 */				ungetc(c,iop); 				c = '0';				base = 10 ;			}		} else			base = 10 ;	} 	    for( ; --len >= 0 && np < &numbuf[63]; *np++ = c, c = getc(iop)) {		if(isdigit(c) || base == 16 && isxdigit(c)) {			int digit = c - (isdigit(c) ? '0' :			    isupper(c) ? 'A' - 10 : 'a' - 10);			if(digit >= base)				break;			if(stow && !floater)				lcval = base * lcval + digit;			digitseen++;			(*chars_scanned)++ ;			continue;		}		if(!floater)			break;		if(c == _lc_radix && !dotseen++) {	/* INTL */			(*chars_scanned)++ ;			continue;		}		if((c == 'e' || c == 'E') && digitseen && !expseen++) {			(*chars_scanned)++ ;			if (--len < 0 || np >= &numbuf[63])				break;			*np++ = c;			c = getc(iop);			if(isdigit(c) || c == '+' || c == '-' || isspace(c)) {				(*chars_scanned)++ ;				continue;			}		}		break;	    }	if(stow && digitseen)		if(floater) {			register double dval;				*np = '\0';			dval = atof(numbuf);			if(negflg)				dval = -dval;			if(size == 'l' || size == 'L')				*va_arg(*listp, double *) = dval;			else				*va_arg(*listp, float *) = (float)dval;		} else {			/* suppress possible overflow on 2's-comp negation */			if(negflg && lcval != HIBITL)				lcval = -lcval;			store_int(lcval,size,listp);		}	ungetc(c,iop);	return(digitseen); /* successful match if non-zero */}static intstring(stow, type, len, tab, iop, chars_scanned, listp)register int stow, type, len;register char *tab;register FILE *iop;int *chars_scanned;va_list *listp;{	register int ch;	register char *ptr;	char *start;	start = ptr = stow ? va_arg(*listp, char *) : NULL;	if(type == 'c' && len == MAXINT)		len = 1;	while((ch = getc(iop)) != EOF &&	    !(type == 's' && isspace(ch) || type == '[' && tab[ch])) {		if(stow)			*ptr = ch;		ptr++;		(*chars_scanned)++;		if(--len <= 0)			break;	}	if(ch == EOF || len > 0 && ungetc(ch, iop) == EOF)		*listp = NULL; /* end of input */	if(ptr == start)		return(0); /* no match */	if(stow && type != 'c')		*ptr = '\0';	return(1); /* successful match */}

⌨️ 快捷键说明

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