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

📄 doscan.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#if !defined(lint) && defined(SCCSIDS)static char sccsid[] = "@(#)doscan.c 1.1 92/07/30 SMI"; /* from S5R3.1 2.18 */#endif/*	Copyright (c) 1984 AT&T	*//*	  All Rights Reserved  	*//*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*//*	The copyright notice above does not evidence any   	*//*	actual or intended publication of such source code.	*//* * Copyright (c) 1988 by Sun Microsystems, Inc. *//*LINTLIBRARY*/#include <stdio.h>#include <ctype.h>#include <varargs.h>#include <values.h>#include <floatingpoint.h>#include <errno.h>#define NCHARS	(1 << BITSPERBYTE)#define locgetc()	(chcount+=1,getc(iop))#define locungetc(x)	(chcount-=1,ungetc(x,iop))extern char *memset();static int chcount,flag_eof;#ifdef S5EMUL#define	isws(c)		isspace(c)#else/* * _sptab[c+1] is 1 iff 'c' is a white space character according to the * 4.2BSD "scanf" definition - namely, SP, TAB, and NL are the only * whitespace characters. */static char _sptab[1+256] = {	0,				/* EOF - not a whitespace char */	0,0,0,0,0,0,0,0,	0,1,1,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	1,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,	0,0,0,0,0,0,0,0,};#define	isws(c)		((_sptab + 1)[c] != 0)#endifint_doscan(iop, fmt, va_alist)register FILE *iop;register unsigned char *fmt;va_list va_alist;{	extern unsigned char *setup();	char tab[NCHARS];	register int ch;	int nmatch = 0, len, inchar, stow, size;	chcount=0; flag_eof=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 (isws(ch))		{		  	if (!flag_eof) 			{			   while (isws(inchar = locgetc()))				;			   if (inchar == EOF) {				chcount--;				flag_eof = 1;			   }			   else if (locungetc(inchar) == EOF)				flag_eof = 1;			}		  continue;		}		if (ch != '%' || (ch = *fmt++) == '%')                {			if ( (inchar = locgetc()) == ch )				continue;			if (inchar != EOF) {				if (locungetc(inchar) != EOF)					return(nmatch); /* failed to match input */			} else {				chcount--;			}			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 */		{			size = 'l';#ifdef S5EMUL			ch = _tolower(ch);#else			ch = tolower(ch);#endif		}		switch(ch)		{		 case 'c':		 case 's':		 case '[':			  if ((size = string(stow,ch,len,tab,iop,&va_alist)) < 0)				goto out;	/* EOF seen, nothing converted */			  break;                 case 'n':			  if (size == 'h')				*va_arg(va_alist, short *) = (short) chcount;		          else if (size == 'l')				*va_arg(va_alist, long *) = (long) chcount;			  else			  	*va_arg(va_alist, int *) = (int) chcount;			  continue;                 default:			 if ((size = number(stow, ch, len, size, iop, &va_alist)) < 0)				goto out;	/* EOF seen, nothing converted */			 break;                 }		   if (size)			nmatch += stow;		   else 			return((flag_eof && !nmatch) ? EOF : nmatch);		continue;	}out:	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, listp)int stow, type, len, size;register FILE *iop;va_list *listp;{	char numbuf[64], inchar, lookahead;	register char *np = numbuf;	register int c, base;	int digitseen = 0, floater = 0, negflg = 0;	long lcval = 0;	switch(type)	{	case 'e':	case 'f':	case 'g':		floater++;	case 'd':	case 'u':	case 'i':		base = 10;		break;	case 'o':		base = 8;		break;	case 'x':		base = 16;		break;	default:		return(0); /* unrecognized conversion character */	}	if (!flag_eof)	{		while (isws(c = locgetc()))			;	}	else		c = locgetc();	if (c == EOF) {		chcount--;		return(-1);	/* EOF before match */	}        if (floater != 0) {     /* Handle floating point with                                 * file_to_decimal. */                decimal_mode    dm;                decimal_record  dr;                fp_exception_field_type efs;                enum decimal_string_form form;                char           *echar;                int             nread, ic;                char            buffer[1024];                char           *nb = buffer;                locungetc(c);		if (len > 1024)			len = 1024;                file_to_decimal(&nb, len, 0, &dr, &form, &echar, iop, &nread);                if (stow && (form != invalid_form)) {                        dm.rd = fp_direction;                        if (size == 'l') {      /* double */                                decimal_to_double((double *) va_arg(*listp, double *), &dm, &dr, &efs);                        } else if (size == 'L') {      /* quad */                                decimal_to_quadruple((quadruple *)va_arg(*listp, double *), &dm, &dr, &efs);                        } else {/* single */                                decimal_to_single((float *) va_arg(*listp, float *), &dm, &dr, &efs);                        }                          }		chcount += nread;	/* Count characters read. */                c = *nb;        /* Get first unused character. */                ic = c;                if (c == NULL) {                        ic = locgetc();                        c = ic;                        /*                         * If null, first unused may have been put back                         * already.                         */                }                         if (ic == EOF) {                        chcount--;                        flag_eof = 1;                } else if (locungetc(c) == EOF)                        flag_eof = 1;                return ((form == invalid_form) ? 0 : 1);        /* successful match if                                                                 * non-zero */        }	switch(c) {	case '-':		negflg++;		if (type == 'u')			break;	case '+': /* fall-through */		if (--len <= 0)			break;		if ( (c = locgetc()) != '0')			break;        case '0':                if ( (type != 'i') || (len <= 1) )  		   break;	        if ( ((inchar = locgetc()) == 'x') || (inchar == 'X') ) 	        {		      /* If not using sscanf and *		       * at the buffer's end     *		       * then LOOK ahead         */                   if ( (iop->_flag & _IOSTRG) || (iop->_cnt != 0) )		      lookahead = locgetc();		   else		   {		      if ( read(fileno(iop),np,1) == 1)		         lookahead = *np;                      else		         lookahead = EOF;                      chcount += 1;                   }    		   if ( isxdigit(lookahead) )		   {		       base =16;		       if ( len <= 2)		       {			  locungetc(lookahead);			  len -= 1;            /* Take into account the 'x'*/                       }		       else 		       {		          c = lookahead;			  len -= 2;           /* Take into account '0x'*/		       }                   }	           else	           {	               locungetc(lookahead);	               locungetc(inchar);                   }		}	        else	        {		    locungetc(inchar);	            base = 8;                }	}	if (!negflg || type != 'u')	    for (; --len  >= 0 ; *np++ = c, c = locgetc()) 	    {		if (np > numbuf + 62)           		{		    errno = ERANGE;		    return(0);                }		if (isdigit(c))		{			register int digit;			digit = c - '0';			if (base == 8)			{				if (digit >= 8)					break;				if (stow)					lcval = (lcval<<3) + digit;			}			else			{				if (stow)				{					if (base == 10)						lcval = (((lcval<<2) + lcval)<<1) + digit;					else /* base == 16 */						lcval = (lcval<<4) + digit;				}			}			digitseen++;			continue;		}		else if (base == 16 && isxdigit(c))		{			register int digit;			digit = c - (isupper(c) ? 'A' - 10 : 'a' - 10);			if (stow)				lcval = (lcval<<4) + digit;			digitseen++;			continue;		}		break;	    }	if (stow && digitseen)		{	 	/* suppress possible overflow on 2's-comp negation */			if (negflg && lcval != HIBITL)				lcval = -lcval;			if (size == 'l')				*va_arg(*listp, long *) = lcval;			else if (size == 'h')				*va_arg(*listp, short *) = (short)lcval;			else				*va_arg(*listp, int *) = (int)lcval;		}	if (c == EOF) {		chcount--;		flag_eof=1;	} else if (locungetc(c) == EOF)		flag_eof=1;	return (digitseen); /* successful match if non-zero */}static intstring(stow, type, len, tab, iop, listp)register int stow, type, len;register char *tab;register FILE *iop;va_list *listp;{	register int ch;	register char *ptr;	char *start;	start = ptr = stow ? va_arg(*listp, char *) : NULL;	if (type == 's')	{		if (!flag_eof)		{			while (isws(ch = locgetc()))				;		}		else			ch = locgetc();		if (ch == EOF)			return(-1);	/* EOF before match */		while (ch != EOF && !isws(ch))		{			if (stow)				*ptr = ch;			ptr++;			if (--len <= 0)				break;			ch = locgetc();		}	} else if (type == 'c') {		if (len == MAXINT)			len = 1;		while ( (ch = locgetc()) != EOF)		{			if (stow)				*ptr = ch;			ptr++;			if (--len <= 0)				break;		}	} else { /* type == '[' */		while ( (ch = locgetc()) != EOF && !tab[ch])		{			if (stow)				*ptr = ch;			ptr++;			if (--len <= 0)				break;		}	}	if (ch == EOF )	{		chcount-=1;		flag_eof = 1;	}	else if (len > 0 && locungetc(ch) == EOF)		flag_eof = 1;	if (ptr == start)		return(0); /* no match */	if (stow && type != 'c')		*ptr = '\0';	return (1); /* successful match */}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);}

⌨️ 快捷键说明

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