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

📄 iovfscanf.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
				n = 0;				while (ccltab[(unsigned char)*fp->_IO_read_ptr]) {				    n++, fp->_IO_read_ptr++;				    if (--width == 0)					break;				    if (_IO_peekc(fp) == EOF) {					if (n == 0)					    goto eof_failure;					seen_eof++;					break;				    }				}				if (n == 0)					goto match_failure;			} else {			    p0 = p = va_arg(ap, char *);			    while (ccltab[(unsigned char)*fp->_IO_read_ptr]) {				*p++ = *fp->_IO_read_ptr++;				if (--width == 0)				    break;				if (_IO_peekc(fp) == EOF) {				    if (p == p0)					goto eof_failure;				    seen_eof++;				    break;				}			    }			    n = p - p0;			    if (n == 0)				goto match_failure;			    *p = 0;			    nassigned++;			}			nread += n;			break;		case CT_STRING:			/* like CCL, but zero-length string OK, & no NOSKIP */			if (width == 0)				width = ~0;			if (flags & SUPPRESS) {				n = 0;				while (!isspace((unsigned char)*fp->_IO_read_ptr)) {					n++, fp->_IO_read_ptr++;					if (--width == 0)						break;					if (_IO_peekc(fp) == EOF) {					    seen_eof++;					    break;					}				}				nread += n;			} else {				p0 = p = va_arg(ap, char *);				while (!isspace((unsigned char)*fp->_IO_read_ptr)) {					*p++ = *fp->_IO_read_ptr++;					if (--width == 0)						break;					if (_IO_peekc(fp) == EOF) {					    seen_eof++;					    break;					}				}				*p = 0;				nread += p - p0;				nassigned++;			}			continue;		case CT_INT:			/* scan an integer as if by strtol/strtoul */			if (width == 0 || width > sizeof(buf) - 1)				width = sizeof(buf) - 1;			flags |= SIGNOK | NDIGITS | NZDIGITS;			for (p = buf; width; width--) {				c = (unsigned char)*fp->_IO_read_ptr;				/*				 * Switch on the character; `goto ok'				 * if we accept it as a part of number.				 */				switch (c) {				/*				 * The digit 0 is always legal, but is				 * special.  For %i conversions, if no				 * digits (zero or nonzero) have been				 * scanned (only signs), we will have				 * base==0.  In that case, we should set				 * it to 8 and enable 0x prefixing.				 * Also, if we have not scanned zero digits				 * before this, do not turn off prefixing				 * (someone else will turn it off if we				 * have scanned any nonzero digits).				 */				case '0':					if (base == 0) {						base = 8;						flags |= PFXOK;					}					if (flags & NZDIGITS)					    flags &= ~(SIGNOK|NZDIGITS|NDIGITS);					else					    flags &= ~(SIGNOK|PFXOK|NDIGITS);					goto ok;				/* 1 through 7 always legal */				case '1': case '2': case '3':				case '4': case '5': case '6': case '7':					base = basefix[base];					flags &= ~(SIGNOK | PFXOK | NDIGITS);					goto ok;				/* digits 8 and 9 ok iff decimal or hex */				case '8': case '9':					base = basefix[base];					if (base <= 8)						break;	/* not legal here */					flags &= ~(SIGNOK | PFXOK | NDIGITS);					goto ok;				/* letters ok iff hex */				case 'A': case 'B': case 'C':				case 'D': case 'E': case 'F':				case 'a': case 'b': case 'c':				case 'd': case 'e': case 'f':					/* no need to fix base here */					if (base <= 10)						break;	/* not legal here */					flags &= ~(SIGNOK | PFXOK | NDIGITS);					goto ok;				/* sign ok only as first character */				case '+': case '-':					if (flags & SIGNOK) {						flags &= ~SIGNOK;						goto ok;					}					break;				/* x ok iff flag still set & 2nd char */				case 'x': case 'X':					if (flags & PFXOK && p == buf + 1) {						base = 16;	/* if %i */						flags &= ~PFXOK;						goto ok;					}					break;				}				/*				 * If we got here, c is not a legal character				 * for a number.  Stop accumulating digits.				 */				break;		ok:				/*				 * c is legal: store it and look at the next.				 */				*p++ = c;				fp->_IO_read_ptr++;				if (_IO_peekc(fp) == EOF) {				    seen_eof++;				    break;		/* EOF */				}		        }			/*			 * If we had only a sign, it is no good; push			 * back the sign.  If the number ends in `x',			 * it was [sign] '0' 'x', so push back the x			 * and treat it as [sign] '0'.			 */			if (flags & NDIGITS) {				if (p > buf)					(void) _IO_ungetc(*(u_char *)--p, fp);				goto match_failure;			}			c = ((u_char *)p)[-1];			if (c == 'x' || c == 'X') {				--p;				(void) _IO_ungetc (c, fp);			}			if ((flags & SUPPRESS) == 0) {				u_long res;				*p = 0;				res = (*ccfn)(buf, (char **)NULL, base);				if (flags & POINTER)					*va_arg(ap, void **) = (void *)res;				else if (flags & SHORT)					*va_arg(ap, short *) = res;				else if (flags & LONG)					*va_arg(ap, long *) = res;				else					*va_arg(ap, int *) = res;				nassigned++;			}			nread += p - buf;			break;#ifdef FLOATING_POINT		case CT_FLOAT:			/* scan a floating point number as if by strtod */			if (width == 0 || width > sizeof(buf) - 1)				width = sizeof(buf) - 1;			flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;			for (p = buf; width; width--) {				c = (unsigned char)*fp->_IO_read_ptr;				/*				 * This code mimicks the integer conversion				 * code, but is much simpler.				 */				switch (c) {				case '0': case '1': case '2': case '3':				case '4': case '5': case '6': case '7':				case '8': case '9':					flags &= ~(SIGNOK | NDIGITS);					goto fok;				case '+': case '-':					if (flags & SIGNOK) {						flags &= ~SIGNOK;						goto fok;					}					break;				case '.':					if (flags & DPTOK) {						flags &= ~(SIGNOK | DPTOK);						goto fok;					}					break;				case 'e': case 'E':					/* no exponent without some digits */					if ((flags&(NDIGITS|EXPOK)) == EXPOK) {						flags =						    (flags & ~(EXPOK|DPTOK)) |						    SIGNOK | NDIGITS;						goto fok;					}					break;				}				break;		fok:				*p++ = c;				fp->_IO_read_ptr++;				if (_IO_peekc(fp) == EOF) {				    seen_eof++;				    break;	/* EOF */				}			}			/*			 * If no digits, might be missing exponent digits			 * (just give back the exponent) or might be missing			 * regular digits, but had sign and/or decimal point.			 */			if (flags & NDIGITS) {				if (flags & EXPOK) {					/* no digits at all */					while (p > buf)					    _IO_ungetc (*(u_char *)--p, fp);					goto match_failure;				}				/* just a bad exponent (e and maybe sign) */				c = *(u_char *)--p;				if (c != 'e' && c != 'E') {					(void) _IO_ungetc (c, fp);/* sign */					c = *(u_char *)--p;				}				(void) _IO_ungetc (c, fp);			}			if ((flags & SUPPRESS) == 0) {				double res;				*p = 0;#ifdef _IO_USE_DTOA				res = _IO_strtod(buf, NULL);#else				res = atof(buf);#endif				if (flags & LONG)					*va_arg(ap, double *) = res;				else					*va_arg(ap, float *) = res;				nassigned++;			}			nread += p - buf;			break;#endif /* FLOATING_POINT */		}	}eof_failure:	seen_eof++;input_failure:	if (nassigned == 0)	    nassigned = -1;control_failure:match_failure:	if (errp)	    *errp |= 2;done:	if (errp && seen_eof)		*errp |= 1;	return (nassigned);}/* * Fill in the given table from the scanset at the given format * (just after `[').  Return a pointer to the character past the * closing `]'.  The table has a 1 wherever characters should be * considered part of the scanset. */static const u_char *__sccl (tab, fmt)     char *tab;     const u_char *fmt;{	register int c, n, v;	/* first `clear' the whole table */	c = *fmt++;		/* first char hat => negated scanset */	if (c == '^') {		v = 1;		/* default => accept */		c = *fmt++;	/* get new first char */	} else		v = 0;		/* default => reject */	/* should probably use memset here */	for (n = 0; n < 256; n++)		tab[n] = v;	if (c == 0)		return (fmt - 1);/* format ended before closing ] */	/*	 * Now set the entries corresponding to the actual scanset	 * to the opposite of the above.	 *	 * The first character may be ']' (or '-') without being special;	 * the last character may be '-'.	 */	v = 1 - v;	for (;;) {		tab[c] = v;		/* take character c */doswitch:		n = *fmt++;		/* and examine the next */		switch (n) {		case 0:			/* format ended too soon */			return (fmt - 1);		case '-':			/*			 * A scanset of the form			 *	[01+-]			 * is defined as `the digit 0, the digit 1,			 * the character +, the character -', but			 * the effect of a scanset such as			 *	[a-zA-Z0-9]			 * is implementation defined.  The V7 Unix			 * scanf treats `a-z' as `the letters a through			 * z', but treats `a-a' as `the letter a, the			 * character -, and the letter a'.			 *			 * For compatibility, the `-' is not considerd			 * to define a range if the character following			 * it is either a close bracket (required by ANSI)			 * or is not numerically greater than the character			 * we just stored in the table (c).			 */			n = *fmt;			if (n == ']' || n < c) {				c = '-';				break;	/* resume the for(;;) */			}			fmt++;			do {		/* fill in the range */				tab[++c] = v;			} while (c < n);#if 1	/* XXX another disgusting compatibility hack */			/*			 * Alas, the V7 Unix scanf also treats formats			 * such as [a-c-e] as `the letters a through e'.			 * This too is permitted by the standard....			 */			goto doswitch;#else			c = *fmt++;			if (c == 0)				return (fmt - 1);			if (c == ']')				return (fmt);#endif			break;		case ']':		/* end of scanset */			return (fmt);		default:		/* just another character */			c = n;			break;		}	}	/* NOTREACHED */}

⌨️ 快捷键说明

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