11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$OpenBSD: vfprintf.c,v 1.37 2006/01/13 17:56:18 millert Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*-
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1990 The Regents of the University of California.
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 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/*
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Actual printf innards.
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code is large and complicated...
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h>
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/mman.h>
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdarg.h>
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stddef.h>
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdint.h>
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "local.h"
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "fvwrite.h"
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void __find_arguments(const char *fmt0, va_list ap, va_list **argtable,
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    size_t *argtablesiz);
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int __grow_type_table(unsigned char **typetable, int *tablesize);
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flush out all the vectors defined by the given uio,
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * then reset it so that it can be reused.
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__sprint(FILE *fp, struct __suio *uio)
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int err;
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (uio->uio_resid == 0) {
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		uio->uio_iovcnt = 0;
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (0);
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	err = __sfvwrite(fp, uio);
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uio->uio_resid = 0;
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uio->uio_iovcnt = 0;
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (err);
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Helper function for `fprintf to unbuffered unix file': creates a
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * temporary buffer.  We only work on write-only files; this avoids
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * worries about ungetc buffers and so forth.
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__sbprintf(FILE *fp, const char *fmt, va_list ap)
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ret;
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	FILE fake;
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct __sfileext fakeext;
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	unsigned char buf[BUFSIZ];
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_FILEEXT_SETUP(&fake, &fakeext);
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* copy the important variables */
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fake._flags = fp->_flags & ~__SNBF;
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fake._file = fp->_file;
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fake._cookie = fp->_cookie;
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fake._write = fp->_write;
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* set up the buffer */
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fake._bf._base = fake._p = buf;
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fake._bf._size = fake._w = sizeof(buf);
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fake._lbfsize = 0;	/* not actually used, but Just In Case */
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* do the work, then copy any error status */
103f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	ret = __vfprintf(&fake, fmt, ap);
104f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	if (ret >= 0 && __sflush(&fake))
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ret = EOF;
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (fake._flags & __SERR)
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		fp->_flags |= __SERR;
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (ret);
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <locale.h>
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <math.h>
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "floatio.h"
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	BUF		(MAXEXP+MAXFRACT+1)	/* + decimal point */
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	DEFPREC		6
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *cvt(double, int, int, char *, int *, int, int *);
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int exponent(char *, int, int);
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* no FLOATING_POINT */
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	BUF		40
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define STATIC_ARG_TBL_SIZE 8	/* Size of static argument table. */
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC: do not link libm for only two rather simple functions */
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic  int  _my_isinf(double);
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic  int  _my_isnan(double);
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Macros for converting digits to letters and vice versa
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	to_digit(c)	((c) - '0')
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define is_digit(c)	((unsigned)to_digit(c) <= 9)
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	to_char(n)	((n) + '0')
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flags used during conversion.
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	ALT		0x0001		/* alternate form */
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	HEXPREFIX	0x0002		/* add 0x or 0X prefix */
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	LADJUST		0x0004		/* left adjustment */
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	LONGDBL		0x0008		/* long double; unimplemented */
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	LONGINT		0x0010		/* long integer */
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	LLONGINT	0x0020		/* long long integer */
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	SHORTINT	0x0040		/* short integer */
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	ZEROPAD		0x0080		/* zero (as opposed to blank) pad */
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define FPT		0x0100		/* Floating point number */
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PTRINT		0x0200		/* (unsigned) ptrdiff_t */
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define SIZEINT		0x0400		/* (signed) size_t */
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define CHARINT		0x0800		/* 8 bit integer */
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define MAXINT		0x1000		/* largest integer size (intmax_t) */
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvfprintf(FILE *fp, const char *fmt0, __va_list ap)
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
161f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	int ret;
162f582340a6a48588aa50da17e1620e8f91b146941Kenny Root
163f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	FLOCKFILE(fp);
164f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	ret = __vfprintf(fp, fmt0, ap);
165f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	FUNLOCKFILE(fp);
166f582340a6a48588aa50da17e1620e8f91b146941Kenny Root	return (ret);
167f582340a6a48588aa50da17e1620e8f91b146941Kenny Root}
168f582340a6a48588aa50da17e1620e8f91b146941Kenny Root
169f582340a6a48588aa50da17e1620e8f91b146941Kenny Rootint
170f582340a6a48588aa50da17e1620e8f91b146941Kenny Root__vfprintf(FILE *fp, const char *fmt0, __va_list ap)
171f582340a6a48588aa50da17e1620e8f91b146941Kenny Root{
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *fmt;	/* format string */
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ch;	/* character from fmt */
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n, m, n2;	/* handy integers (short term usage) */
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *cp;	/* handy char pointer (short term usage) */
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *cp_free = NULL;  /* BIONIC: copy of cp to be freed after usage */
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct __siov *iovp;/* for PRINT macro */
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int flags;	/* flags as above */
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ret;		/* return value accumulator */
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int width;		/* width from format (%8d), or 0 */
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int prec;		/* precision from format (%.3d), or -1 */
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char sign;		/* sign prefix (' ', '+', '-', or \0) */
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wchar_t wc;
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	void* ps;
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *decimal_point = ".";
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char softsign;		/* temporary negative sign for floats */
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	double _double = 0.;	/* double precision arguments %[eEfgG] */
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int expt;		/* integer value of exponent */
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int expsize = 0;	/* character count for expstr */
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ndig;		/* actual number of digits returned by cvt */
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char expstr[7];		/* buffer for exponent string */
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uintmax_t _umax;	/* integer arguments %[diouxX] */
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int dprec;		/* a copy of prec if [diouxX], 0 otherwise */
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int realsz;		/* field size expanded by dprec */
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int size;		/* size of converted field or string */
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char* xdigs = NULL;		/* digits for [xX] conversion */
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define NIOV 8
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct __suio uio;	/* output information: summary */
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct __siov iov[NIOV];/* ... and individual io vectors */
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char buf[BUF];		/* space for %c, %[diouxX], %[eEfgG] */
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char ox[2];		/* space for 0x hex-prefix */
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	va_list *argtable;	/* args, built due to positional arg */
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	va_list statargtable[STATIC_ARG_TBL_SIZE];
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	size_t argtablesiz;
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int nextarg;		/* 1-based argument index */
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	va_list orgap;		/* original argument pointer */
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Choose PADSIZE to trade efficiency vs. size.  If larger printf
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * fields occur frequently, increase PADSIZE and make the initialisers
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * below longer.
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	PADSIZE	16		/* pad chunk size */
2170946b1f6e9223a0a82306e40fc2b41ebddb1f7efGlenn Kasten	static const char blanks[PADSIZE] =
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
2190946b1f6e9223a0a82306e40fc2b41ebddb1f7efGlenn Kasten	static const char zeroes[PADSIZE] =
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * BEWARE, these `goto error' on error, and PAD uses `n'.
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	PRINT(ptr, len) do { \
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	iovp->iov_base = (ptr); \
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	iovp->iov_len = (len); \
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uio.uio_resid += (len); \
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	iovp++; \
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (++uio.uio_iovcnt >= NIOV) { \
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (__sprint(fp, &uio)) \
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto error; \
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		iovp = iov; \
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} \
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} while (0)
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	PAD(howmany, with) do { \
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((n = (howmany)) > 0) { \
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while (n > PADSIZE) { \
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PRINT(with, PADSIZE); \
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n -= PADSIZE; \
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} \
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		PRINT(with, n); \
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} \
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} while (0)
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	FLUSH() do { \
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (uio.uio_resid && __sprint(fp, &uio)) \
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto error; \
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uio.uio_iovcnt = 0; \
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	iovp = iov; \
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} while (0)
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * To extend shorts properly, we need both signed and unsigned
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * argument extraction methods.
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	SARG() \
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	((intmax_t)(flags&MAXINT ? GETARG(intmax_t) : \
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&LLONGINT ? GETARG(long long) : \
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&LONGINT ? GETARG(long) : \
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&PTRINT ? GETARG(ptrdiff_t) : \
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&SIZEINT ? GETARG(ssize_t) : \
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&SHORTINT ? (short)GETARG(int) : \
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&CHARINT ? (__signed char)GETARG(int) : \
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    GETARG(int)))
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	UARG() \
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	((uintmax_t)(flags&MAXINT ? GETARG(uintmax_t) : \
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&LLONGINT ? GETARG(unsigned long long) : \
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&LONGINT ? GETARG(unsigned long) : \
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&PTRINT ? (uintptr_t)GETARG(ptrdiff_t) : /* XXX */ \
2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&SIZEINT ? GETARG(size_t) : \
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&SHORTINT ? (unsigned short)GETARG(int) : \
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    flags&CHARINT ? (unsigned char)GETARG(int) : \
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    GETARG(unsigned int)))
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 /*
2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	  * Get * arguments, including the form *nn$.  Preserve the nextarg
2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	  * that the argument can be gotten once the type is determined.
2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	  */
2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define GETASTER(val) \
2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n2 = 0; \
2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp = fmt; \
2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (is_digit(*cp)) { \
2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n2 = 10 * n2 + to_digit(*cp); \
2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp++; \
2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} \
2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*cp == '$') { \
2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		int hold = nextarg; \
2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (argtable == NULL) { \
2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			argtable = statargtable; \
2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			__find_arguments(fmt0, orgap, &argtable, &argtablesiz); \
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} \
2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		nextarg = n2; \
2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		val = GETARG(int); \
2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		nextarg = hold; \
2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		fmt = ++cp; \
2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else { \
2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		val = GETARG(int); \
2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project* Get the argument indexed by nextarg.   If the argument table is
3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project* built, use it to get the argument.  If its not, get the next
3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project* argument (and arguments must be gotten sequentially).
3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/
3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define GETARG(type) \
3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(((argtable != NULL) ? (void)(ap = argtable[nextarg]) : (void)0), \
3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 nextarg++, va_arg(ap, type))
3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_SET_ORIENTATION(fp, -1);
3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (cantwrite(fp)) {
3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		errno = EBADF;
3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (EOF);
3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* optimise fprintf(stderr) (and other unbuffered Unix files) */
3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    fp->_file >= 0)
3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (__sbprintf(fp, fmt0, ap));
3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fmt = (char *)fmt0;
3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	argtable = NULL;
3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	nextarg = 1;
3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	va_copy(orgap, ap);
3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uio.uio_iov = iovp = iov;
3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uio.uio_resid = 0;
3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uio.uio_iovcnt = 0;
3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ret = 0;
3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	memset(&ps, 0, sizeof(ps));
3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Scan the format for conversions (`%' character).
3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (;;) {
3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp = fmt;
3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1  /* BIONIC */
3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                n = -1;
3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                while ( (wc = *fmt) != 0 ) {
3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    if (wc == '%') {
3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        n = 1;
3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        break;
3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    }
3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    fmt++;
3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while ((n = mbrtowc(&wc, fmt, MB_CUR_MAX, &ps)) > 0) {
3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			fmt += n;
3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (wc == '%') {
3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fmt--;
3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((m = fmt - cp) != 0) {
3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PRINT(cp, m);
3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ret += m;
3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (n <= 0)
3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto done;
3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		fmt++;		/* skip over '%' */
3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		flags = 0;
3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		dprec = 0;
3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		width = 0;
3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		prec = -1;
3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		sign = '\0';
3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectrflag:		ch = *fmt++;
3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectreswitch:	switch (ch) {
3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case ' ':
3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * ``If the space and + flags both appear, the space
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * flag will be ignored.''
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	-- ANSI X3J11
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!sign)
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				sign = ' ';
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '#':
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= ALT;
3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '*':
3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * ``A negative field width argument is taken as a
3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * - flag followed by a positive field width.''
3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	-- ANSI X3J11
3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * They don't exclude field widths read from args.
3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			GETASTER(width);
3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (width >= 0)
3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto rflag;
3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			width = -width;
3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* FALLTHROUGH */
3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '-':
3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LADJUST;
3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '+':
3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			sign = '+';
3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '.':
4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((ch = *fmt++) == '*') {
4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				GETASTER(n);
4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				prec = n < 0 ? -1 : n;
4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto rflag;
4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = 0;
4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while (is_digit(ch)) {
4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = 10 * n + to_digit(ch);
4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ch = *fmt++;
4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch == '$') {
4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nextarg = n;
4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (argtable == NULL) {
4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					argtable = statargtable;
4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					__find_arguments(fmt0, orgap,
4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					    &argtable, &argtablesiz);
4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto rflag;
4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			prec = n < 0 ? -1 : n;
4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto reswitch;
4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '0':
4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * ``Note that 0 is taken as a flag, not as the
4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * beginning of a field width.''
4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	-- ANSI X3J11
4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= ZEROPAD;
4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '1': case '2': case '3': case '4':
4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '5': case '6': case '7': case '8': case '9':
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = 0;
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			do {
4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = 10 * n + to_digit(ch);
4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ch = *fmt++;
4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} while (is_digit(ch));
4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch == '$') {
4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nextarg = n;
4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (argtable == NULL) {
4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					argtable = statargtable;
4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					__find_arguments(fmt0, orgap,
4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					    &argtable, &argtablesiz);
4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto rflag;
4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			width = n;
4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto reswitch;
4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'L':
4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGDBL;
4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'h':
4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= SHORTINT;
4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'j':
4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= MAXINT;
4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'l':
4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*fmt == 'l') {
4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fmt++;
4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= LLONGINT;
4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= LONGINT;
4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'q':
4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LLONGINT;
4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 't':
4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= PTRINT;
4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'z':
4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= SIZEINT;
4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'c':
4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*(cp = buf) = GETARG(int);
4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			size = 1;
4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			sign = '\0';
4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'D':
4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGINT;
4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*FALLTHROUGH*/
4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'd':
4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'i':
4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			_umax = SARG();
4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((intmax_t)_umax < 0) {
4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				_umax = -_umax;
4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				sign = '-';
4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = DEC;
4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto number;
4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'e':
4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'E':
4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'f':
4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'g':
4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'G':
4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (prec == -1) {
5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				prec = DEFPREC;
5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else if ((ch == 'g' || ch == 'G') && prec == 0) {
5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				prec = 1;
5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & LONGDBL) {
5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				_double = (double) GETARG(long double);
5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				_double = GETARG(double);
5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* do this before tricky precision changes */
5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (_my_isinf(_double)) {
5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (_double < 0)
5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					sign = '-';
5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				cp = "Inf";
5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size = 3;
5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (_my_isnan(_double)) {
5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				cp = "NaN";
5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size = 3;
5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= FPT;
5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp = cvt(_double, prec, flags, &softsign,
5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				&expt, ch, &ndig);
5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    cp_free = cp;
5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch == 'g' || ch == 'G') {
5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (expt <= -4 || expt > prec)
5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					ch = (ch == 'g') ? 'e' : 'E';
5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				else
5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					ch = 'g';
5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch <= 'e') {	/* 'e' or 'E' fmt */
5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				--expt;
5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				expsize = exponent(expstr, expt, ch);
5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size = expsize + ndig;
5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (ndig > 1 || flags & ALT)
5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					++size;
5411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else if (ch == 'f') {		/* f fmt */
5421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (expt > 0) {
5431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					size = expt;
5441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (prec || flags & ALT)
5451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						size += prec + 1;
5461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				} else	/* "0.X" */
5471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					size = prec + 2;
5481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else if (expt >= ndig) {	/* fixed g fmt */
5491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size = expt;
5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (flags & ALT)
5511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					++size;
5521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else
5531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size = ndig + (expt > 0 ?
5541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					1 : 2 - expt);
5551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (softsign)
5571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				sign = '-';
5581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
5591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */
5601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* the Android security team suggests removing support for %n
5611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * since it has no real practical value, and could lead to
5629145ad3f0ae917e6daddbceaa541dfbe208a3bc5Nick Kralevich * running malicious code (for really buggy programs that
5631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * send to printf() user-generated formatting strings).
5641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
5651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 0
5661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'n':
5671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & LLONGINT)
5681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(long long *) = ret;
5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & LONGINT)
5701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(long *) = ret;
5711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & SHORTINT)
5721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(short *) = ret;
5731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & CHARINT)
5741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(__signed char *) = ret;
5751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & PTRINT)
5761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(ptrdiff_t *) = ret;
5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & SIZEINT)
5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(ssize_t *) = ret;
5791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & MAXINT)
5801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(intmax_t *) = ret;
5811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
5821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*GETARG(int *) = ret;
5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;	/* no output */
5841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
5851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'O':
5861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGINT;
5871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*FALLTHROUGH*/
5881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'o':
5891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			_umax = UARG();
5901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = OCT;
5911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto nosign;
5921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'p':
5931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
5941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * ``The argument shall be a pointer to void.  The
5951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * value of the pointer is converted to a sequence
5961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * of printable characters, in an implementation-
5971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * defined manner.''
5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	-- ANSI X3J11
5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
6001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* NOSTRICT */
6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			_umax = (u_long)GETARG(void *);
6021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = HEX;
6031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			xdigs = "0123456789abcdef";
6041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= HEXPREFIX;
6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ch = 'x';
6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto nosign;
6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 's':
6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((cp = GETARG(char *)) == NULL)
6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				cp = "(null)";
6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (prec >= 0) {
6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * can't use strlen; can only look for the
6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * NUL in the first `prec' characters, and
6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * strlen() will go further.
6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				char *p = memchr(cp, 0, prec);
6171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (p != NULL) {
6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					size = p - cp;
6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (size > prec)
6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						size = prec;
6221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				} else
6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					size = prec;
6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else
6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				size = strlen(cp);
6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			sign = '\0';
6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'U':
6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGINT;
6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*FALLTHROUGH*/
6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'u':
6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			_umax = UARG();
6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = DEC;
6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto nosign;
6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'X':
6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			xdigs = "0123456789ABCDEF";
6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto hex;
6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'x':
6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			xdigs = "0123456789abcdef";
6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecthex:			_umax = UARG();
6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			base = HEX;
6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* leading 0x/X only if non-zero */
6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & ALT && _umax != 0)
6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= HEXPREFIX;
6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* unsigned conversions */
6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectnosign:			sign = '\0';
6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * ``... diouXx conversions ... if a precision is
6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * specified, the 0 flag will be ignored.''
6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	-- ANSI X3J11
6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectnumber:			if ((dprec = prec) >= 0)
6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags &= ~ZEROPAD;
6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * ``The result of converting a zero value with an
6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * explicit precision of zero is no characters.''
6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 *	-- ANSI X3J11
6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp = buf + BUF;
6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (_umax != 0 || prec != 0) {
6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * Unsigned mod is hard, and unsigned mod
6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * by a constant is easier than that by
6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * a variable; hence this switch.
6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				switch (base) {
6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case OCT:
6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					do {
6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						*--cp = to_char(_umax & 7);
6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						_umax >>= 3;
6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					} while (_umax);
6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* handle octal leading 0 */
6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (flags & ALT && *cp != '0')
6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						*--cp = '0';
6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case DEC:
6801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* many numbers are 1 digit */
6811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					while (_umax >= 10) {
6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						*--cp = to_char(_umax % 10);
6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						_umax /= 10;
6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					*--cp = to_char(_umax);
6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				case HEX:
6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					do {
6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						*--cp = xdigs[_umax & 15];
6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						_umax >>= 4;
6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					} while (_umax);
6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				default:
6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					cp = "bug in vfprintf: bad base";
6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					size = strlen(cp);
6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					goto skipsize;
6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			size = buf + BUF - cp;
7021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		skipsize:
7031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:	/* "%?" prints ?, unless ? is NUL */
7051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch == '\0')
7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto done;
7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* pretend it was %c with argument ch */
7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp = buf;
7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*cp = ch;
7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			size = 1;
7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			sign = '\0';
7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
7161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * All reasonable formats wind up here.  At this point, `cp'
7171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * points to a string which (if not flags&LADJUST) should be
7181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * padded out to `width' places.  If flags&ZEROPAD, it should
7191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * first be prefixed by any sign or other prefix; otherwise,
7201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * it should be blank padded before the prefix is emitted.
7211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * After any left-hand padding and prefixing, emit zeroes
7221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * required by a decimal [diouxX] precision, then print the
7231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * string proper, then emit zeroes required by any leftover
7241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * floating precision; finally, if LADJUST, pad with blanks.
7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 *
7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Compute actual size, so we know how much to pad.
7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * size excludes decimal prec; realsz includes it.
7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		realsz = dprec > size ? dprec : size;
7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (sign)
7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			realsz++;
7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else if (flags & HEXPREFIX)
7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			realsz+= 2;
7341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* right-adjusting blank padding */
7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((flags & (LADJUST|ZEROPAD)) == 0)
7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PAD(width - realsz, blanks);
7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* prefix */
7401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (sign) {
7411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PRINT(&sign, 1);
7421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} else if (flags & HEXPREFIX) {
7431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ox[0] = '0';
7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ox[1] = ch;
7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PRINT(ox, 2);
7461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
7471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* right-adjusting zero padding */
7491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PAD(width - realsz, zeroes);
7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* leading zeroes from decimal precision */
7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		PAD(dprec - size, zeroes);
7541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* the string or number proper */
7561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
7571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((flags & FPT) == 0) {
7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PRINT(cp, size);
7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} else {	/* glue together f_p fragments */
7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch >= 'f') {	/* 'f' or 'g' */
7611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (_double == 0) {
7621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* kludge for __dtoa irregularity */
7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT("0", 1);
7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (expt < ndig || (flags & ALT) != 0) {
7651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						PRINT(decimal_point, 1);
7661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						PAD(ndig - 1, zeroes);
7671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					}
7681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				} else if (expt <= 0) {
7691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT("0", 1);
7701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(decimal_point, 1);
7711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PAD(-expt, zeroes);
7721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(cp, ndig);
7731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				} else if (expt >= ndig) {
7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(cp, ndig);
7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PAD(expt - ndig, zeroes);
7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (flags & ALT)
7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						PRINT(".", 1);
7781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				} else {
7791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(cp, expt);
7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					cp += expt;
7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(".", 1);
7821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(cp, ndig-expt);
7831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
7841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {	/* 'e' or 'E' */
7851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (ndig > 1 || flags & ALT) {
7861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					ox[0] = *cp++;
7871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					ox[1] = '.';
7881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(ox, 2);
7891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					if (_double) {
7901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						PRINT(cp, ndig-1);
7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					} else	/* 0.[0..] */
7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						/* __dtoa irregularity */
7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						PAD(ndig - 1, zeroes);
7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				} else	/* XeYYY */
7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					PRINT(cp, 1);
7961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				PRINT(expstr, expsize);
7971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
7981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
7991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
8001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		PRINT(cp, size);
8011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
8021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* left-adjusting padding (always blank) */
8031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (flags & LADJUST)
8041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			PAD(width - realsz, blanks);
8051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* finally, adjust ret */
8071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ret += width > realsz ? width : realsz;
8081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		FLUSH();	/* copy out the I/O vectors */
8101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1   /* BIONIC: remove memory leak when printing doubles */
8111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (cp_free) {
8121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		  free(cp_free);
8131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		  cp_free = NULL;
8141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
8151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
8161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
8171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdone:
8181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	FLUSH();
8191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecterror:
8201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1   /* BIONIC: remove memory leak when printing doubles */
8211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    if (cp_free) {
8221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        free(cp_free);
8231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        cp_free = NULL;
8241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
8251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
8261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (argtable != NULL && argtable != statargtable) {
8271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		munmap(argtable, argtablesiz);
8281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		argtable = NULL;
8291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
830c7dcd67d56701a10c14019b17c9499249ab6c252Yaroslav Miroshnychenko        va_end(orgap);
8311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (__sferror(fp) ? EOF : ret);
8321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* NOTREACHED */
8331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
8341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
8361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Type ids for argument type table.
8371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
8381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_UNUSED	0
8391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_SHORT		1
8401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_SHORT	2
8411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_SHORT	3
8421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_INT		4
8431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_INT		5
8441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_INT		6
8451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_LONG		7
8461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_LONG	8
8471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_LONG		9
8481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_LLONG		10
8491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_U_LLONG	11
8501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_LLONG	12
8511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_DOUBLE	13
8521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_LONG_DOUBLE	14
8531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_CHAR		15
8541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_VOID		16
8551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_PTRINT	17
8561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_PTRINT	18
8571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_SIZEINT	19
8581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_SSIZEINT	20
8591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_SSIZEINT	21
8601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_MAXINT	22
8611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_MAXUINT	23
8621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define TP_MAXINT	24
8631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
8651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Find all arguments when a positional parameter is encountered.  Returns a
8661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * table, indexed by argument number, of pointers to each arguments.  The
8671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
8681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * It will be replaced with a mmap-ed one if it overflows (malloc cannot be
8691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * used since we are attempting to make snprintf thread safe, and alloca is
8701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * problematic since we have nested functions..)
8711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
8721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
8731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__find_arguments(const char *fmt0, va_list ap, va_list **argtable,
8741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    size_t *argtablesiz)
8751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
8761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *fmt;	/* format string */
8771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ch;	/* character from fmt */
8781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n, n2;	/* handy integer (short term usage) */
8791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *cp;	/* handy char pointer (short term usage) */
8801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int flags;	/* flags as above */
8811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	unsigned char *typetable; /* table of types */
8821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	unsigned char stattypetable[STATIC_ARG_TBL_SIZE];
8831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int tablesize;		/* current size of type table */
8841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int tablemax;		/* largest used index in table */
8851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int nextarg;		/* 1-based argument index */
8861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	wchar_t wc;
8871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	void* ps;
8881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
8901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Add an argument type to the table, expanding if necessary.
8911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
8921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ADDTYPE(type) \
8931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	((nextarg >= tablesize) ? \
8941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		__grow_type_table(&typetable, &tablesize) : 0, \
8951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(nextarg > tablemax) ? tablemax = nextarg : 0, \
8961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	typetable[nextarg++] = type)
8971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	ADDSARG() \
8991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        ((flags&MAXINT) ? ADDTYPE(T_MAXINT) : \
9001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
9011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&SIZEINT) ? ADDTYPE(T_SSIZEINT) : \
9021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
9031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&LONGINT) ? ADDTYPE(T_LONG) : \
9041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&SHORTINT) ? ADDTYPE(T_SHORT) : ADDTYPE(T_INT)))))))
9051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	ADDUARG() \
9071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        ((flags&MAXINT) ? ADDTYPE(T_MAXUINT) : \
9081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&PTRINT) ? ADDTYPE(T_PTRINT) : \
9091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&SIZEINT) ? ADDTYPE(T_SIZEINT) : \
9101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
9111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&LONGINT) ? ADDTYPE(T_U_LONG) : \
9121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ((flags&SHORTINT) ? ADDTYPE(T_U_SHORT) : ADDTYPE(T_U_INT)))))))
9131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
9151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Add * arguments to the type array.
9161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
9171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ADDASTER() \
9181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n2 = 0; \
9191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp = fmt; \
9201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (is_digit(*cp)) { \
9211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n2 = 10 * n2 + to_digit(*cp); \
9221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp++; \
9231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} \
9241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*cp == '$') { \
9251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		int hold = nextarg; \
9261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		nextarg = n2; \
9271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ADDTYPE(T_INT); \
9281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		nextarg = hold; \
9291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		fmt = ++cp; \
9301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else { \
9311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ADDTYPE(T_INT); \
9321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
9331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	fmt = (char *)fmt0;
9341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	typetable = stattypetable;
9351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tablesize = STATIC_ARG_TBL_SIZE;
9361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tablemax = 0;
9371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	nextarg = 1;
9381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	memset(typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
9391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	memset(&ps, 0, sizeof(ps));
9401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
9421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Scan the format for conversions (`%' character).
9431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
9441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (;;) {
9451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp = fmt;
9461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 1  /* BIONIC */
9471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                n = -1;
9481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                while ((wc = *fmt) != 0) {
9491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    if (wc == '%') {
9501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        n = 1;
9511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        break;
9521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    }
9531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    fmt++;
9541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
9551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
9561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while ((n = mbrtowc(&wc, fmt, MB_CUR_MAX, &ps)) > 0) {
9571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			fmt += n;
9581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (wc == '%') {
9591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fmt--;
9601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
9611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
9621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
9631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
9641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (n <= 0)
9651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto done;
9661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		fmt++;		/* skip over '%' */
9671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		flags = 0;
9691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectrflag:		ch = *fmt++;
9711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectreswitch:	switch (ch) {
9721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case ' ':
9731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '#':
9741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
9751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '*':
9761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ADDASTER();
9771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
9781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '-':
9791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '+':
9801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
9811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '.':
9821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((ch = *fmt++) == '*') {
9831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDASTER();
9841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto rflag;
9851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
9861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while (is_digit(ch)) {
9871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ch = *fmt++;
9881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
9891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto reswitch;
9901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '0':
9911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
9921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '1': case '2': case '3': case '4':
9931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case '5': case '6': case '7': case '8': case '9':
9941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = 0;
9951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			do {
9961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = 10 * n + to_digit(ch);
9971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ch = *fmt++;
9981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} while (is_digit(ch));
9991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch == '$') {
10001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nextarg = n;
10011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto rflag;
10021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
10031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto reswitch;
10041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
10051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'L':
10061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGDBL;
10071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
10081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'h':
10101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*fmt == 'h') {
10111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fmt++;
10121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= CHARINT;
10131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
10141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= SHORTINT;
10151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
10161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
10171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'l':
10181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*fmt == 'l') {
10191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fmt++;
10201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= LLONGINT;
10211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else {
10221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				flags |= LONGINT;
10231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
10241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
10251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'q':
10261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LLONGINT;
10271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
10281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 't':
10291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= PTRINT;
10301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
10311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'z':
10321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= SIZEINT;
10331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto rflag;
10341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'c':
10351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ADDTYPE(T_INT);
10361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'D':
10381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGINT;
10391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*FALLTHROUGH*/
10401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'd':
10411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'i':
10421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ADDSARG();
10431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
10451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'e':
10461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'E':
10471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'f':
10481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'g':
10491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'G':
10501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & LONGDBL)
10511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(T_LONG_DOUBLE);
10521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
10531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(T_DOUBLE);
10541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */
10561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'n':
10571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & LLONGINT)
10581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(TP_LLONG);
10591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & LONGINT)
10601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(TP_LONG);
10611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & SHORTINT)
10621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(TP_SHORT);
10631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & PTRINT)
10641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(TP_PTRINT);
10651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & SIZEINT)
10661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(TP_SSIZEINT);
10671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (flags & MAXINT)
10681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(TP_MAXINT);
10691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
10701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ADDTYPE(TP_INT);
10711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;	/* no output */
10721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'O':
10731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGINT;
10741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*FALLTHROUGH*/
10751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'o':
10761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ADDUARG();
10771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'p':
10791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ADDTYPE(TP_VOID);
10801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 's':
10821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ADDTYPE(TP_CHAR);
10831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'U':
10851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			flags |= LONGINT;
10861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*FALLTHROUGH*/
10871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'u':
10881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'X':
10891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'x':
10901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ADDUARG();
10911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:	/* "%?" prints ?, unless ? is NUL */
10931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ch == '\0')
10941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto done;
10951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
10961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
10971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
10981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdone:
10991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
11001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Build the argument table.
11011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
11021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (tablemax >= STATIC_ARG_TBL_SIZE) {
11031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*argtablesiz = sizeof (va_list) * (tablemax + 1);
11041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*argtable = (va_list *)mmap(NULL, *argtablesiz,
11051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    PROT_WRITE|PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0);
11061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
11071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 0
11091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* XXX is this required? */
11101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(*argtable) [0] = NULL;
11111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
11121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (n = 1; n <= tablemax; n++) {
11131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		va_copy((*argtable)[n], ap);
11141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (typetable[n]) {
11151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_UNUSED:
11161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, int);
11171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_SHORT:
11191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, int);
11201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_U_SHORT:
11221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, int);
11231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_SHORT:
11251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, short *);
11261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_INT:
11281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, int);
11291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_U_INT:
11311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, unsigned int);
11321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_INT:
11341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, int *);
11351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_LONG:
11371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, long);
11381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_U_LONG:
11401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, unsigned long);
11411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_LONG:
11431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, long *);
11441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_LLONG:
11461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, long long);
11471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_U_LLONG:
11491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, unsigned long long);
11501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_LLONG:
11521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, long long *);
11531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_DOUBLE:
11551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, double);
11561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_LONG_DOUBLE:
11581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, long double);
11591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_CHAR:
11611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, char *);
11621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_VOID:
11641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, void *);
11651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_PTRINT:
11671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, ptrdiff_t);
11681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_PTRINT:
11701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, ptrdiff_t *);
11711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_SIZEINT:
11731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, size_t);
11741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_SSIZEINT:
11761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, ssize_t);
11771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_SSIZEINT:
11791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, ssize_t *);
11801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TP_MAXINT:
11821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void) va_arg(ap, intmax_t *);
11831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
11851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
11861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (typetable != NULL && typetable != stattypetable) {
11881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		munmap(typetable, *argtablesiz);
11891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		typetable = NULL;
11901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
11911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
11921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
11941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Increase the size of the type table.
11951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
11961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
11971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__grow_type_table(unsigned char **typetable, int *tablesize)
11981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
11991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	unsigned char *oldtable = *typetable;
12001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int newsize = *tablesize * 2;
12011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*tablesize == STATIC_ARG_TBL_SIZE) {
12031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*typetable = (unsigned char *)mmap(NULL,
12041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    sizeof (unsigned char) * newsize, PROT_WRITE|PROT_READ,
12051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    MAP_ANON|MAP_PRIVATE, -1, 0);
12061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* XXX unchecked */
12071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		memcpy( *typetable, oldtable, *tablesize);
12081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else {
12091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		unsigned char *new = (unsigned char *)mmap(NULL,
12101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    sizeof (unsigned char) * newsize, PROT_WRITE|PROT_READ,
12111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    MAP_ANON|MAP_PRIVATE, -1, 0);
12121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		memmove(new, *typetable, *tablesize);
12131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		munmap(*typetable, *tablesize);
12141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*typetable = new;
12151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* XXX unchecked */
12161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	memset(*typetable + *tablesize, T_UNUSED, (newsize - *tablesize));
12181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*tablesize = newsize;
12201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return(0);
12211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
12221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef FLOATING_POINT
12251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char *__dtoa(double, int, int, int *, int *, char **);
12271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *
12291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectcvt(double value, int ndigits, int flags, char *sign, int *decpt, int ch,
12301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    int *length)
12311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
12321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int mode, dsgn;
12331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *digits, *bp, *rve;
12341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ch == 'f') {
12361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mode = 3;		/* ndigits after the decimal point */
12371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else {
12381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* To obtain ndigits after the decimal point for the 'e'
12391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * and 'E' formats, round to ndigits + 1 significant
12401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * figures.
12411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
12421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ch == 'e' || ch == 'E') {
12431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ndigits++;
12441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
12451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		mode = 2;		/* ndigits significant digits */
12461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (value < 0) {
12491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		value = -value;
12501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*sign = '-';
12511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else
12521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*sign = '\000';
12531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
12541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((ch != 'g' && ch != 'G') || flags & ALT) {	/* Print trailing zeros */
12551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bp = digits + ndigits;
12561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ch == 'f') {
12571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*digits == '0' && value)
12581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*decpt = -ndigits + 1;
12591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bp += *decpt;
12601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
12611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (value == 0)	/* kludge for __dtoa irregularity */
12621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			rve = bp;
12631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while (rve < bp)
12641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*rve++ = '0';
12651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*length = rve - digits;
12671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (digits);
12681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
12691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
12711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectexponent(char *p0, int exp, int fmtch)
12721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
12731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *p, *t;
12741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char expbuf[MAXEXP];
12751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	p = p0;
12771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*p++ = fmtch;
12781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (exp < 0) {
12791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		exp = -exp;
12801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*p++ = '-';
12811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else
12831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*p++ = '+';
12841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	t = expbuf + MAXEXP;
12851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (exp > 9) {
12861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		do {
12871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*--t = to_char(exp % 10);
12881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} while ((exp /= 10) > 9);
12891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*--t = to_char(exp);
12901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (; t < expbuf + MAXEXP; *p++ = *t++);
12911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
12931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*p++ = '0';
12941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*p++ = to_char(exp);
12951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (p - p0);
12971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
12981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC */
13011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <machine/ieee.h>
13021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union {
13031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    double              d;
13041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    struct ieee_double  i;
13051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} ieee_u;
13061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
13081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_my_isinf (double  value)
13091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
13101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    ieee_u   u;
13111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    u.d = value;
13131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    return (u.i.dbl_exp == 2047 && u.i.dbl_frach == 0 && u.i.dbl_fracl == 0);
13141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
13151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
13171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_my_isnan (double  value)
13181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
13191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    ieee_u   u;
13201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    u.d = value;
13221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    return (u.i.dbl_exp == 2047 && (u.i.dbl_frach != 0 || u.i.dbl_fracl != 0));
13231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
13241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* FLOATING_POINT */
1325