11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$OpenBSD: vfscanf.c,v 1.21 2006/01/13 21:33:28 millert Exp $ */
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*-
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1990, 1993
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code is derived from software contributed to Berkeley by
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Chris Torek.
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    documentation and/or other materials provided with the distribution.
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    may be used to endorse or promote products derived from this software
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    without specific prior written permission.
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <ctype.h>
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <inttypes.h>
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdarg.h>
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stddef.h>
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "local.h"
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "floatio.h"
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	BUF		513	/* Maximum length of numeric string. */
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flags used during conversion.
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	LONG		0x00001	/* l: long or double */
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	LONGDBL		0x00002	/* L: long double; unimplemented */
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	SHORT		0x00004	/* h: short */
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	SHORTSHORT	0x00008	/* hh: 8 bit integer */
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define LLONG		0x00010	/* ll: long long (+ deprecated q: quad) */
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	POINTER		0x00020	/* p: void * (as hex) */
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	SIZEINT		0x00040	/* z: (signed) size_t */
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	MAXINT		0x00080	/* j: intmax_t */
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	PTRINT		0x00100	/* t: ptrdiff_t */
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	NOSKIP		0x00200	/* [ or c: do not skip blanks */
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	SUPPRESS	0x00400	/* *: suppress assignment */
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	UNSIGNED	0x00800	/* %[oupxX] conversions */
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The following are used in numeric conversions only:
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point;
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral.
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	SIGNOK		0x01000	/* +/- is (still) legal */
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	HAVESIGN	0x02000	/* sign detected */
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	NDIGITS		0x04000	/* no digits detected */
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	DPTOK		0x08000	/* (float) decimal point is still legal */
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	EXPOK		0x10000	/* (float) exponent (e+3, etc) still legal */
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	PFXOK		0x08000	/* 0x prefix is (still) legal */
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	NZDIGITS	0x10000	/* no zero digits detected */
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Conversion types.
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	CT_CHAR		0	/* %c conversion */
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	CT_CCL		1	/* %[...] conversion */
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	CT_STRING	2	/* %s conversion */
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	CT_INT		3	/* integer, i.e., strtoimax or strtoumax */
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	CT_FLOAT	4	/* floating, i.e., strtod */
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define u_char unsigned char
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define u_long unsigned long
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic u_char *__sccl(char *, u_char *);
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if !defined(VFSCANF)
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define VFSCANF	vfscanf
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * vfscanf
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectVFSCANF(FILE *fp, const char *fmt0, __va_list ap)
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_char *fmt = (u_char *)fmt0;
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int c;		/* character from format, or conversion */
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	size_t width;	/* field width, or 0 */
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *p;	/* points into all kinds of strings */
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n;		/* handy integer */
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int flags;	/* flags as defined above */
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *p0;	/* saves original value of p when necessary */
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int nassigned;		/* number of fields assigned */
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int nread;		/* number of characters consumed from fp */
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int base;		/* base argument to strtoimax/strtouimax */
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char ccltab[256];	/* character class table for %[...] */
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char buf[BUF];		/* buffer for numeric conversions */
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* `basefix' is used to avoid `if' tests in the integer scanner */
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	static short basefix[17] =
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		{ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
120f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	FLOCKFILE(fp);
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_SET_ORIENTATION(fp, -1);
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	nassigned = 0;
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	nread = 0;
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	base = 0;		/* XXX just to keep gcc happy */
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (;;) {
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		c = *fmt++;
128f582340a6a48588aa50da17e1620e8f91b146941Kenny Root		if (c == 0) {
129f582340a6a48588aa50da17e1620e8f91b146941Kenny Root			FUNLOCKFILE(fp);
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (nassigned);
131f582340a6a48588aa50da17e1620e8f91b146941Kenny Root		}
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (isspace(c)) {
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while ((fp->_r > 0 || __srefill(fp) == 0) &&
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    isspace(*fp->_p))
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nread++, fp->_r--, fp->_p++;
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (c != '%')
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto literal;
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		width = 0;
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		flags = 0;
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * switch on the format.  continue if done;
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * break once format type is derived.
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectagain:		c = *fmt++;
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (c) {
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '%':
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectliteral:
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (fp->_r <= 0 && __srefill(fp))
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto input_failure;
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*fp->_p != c)
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto match_failure;
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			fp->_r--, fp->_p++;
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nread++;
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '*':
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= SUPPRESS;
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'j':
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= MAXINT;
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'L':
165712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries			flags |=
166712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries				(*fmt == 'd') ? LLONG :
167712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries				(*fmt == 'i') ? LLONG :
168712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries				(*fmt == 'o') ? LLONG :
169712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries				(*fmt == 'u') ? LLONG :
170712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries				(*fmt == 'x') ? LLONG :
171712e4f81e066578b0925dbfb5a6b664aeba5f564Chris Fries				LONGDBL;
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'h':
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*fmt == 'h') {
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fmt++;
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= SHORTSHORT;
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= SHORT;
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'l':
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*fmt == 'l') {
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fmt++;
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= LLONG;
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= LONG;
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'q':
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LLONG;		/* deprecated */
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 't':
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= PTRINT;
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'z':
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= SIZEINT;
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '0': case '1': case '2': case '3': case '4':
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '5': case '6': case '7': case '8': case '9':
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			width = width * 10 + c - '0';
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Conversions.
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Those marked `compat' are for 4.[123]BSD compatibility.
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * (According to ANSI, E and X formats are supposed
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * to the same as e and x.  Sorry about that.)
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'D':	/* compat */
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONG;
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* FALLTHROUGH */
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'd':
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_INT;
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = 10;
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'i':
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_INT;
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = 0;
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'O':	/* compat */
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONG;
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* FALLTHROUGH */
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'o':
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_INT;
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= UNSIGNED;
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = 8;
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'u':
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_INT;
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= UNSIGNED;
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = 10;
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'X':
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'x':
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= PFXOK;	/* enable 0x prefixing */
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_INT;
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= UNSIGNED;
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = 16;
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'E':
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'G':
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'e':
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'f':
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'g':
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_FLOAT;
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 's':
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_STRING;
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '[':
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			fmt = __sccl(ccltab, fmt);
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= NOSKIP;
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_CCL;
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'c':
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= NOSKIP;
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_CHAR;
2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'p':	/* pointer format is like hex */
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= POINTER | PFXOK;
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_INT;
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= UNSIGNED;
2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = 16;
2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'n':
2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & SUPPRESS)
2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & SHORTSHORT)
2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, __signed char *) = nread;
2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & SHORT)
2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, short *) = nread;
2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & LONG)
2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, long *) = nread;
2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & SIZEINT)
2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, ssize_t *) = nread;
2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & PTRINT)
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, ptrdiff_t *) = nread;
2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & LLONG)
2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, long long *) = nread;
2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & MAXINT)
2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, intmax_t *) = nread;
2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*va_arg(ap, int *) = nread;
2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Disgusting backwards compatibility hacks.	XXX
3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '\0':	/* compat */
304f582340a6a48588aa50da17e1620e8f91b146941Kenny Root			FUNLOCKFILE(fp);
3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (EOF);
3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:	/* compat */
3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (isupper(c))
3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= LONG;
3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = CT_INT;
3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = 10;
3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * We have a conversion that requires input.
3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (fp->_r <= 0 && __srefill(fp))
3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto input_failure;
3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Consume leading white space, except for formats
3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * that suppress this.
3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((flags & NOSKIP) == 0) {
3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while (isspace(*fp->_p)) {
3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nread++;
3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (--fp->_r > 0)
3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					fp->_p++;
3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (__srefill(fp))
3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto input_failure;
3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * Note that there is at least one character in
3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * the buffer, so conversions that do not set NOSKIP
3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * ca no longer result in an input failure.
3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Do the conversion.
3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (c) {
3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case CT_CHAR:
3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* scan arbitrary characters (sets NOSKIP) */
3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (width == 0)
3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				width = 1;
3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & SUPPRESS) {
3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size_t sum = 0;
3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				for (;;) {
3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if ((n = fp->_r) < (int)width) {
3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						sum += n;
3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						width -= n;
3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						fp->_p += n;
3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						if (__srefill(fp)) {
3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							if (sum == 0)
3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							    goto input_failure;
3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							break;
3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						}
3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					} else {
3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						sum += width;
3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						fp->_r -= width;
3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						fp->_p += width;
3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nread += sum;
3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size_t r = fread((void *)va_arg(ap, char *), 1,
3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    width, fp);
3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (r == 0)
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto input_failure;
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nread += r;
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nassigned++;
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case CT_CCL:
3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* scan a (nonempty) character class (sets NOSKIP) */
3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (width == 0)
3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				width = (size_t)~0;	/* `infinity' */
3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* take only those things in the class */
3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & SUPPRESS) {
3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = 0;
3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				while (ccltab[*fp->_p]) {
3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					n++, fp->_r--, fp->_p++;
3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (--width == 0)
3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (fp->_r <= 0 && __srefill(fp)) {
3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						if (n == 0)
3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							goto input_failure;
3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (n == 0)
3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto match_failure;
3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				p0 = p = va_arg(ap, char *);
4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				while (ccltab[*fp->_p]) {
4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					fp->_r--;
4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*p++ = *fp->_p++;
4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (--width == 0)
4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (fp->_r <= 0 && __srefill(fp)) {
4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						if (p == p0)
4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project							goto input_failure;
4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = p - p0;
4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (n == 0)
4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto match_failure;
4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p = '\0';
4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nassigned++;
4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nread += n;
4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case CT_STRING:
4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* like CCL, but zero-length string OK, & no NOSKIP */
4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (width == 0)
4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				width = (size_t)~0;
4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & SUPPRESS) {
4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = 0;
4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				while (!isspace(*fp->_p)) {
4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					n++, fp->_r--, fp->_p++;
4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (--width == 0)
4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (fp->_r <= 0 && __srefill(fp))
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nread += n;
4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				p0 = p = va_arg(ap, char *);
4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				while (!isspace(*fp->_p)) {
4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					fp->_r--;
4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*p++ = *fp->_p++;
4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (--width == 0)
4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (fp->_r <= 0 && __srefill(fp))
4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;
4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p = '\0';
4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nread += p - p0;
4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nassigned++;
4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case CT_INT:
4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* scan an integer as if by strtoimax/strtoumax */
4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef hardway
4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (width == 0 || width > sizeof(buf) - 1)
4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				width = sizeof(buf) - 1;
4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* size_t is unsigned, hence this optimisation */
4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (--width > sizeof(buf) - 2)
4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				width = sizeof(buf) - 2;
4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			width++;
4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= SIGNOK | NDIGITS | NZDIGITS;
4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for (p = buf; width; width--) {
4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				c = *fp->_p;
4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * Switch on the character; `goto ok'
4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * if we accept it as a part of number.
4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				switch (c) {
4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * The digit 0 is always legal, but is
4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * special.  For %i conversions, if no
4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * digits (zero or nonzero) have been
4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * scanned (only signs), we will have
4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * base==0.  In that case, we should set
4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * it to 8 and enable 0x prefixing.
4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * Also, if we have not scanned zero digits
4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * before this, do not turn off prefixing
4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * (someone else will turn it off if we
4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * have scanned any nonzero digits).
4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '0':
4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (base == 0) {
4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						base = 8;
4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						flags |= PFXOK;
4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (flags & NZDIGITS)
4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					    flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					else
4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					    flags &= ~(SIGNOK|PFXOK|NDIGITS);
4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ok;
4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* 1 through 7 always legal */
4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '1': case '2': case '3':
4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '4': case '5': case '6': case '7':
4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					base = basefix[base];
4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					flags &= ~(SIGNOK | PFXOK | NDIGITS);
4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ok;
5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* digits 8 and 9 ok iff decimal or hex */
5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '8': case '9':
5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					base = basefix[base];
5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (base <= 8)
5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;	/* not legal here */
5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					flags &= ~(SIGNOK | PFXOK | NDIGITS);
5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ok;
5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* letters ok iff hex */
5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 'A': case 'B': case 'C':
5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 'D': case 'E': case 'F':
5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 'a': case 'b': case 'c':
5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 'd': case 'e': case 'f':
5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* no need to fix base here */
5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (base <= 10)
5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						break;	/* not legal here */
5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					flags &= ~(SIGNOK | PFXOK | NDIGITS);
5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto ok;
5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* sign ok only as first character */
5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '+': case '-':
5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (flags & SIGNOK) {
5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						flags &= ~SIGNOK;
5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						flags |= HAVESIGN;
5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto ok;
5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * x ok iff flag still set and 2nd char (or
5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * 3rd char if we have a sign).
5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 'x': case 'X':
5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if ((flags & PFXOK) && p ==
5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					    buf + 1 + !!(flags & HAVESIGN)) {
5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						base = 16;	/* if %i */
5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						flags &= ~PFXOK;
5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto ok;
5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
5411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
5421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
5441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * If we got here, c is not a legal character
5451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * for a number.  Stop accumulating digits.
5461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
5471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
5481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ok:
5491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * c is legal: store it and look at the next.
5511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
5521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p++ = c;
5531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (--fp->_r > 0)
5541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					fp->_p++;
5551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (__srefill(fp))
5561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;		/* EOF */
5571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
5591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * If we had only a sign, it is no good; push
5601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * back the sign.  If the number ends in `x',
5611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * it was [sign] '0' 'x', so push back the x
5621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * and treat it as [sign] '0'.
5631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
5641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & NDIGITS) {
5651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (p > buf)
5661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					(void) ungetc(*(u_char *)--p, fp);
5671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto match_failure;
5681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = ((u_char *)p)[-1];
5701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (c == 'x' || c == 'X') {
5711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				--p;
5721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				(void) ungetc(c, fp);
5731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((flags & SUPPRESS) == 0) {
5751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				uintmax_t res;
5761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p = '\0';
5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (flags & UNSIGNED)
5791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					res = strtoumax(buf, NULL, base);
5801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
5811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					res = strtoimax(buf, NULL, base);
5821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (flags & POINTER)
5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, void **) =
5841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					    (void *)(uintptr_t)res;
5851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & MAXINT)
5861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, intmax_t *) = res;
5871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & LLONG)
5881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, long long *) = res;
5891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & SIZEINT)
5901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, ssize_t *) = res;
5911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & PTRINT)
5921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, ptrdiff_t *) = res;
5931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & LONG)
5941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, long *) = res;
5951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & SHORT)
5961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, short *) = res;
5971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & SHORTSHORT)
5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, __signed char *) = res;
5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
6001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, int *) = res;
6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nassigned++;
6021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
6031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nread += p - buf;
6041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case CT_FLOAT:
6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* scan a floating point number as if by strtod */
6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef hardway
6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (width == 0 || width > sizeof(buf) - 1)
6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				width = sizeof(buf) - 1;
6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* size_t is unsigned, hence this optimisation */
6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (--width > sizeof(buf) - 2)
6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				width = sizeof(buf) - 2;
6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			width++;
6171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for (p = buf; width; width--) {
6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				c = *fp->_p;
6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
6221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * This code mimicks the integer conversion
6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * code, but is much simpler.
6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				switch (c) {
6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '0': case '1': case '2': case '3':
6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '4': case '5': case '6': case '7':
6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '8': case '9':
6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					flags &= ~(SIGNOK | NDIGITS);
6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto fok;
6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '+': case '-':
6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (flags & SIGNOK) {
6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						flags &= ~SIGNOK;
6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto fok;
6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case '.':
6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (flags & DPTOK) {
6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						flags &= ~(SIGNOK | DPTOK);
6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto fok;
6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case 'e': case 'E':
6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* no exponent without some digits */
6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						flags =
6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						    (flags & ~(EXPOK|DPTOK)) |
6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						    SIGNOK | NDIGITS;
6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						goto fok;
6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
6561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		fok:
6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p++ = c;
6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (--fp->_r > 0)
6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					fp->_p++;
6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (__srefill(fp))
6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;	/* EOF */
6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * If no digits, might be missing exponent digits
6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * (just give back the exponent) or might be missing
6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * regular digits, but had sign and/or decimal point.
6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & NDIGITS) {
6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (flags & EXPOK) {
6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* no digits at all */
6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					while (p > buf)
6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						ungetc(*(u_char *)--p, fp);
6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto match_failure;
6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* just a bad exponent (e and maybe sign) */
6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				c = *(u_char *)--p;
6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (c != 'e' && c != 'E') {
6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					(void) ungetc(c, fp);/* sign */
6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					c = *(u_char *)--p;
6801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
6811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				(void) ungetc(c, fp);
6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((flags & SUPPRESS) == 0) {
6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				double res;
6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p = '\0';
6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				res = strtod(buf, (char **) NULL);
6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (flags & LONGDBL)
6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, long double *) = res;
6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else if (flags & LONG)
6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, double *) = res;
6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*va_arg(ap, float *) = res;
6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nassigned++;
6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nread += p - buf;
6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */
6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectinput_failure:
702f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	if (nassigned == 0)
703f582340a6a48588aa50da17e1620e8f91b146941Kenny Root		nassigned = -1;
7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectmatch_failure:
705f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	FUNLOCKFILE(fp);
7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (nassigned);
7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Fill in the given table from the scanset at the given format
7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (just after `[').  Return a pointer to the character past the
7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * closing `]'.  The table has a 1 wherever characters should be
7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * considered part of the scanset.
7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
7151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic u_char *
7161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__sccl(char *tab, u_char *fmt)
7171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
7181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int c, n, v;
7191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* first `clear' the whole table */
7211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	c = *fmt++;		/* first char hat => negated scanset */
7221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (c == '^') {
7231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		v = 1;		/* default => accept */
7241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		c = *fmt++;	/* get new first char */
7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else
7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		v = 0;		/* default => reject */
7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* should probably use memset here */
7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (n = 0; n < 256; n++)
7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		tab[n] = v;
7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (c == 0)
7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (fmt - 1);/* format ended before closing ] */
7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
7341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Now set the entries corresponding to the actual scanset
7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * to the opposite of the above.
7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *
7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * The first character may be ']' (or '-') without being special;
7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * the last character may be '-'.
7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
7401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	v = 1 - v;
7411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (;;) {
7421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		tab[c] = v;		/* take character c */
7431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdoswitch:
7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = *fmt++;		/* and examine the next */
7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (n) {
7461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 0:			/* format ended too soon */
7481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (fmt - 1);
7491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '-':
7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
7521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * A scanset of the form
7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	[01+-]
7541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * is defined as `the digit 0, the digit 1,
7551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * the character +, the character -', but
7561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * the effect of a scanset such as
7571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	[a-zA-Z0-9]
7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * is implementation defined.  The V7 Unix
7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * scanf treats `a-z' as `the letters a through
7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * z', but treats `a-a' as `the letter a, the
7611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * character -, and the letter a'.
7621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *
7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * For compatibility, the `-' is not considerd
7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * to define a range if the character following
7651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * it is either a close bracket (required by ANSI)
7661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * or is not numerically greater than the character
7671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * we just stored in the table (c).
7681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
7691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = *fmt;
7701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n == ']' || n < c) {
7711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				c = '-';
7721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;	/* resume the for(;;) */
7731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			fmt++;
7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			do {		/* fill in the range */
7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				tab[++c] = v;
7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} while (c < n);
7781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1	/* XXX another disgusting compatibility hack */
7791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * Alas, the V7 Unix scanf also treats formats
7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * such as [a-c-e] as `the letters a through e'.
7821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * This too is permitted by the standard....
7831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
7841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto doswitch;
7851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
7861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = *fmt++;
7871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (c == 0)
7881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return (fmt - 1);
7891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (c == ']')
7901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return (fmt);
7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case ']':		/* end of scanset */
7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (fmt);
7961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:		/* just another character */
7981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			c = n;
7991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
8001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
8011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
8021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* NOTREACHED */
8031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
804