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

📄 scanf.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 4 页
字号:
							 * or match and inverting */							break;						}						if (psfs.conv_num == CONV_LEFTBRACKET) {							*wb = sc.wc;							wb += psfs.store;						} else {							i = wcrtomb(b, sc.wc, &mbstate);							if (i < 0) { /* Conversion failure. */								goto DONE_DO_UNGET;							}							if (psfs.store) {								b += i;							}						}						fail = 0;					}				}				/* Common tail for processing of %s and %[. */				__scan_ungetc(&sc);				if (fail) {	/* nothing stored! */					goto DONE;				}				*wb = 0;		/* Nul-terminate string. */				*b = 0;				psfs.cnt += psfs.store;				goto NEXT_FMT;			}#endif /* L_vfscanf */			assert(0);			goto DONE;		} /* conversion specification */	MATCH_CHAR:		if (__scan_getc(&sc) != *fmt) {#ifdef L_vfwscanf		DONE_DO_UNGET:#endif /* L_vfwscanf */			__scan_ungetc(&sc);			goto DONE;		}	NEXT_FMT:		++fmt;		if (__FERROR_UNLOCKED(fp)) {			break;		}	} DONE:	if (__FERROR_UNLOCKED(fp) || (*fmt && zero_conversions && __FEOF_UNLOCKED(fp))) {		psfs.cnt = EOF;			/* Yes, vfwscanf also returns EOF. */	}	kill_scan_cookie(&sc);	__STDIO_STREAM_VALIDATE(fp);	__STDIO_AUTO_THREADUNLOCK(fp);	return psfs.cnt;}#endif/**********************************************************************/#ifdef L___psfs_do_numericstatic const unsigned char spec_base[] = SPEC_BASE;static const unsigned char nil_string[] = "(nil)";int __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc){	unsigned char *b;	const unsigned char *p;#ifdef __UCLIBC_HAS_FLOATS__	int exp_adjust = 0;#endif#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Fix MAX_DIGITS.  We do not do binary, so...!#warning TODO: Fix buf!#endif#define MAX_DIGITS 65			/* Allow one leading 0. */	unsigned char buf[MAX_DIGITS+2+ 100];	unsigned char usflag, base;	unsigned char nonzero = 0;	unsigned char seendigit = 0;	#ifdef __UCLIBC_MJN3_ONLY__#warning CONSIDER: What should be returned for an invalid conversion specifier?#endif#ifndef __UCLIBC_HAS_FLOATS__	if (psfs->conv_num > CONV_i) { /* floating point */		goto DONE;	}#endif	base = spec_base[psfs->conv_num - CONV_p];	usflag = (psfs->conv_num <= CONV_u); /* (1)0 if (un)signed */	b = buf;	if (psfs->conv_num == CONV_p) { /* Pointer */		p = nil_string;		do {			if ((__scan_getc(sc) < 0) || (*p != sc->cc)) {				__scan_ungetc(sc);				if (p > nil_string) {					/* We matched at least the '(' so even if we					 * are at eof,  we can not match a pointer. */					return -2;	/* Matching failure */				}				break;			}			if (!*++p) {   /* Matched (nil), so no unget necessary. */				if (psfs->store) {					++psfs->cnt;					_store_inttype(psfs->cur_ptr, psfs->dataargtype,								   (uintmax_t) NULL);				}				return 0;			}		} while (1);#ifdef __UCLIBC_MJN3_ONLY__#warning CONSIDER: Should we require a 0x prefix and disallow +/- for pointer %p?#endif /*  __UCLIBC_MJN3_ONLY__ */	}	__scan_getc(sc);	if (sc->cc < 0) {		return -1;				/* Input failure (nothing read yet). */	}	if ((sc->cc == '+') || (sc->cc == '-')) { /* Handle leading sign.*/		*b++ = sc->cc;		__scan_getc(sc);	}	if ((base & 0xef) == 0) { /* 0xef is ~16, so 16 or 0. */		if (sc->cc == '0') {	/* Possibly set base and handle prefix. */			__scan_getc(sc);			if ((sc->cc|0x20) == 'x') { /* Assumes ascii.. x or X. */				if (__scan_getc(sc) < 0) {					/* Either EOF or error (including wc outside char range).					 * If EOF or error, this is a matching failure (we read 0x).					 * If wc outside char range, this is also a matching failure.					 * Hence, we do an unget (although not really necessary here					 * and fail. */					goto DONE_DO_UNGET;	/* matching failure */				}				base = 16; /* Base 16 for sure now. */#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__				/* The prefix is required for hexadecimal floats. */				*b++ = '0';				*b++ = 'x';#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */			} else { /* oops... back up */				__scan_ungetc(sc);				sc->cc = '0';	/* NASTY HACK! */				base = (base >> 1) + 8;	/* 0->8, 16->16.  no 'if' */#ifdef __UCLIBC_HAS_FLOATS__				if (psfs->conv_num > CONV_i) { /* floating point */					base = 10;				}#endif			}		} else if (!base) {			base = 10;		}	}	/***************** digit grouping **********************/#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__	if ((psfs->flags & FLAG_THOUSANDS) && (base == 10)		&& *(p = sc->grouping)		) {		int nblk1, nblk2, nbmax, lastblock, pass, i;#ifdef __UCLIBC_MJN3_ONLY__#warning CONSIDER: Should we initalize the grouping blocks in __init_scan_cookie()?#endif /*  __UCLIBC_MJN3_ONLY__ */		nbmax = nblk2 = nblk1 = *p;		if (*++p) {			nblk2 = *p;			if (nbmax < nblk2) {				nbmax = nblk2;			}			assert(!p[1]);		}		/* Note: for printf, if 0 and \' flags appear then		 * grouping is done before 0-padding.  Should we		 * strip leading 0's first?  Or add a 0 flag? */		/* For vfwscanf, sc_getc translates, so the value of sc->cc is		 * either EOF or a char. */		if (!__isdigit_char_or_EOF(sc->cc)) { /* No starting digit! */#ifdef __UCLIBC_HAS_FLOATS__			if (psfs->conv_num > CONV_i) { /* floating point */				goto NO_STARTING_DIGIT;			}#endif			goto DONE_DO_UNGET;		}		if (sc->cc == '0') {			seendigit = 1;			*b++ = '0';			/* Store the first 0. */#ifdef __UCLIBC_MJN3_ONLY__#warning CONSIDER: Should leading 0s be skipped before digit grouping? (printf 0 pad)#endif /*  __UCLIBC_MJN3_ONLY__ */#if 0			do {				/* But ignore all subsequent 0s. */				__scan_getc(sc);			} while (sc->cc == '0');#endif		}		pass = 0;		lastblock = 0;		do {			i = 0;			while (__isdigit_char_or_EOF(sc->cc)) {				seendigit = 1;				if (i == nbmax) { /* too many digits for a block */#ifdef __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__					if (!pass) { /* treat as nongrouped */						if (nonzero) {							goto DO_NO_GROUP;						}						goto DO_TRIM_LEADING_ZEROS;					}#endif					if (nbmax > nblk1) {						goto DONE_DO_UNGET;	/* matching failure */					}					goto DONE_GROUPING_DO_UNGET; /* nbmax == nblk1 */				}				++i;				if (nonzero || (sc->cc != '0')) {					if (b < buf + MAX_DIGITS) {						*b++ = sc->cc;						nonzero = 1;#ifdef __UCLIBC_HAS_FLOATS__					} else {						++exp_adjust;#endif					}				}				__scan_getc(sc);			}			if (i) {			/* we saw digits digits */				if ((i == nblk2) || ((i < nblk2) && !pass)) {					/* (possible) outer grp */					p = sc->thousands_sep;					if (*p == sc->cc) {	/* first byte matches... */						/* so check if grouping mb char */						/* Since 1st matched, either match or fail now						 * unless EOF (yuk) */						__scan_getc(sc);					MBG_LOOP:						if (!*++p) { /* is a grouping mb char */							lastblock = i;							++pass;							continue;						}						if (*p == sc->cc) {							__scan_getc(sc);							goto MBG_LOOP;						}						/* bad grouping mb char! */						__scan_ungetc(sc);						if ((sc->cc >= 0) || (p > sc->thousands_sep + 1)) {#ifdef __UCLIBC_HAS_FLOATS__							/* We failed to match a thousep mb char, and							 * we've read too much to recover.  But if							 * this is a floating point conversion and							 * the initial portion of the decpt mb char							 * matches, then we may still be able to							 * recover. */							int k = p - sc->thousands_sep - 1;							if ((psfs->conv_num > CONV_i) /* float conversion */								&& (!pass || (i == nblk1)) /* possible last */								&& !memcmp(sc->thousands_sep, sc->fake_decpt, k)								/* and prefix matched, so could be decpt */								) {								__scan_getc(sc);								p = sc->fake_decpt + k;								do {									if (!*++p) {										strcpy(b, sc->decpt);										b += sc->decpt_len;										goto GOT_DECPT;									}									if (*p != sc->cc) {										__scan_ungetc(sc);										break; /* failed */									}									__scan_getc(sc);								} while (1);							}#endif /* __UCLIBC_HAS_FLOATS__ */							goto DONE;						}						/* was EOF and 1st, so recoverable. */					}				}				if ((i == nblk1) || ((i < nblk1) && !pass)) {					/* got an inner group */					goto DONE_GROUPING_DO_UNGET;				}				goto DONE_DO_UNGET;	/* Matching failure. */			} /* i != 0 */			assert(pass);			goto DONE_DO_UNGET;		} while (1);		assert(0);				/* Should never get here. */	}#endif /***************** digit grouping **********************/	/* Not grouping so first trim all but one leading 0. */#ifdef __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__	DO_TRIM_LEADING_ZEROS:#endif /* __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__ */	if (sc->cc == '0') {		seendigit = 1;		*b++ = '0';				/* Store the first 0. */		do {					/* But ignore all subsequent 0s. */			__scan_getc(sc);		} while (sc->cc == '0');	}#ifdef __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__ DO_NO_GROUP:#endif /* __UCLIBC_HAS_SCANF_LENIENT_DIGIT_GROUPING__ */	/* At this point, we're ready to start reading digits. */#define valid_digit(cc,base) (isxdigit(cc) && ((base == 16) || (cc - '0' < base)))	while (valid_digit(sc->cc,base)) { /* Now for significant digits.*/		if (b - buf < MAX_DIGITS) {			nonzero = seendigit = 1; /* Set nonzero too 0s trimmed above. */			*b++ = sc->cc;#ifdef __UCLIBC_HAS_FLOATS__		} else {			++exp_adjust;#endif		}		__scan_getc(sc);	}#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ DONE_GROUPING_DO_UNGET:#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */	if (psfs->conv_num <= CONV_i) { /* integer conversion */		__scan_ungetc(sc);		*b = 0;						/* null-terminate */		if (!seendigit) {			goto DONE;				/* No digits! */		}		if (psfs->store) {			if (*buf == '-') {				usflag = 0;			}			++psfs->cnt;			_store_inttype(psfs->cur_ptr, psfs->dataargtype,						   (uintmax_t) STRTOUIM(buf, NULL, base, 1-usflag));		}		return 0;	}#ifdef __UCLIBC_HAS_FLOATS__	/* At this point, we have everything left of the decimal point or exponent. */#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ NO_STARTING_DIGIT:#endif	p = sc->fake_decpt;	do {		if (!*p) {			strcpy(b, sc->decpt);			b += sc->decpt_len;			break;		}		if (*p != sc->cc) {			if (p > sc->fake_decpt) {				goto DONE_DO_UNGET;	/* matching failure (read some of decpt) */			}			goto DO_DIGIT_CHECK;		}		++p;		__scan_getc(sc);	} while (1);#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ GOT_DECPT:#endif	if (!nonzero) {		if (sc->cc == '0') {			assert(exp_adjust == 0);			*b++ = '0';			++exp_adjust;			seendigit = 1;			do {				--exp_adjust;				__scan_getc(sc);			} while (sc->cc == '0');		}	}	while (valid_digit(sc->cc,base)) { /* Process fractional digits.*/		if (b - buf < MAX_DIGITS) {			seendigit = 1;			*b++ = sc->cc;		}		__scan_getc(sc);	} DO_DIGIT_CHECK:	/* Hmm... no decimal point.   */	if (!seendigit) {		static const unsigned char nan_inf_str[] = "an\0nfinity";		if (base == 16) {		/* We had a prefix, but no digits! */			goto DONE_DO_UNGET;	/* matching failure */		}		/* Avoid tolower problems for INFINITY in the tr_TR locale. (yuk)*/#undef TOLOWER#define TOLOWER(C)     ((C)|0x20)		switch (TOLOWER(sc->cc)) {			case 'i':				p = nan_inf_str + 3;				break;			case 'n':				p = nan_inf_str;				break;			default:				/* No digits and not inf or nan. */				goto DONE_DO_UNGET;		}		*b++ = sc->cc;		do {			__scan_getc(sc);			if (TOLOWER(sc->cc) == *p) {				*b++ = sc->cc;				++p;				continue;			}			if (!*p || (p == nan_inf_str + 5)) { /* match nan/infinity or inf */				goto GOT_FLOAT;			}			/* Unrecoverable.  Even if on 1st char, we had no digits. */			goto DONE_DO_UNGET;		} while (1);	}	/* If we get here, we had some digits. */	if (#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__		((base == 16) && (((sc->cc)|0x20) == 'p')) ||#endif		(((sc->cc)|0x20) == 'e')		) {						/* Process an exponent. */		*b++ = sc->cc;		__scan_getc(sc);		if (sc->cc < 0) {			goto DONE_DO_UNGET;	/* matching failure.. no exponent digits */		}		if ((sc->cc == '+') || (sc->cc == '-')) { /* Signed exponent? */			*b++ = sc->cc;			__scan_getc(sc);		}#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Fix MAX_EXP_DIGITS!#endif#define MAX_EXP_DIGITS 20		assert(seendigit);		seendigit = 0;		nonzero = 0;				if (sc->cc == '0') {			seendigit = 1;			*b++ = '0';			do {				__scan_getc(sc);			} while (sc->cc == '0');		}		while (__isdigit_char_or_EOF(sc->cc)) { /* Exponent digits (base 10).*/			if (seendigit < MAX_EXP_DIGITS) {				++seendigit;				*b++ = sc->cc;			}			__scan_getc(sc);		}					if (!seendigit) {		/* No digits.  Unrecoverable. */			goto DONE_DO_UNGET;		}	} GOT_FLOAT:	*b = 0;	{		__fpmax_t x;		char *e;		x = __strtofpmax(buf, &e, exp_adjust);		assert(!*e);		if (psfs->store) {			if (psfs->dataargtype & PA_FLAG_LONG_LONG) {				*((long double *)psfs->cur_ptr) = (long double) x;			} else if (psfs->dataargtype & PA_FLAG_LONG) {				*((double *)psfs->cur_ptr) = (double) x;			} else {				*((float *)psfs->cur_ptr) = (float) x;			}			++psfs->cnt;		}		__scan_ungetc(sc);		return 0;	}#endif /* __UCLIBC_HAS_FLOATS__ */ DONE_DO_UNGET:	__scan_ungetc(sc); DONE:	return -2;					/* Matching failure. */}#endif/**********************************************************************/

⌨️ 快捷键说明

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