vfprintf.c revision 128819
1/*-
2 * Copyright (c) 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Chris Torek.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char sccsid[] = "@(#)vfprintf.c	8.1 (Berkeley) 6/4/93";
39#endif /* LIBC_SCCS and not lint */
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/lib/libc/stdio/vfprintf.c 128819 2004-05-02 10:55:06Z das $");
42
43/*
44 * Actual printf innards.
45 *
46 * This code is large and complicated...
47 */
48
49#include "namespace.h"
50#include <sys/types.h>
51
52#include <ctype.h>
53#include <limits.h>
54#include <locale.h>
55#include <stddef.h>
56#include <stdint.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60#include <wchar.h>
61
62#include <stdarg.h>
63#include "un-namespace.h"
64
65#include "libc_private.h"
66#include "local.h"
67#include "fvwrite.h"
68
69union arg {
70	int	intarg;
71	u_int	uintarg;
72	long	longarg;
73	u_long	ulongarg;
74	long long longlongarg;
75	unsigned long long ulonglongarg;
76	ptrdiff_t ptrdiffarg;
77	size_t	sizearg;
78	intmax_t intmaxarg;
79	uintmax_t uintmaxarg;
80	void	*pvoidarg;
81	char	*pchararg;
82	signed char *pschararg;
83	short	*pshortarg;
84	int	*pintarg;
85	long	*plongarg;
86	long long *plonglongarg;
87	ptrdiff_t *pptrdiffarg;
88	size_t	*psizearg;
89	intmax_t *pintmaxarg;
90#ifndef NO_FLOATING_POINT
91	double	doublearg;
92	long double longdoublearg;
93#endif
94	wint_t	wintarg;
95	wchar_t	*pwchararg;
96};
97
98/*
99 * Type ids for argument type table.
100 */
101enum typeid {
102	T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
103	T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
104	T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
105	T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
106	T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
107};
108
109static int	__sprint(FILE *, struct __suio *);
110static int	__sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
111static char	*__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
112		    const char *);
113static char	*__ultoa(u_long, char *, int, int, const char *, int, char,
114		    const char *);
115static char	*__wcsconv(wchar_t *, int);
116static void	__find_arguments(const char *, va_list, union arg **);
117static void	__grow_type_table(int, enum typeid **, int *);
118
119/*
120 * Flush out all the vectors defined by the given uio,
121 * then reset it so that it can be reused.
122 */
123static int
124__sprint(FILE *fp, struct __suio *uio)
125{
126	int err;
127
128	if (uio->uio_resid == 0) {
129		uio->uio_iovcnt = 0;
130		return (0);
131	}
132	err = __sfvwrite(fp, uio);
133	uio->uio_resid = 0;
134	uio->uio_iovcnt = 0;
135	return (err);
136}
137
138/*
139 * Helper function for `fprintf to unbuffered unix file': creates a
140 * temporary buffer.  We only work on write-only files; this avoids
141 * worries about ungetc buffers and so forth.
142 */
143static int
144__sbprintf(FILE *fp, const char *fmt, va_list ap)
145{
146	int ret;
147	FILE fake;
148	unsigned char buf[BUFSIZ];
149
150	/* copy the important variables */
151	fake._flags = fp->_flags & ~__SNBF;
152	fake._file = fp->_file;
153	fake._cookie = fp->_cookie;
154	fake._write = fp->_write;
155	fake._extra = fp->_extra;
156
157	/* set up the buffer */
158	fake._bf._base = fake._p = buf;
159	fake._bf._size = fake._w = sizeof(buf);
160	fake._lbfsize = 0;	/* not actually used, but Just In Case */
161
162	/* do the work, then copy any error status */
163	ret = __vfprintf(&fake, fmt, ap);
164	if (ret >= 0 && __fflush(&fake))
165		ret = EOF;
166	if (fake._flags & __SERR)
167		fp->_flags |= __SERR;
168	return (ret);
169}
170
171/*
172 * Macros for converting digits to letters and vice versa
173 */
174#define	to_digit(c)	((c) - '0')
175#define is_digit(c)	((unsigned)to_digit(c) <= 9)
176#define	to_char(n)	((n) + '0')
177
178/*
179 * Convert an unsigned long to ASCII for printf purposes, returning
180 * a pointer to the first character of the string representation.
181 * Octal numbers can be forced to have a leading zero; hex numbers
182 * use the given digits.
183 */
184static char *
185__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs,
186	int needgrp, char thousep, const char *grp)
187{
188	char *cp = endp;
189	long sval;
190	int ndig;
191
192	/*
193	 * Handle the three cases separately, in the hope of getting
194	 * better/faster code.
195	 */
196	switch (base) {
197	case 10:
198		if (val < 10) {	/* many numbers are 1 digit */
199			*--cp = to_char(val);
200			return (cp);
201		}
202		ndig = 0;
203		/*
204		 * On many machines, unsigned arithmetic is harder than
205		 * signed arithmetic, so we do at most one unsigned mod and
206		 * divide; this is sufficient to reduce the range of
207		 * the incoming value to where signed arithmetic works.
208		 */
209		if (val > LONG_MAX) {
210			*--cp = to_char(val % 10);
211			ndig++;
212			sval = val / 10;
213		} else
214			sval = val;
215		do {
216			*--cp = to_char(sval % 10);
217			ndig++;
218			/*
219			 * If (*grp == CHAR_MAX) then no more grouping
220			 * should be performed.
221			 */
222			if (needgrp && ndig == *grp && *grp != CHAR_MAX
223					&& sval > 9) {
224				*--cp = thousep;
225				ndig = 0;
226				/*
227				 * If (*(grp+1) == '\0') then we have to
228				 * use *grp character (last grouping rule)
229				 * for all next cases
230				 */
231				if (*(grp+1) != '\0')
232					grp++;
233			}
234			sval /= 10;
235		} while (sval != 0);
236		break;
237
238	case 8:
239		do {
240			*--cp = to_char(val & 7);
241			val >>= 3;
242		} while (val);
243		if (octzero && *cp != '0')
244			*--cp = '0';
245		break;
246
247	case 16:
248		do {
249			*--cp = xdigs[val & 15];
250			val >>= 4;
251		} while (val);
252		break;
253
254	default:			/* oops */
255		abort();
256	}
257	return (cp);
258}
259
260/* Identical to __ultoa, but for intmax_t. */
261static char *
262__ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs,
263	int needgrp, char thousep, const char *grp)
264{
265	char *cp = endp;
266	intmax_t sval;
267	int ndig;
268
269	/* quick test for small values; __ultoa is typically much faster */
270	/* (perhaps instead we should run until small, then call __ultoa?) */
271	if (val <= ULONG_MAX)
272		return (__ultoa((u_long)val, endp, base, octzero, xdigs,
273		    needgrp, thousep, grp));
274	switch (base) {
275	case 10:
276		if (val < 10) {
277			*--cp = to_char(val % 10);
278			return (cp);
279		}
280		ndig = 0;
281		if (val > INTMAX_MAX) {
282			*--cp = to_char(val % 10);
283			ndig++;
284			sval = val / 10;
285		} else
286			sval = val;
287		do {
288			*--cp = to_char(sval % 10);
289			ndig++;
290			/*
291			 * If (*grp == CHAR_MAX) then no more grouping
292			 * should be performed.
293			 */
294			if (needgrp && *grp != CHAR_MAX && ndig == *grp
295					&& sval > 9) {
296				*--cp = thousep;
297				ndig = 0;
298				/*
299				 * If (*(grp+1) == '\0') then we have to
300				 * use *grp character (last grouping rule)
301				 * for all next cases
302				 */
303				if (*(grp+1) != '\0')
304					grp++;
305			}
306			sval /= 10;
307		} while (sval != 0);
308		break;
309
310	case 8:
311		do {
312			*--cp = to_char(val & 7);
313			val >>= 3;
314		} while (val);
315		if (octzero && *cp != '0')
316			*--cp = '0';
317		break;
318
319	case 16:
320		do {
321			*--cp = xdigs[val & 15];
322			val >>= 4;
323		} while (val);
324		break;
325
326	default:
327		abort();
328	}
329	return (cp);
330}
331
332/*
333 * Convert a wide character string argument for the %ls format to a multibyte
334 * string representation. ``prec'' specifies the maximum number of bytes
335 * to output. If ``prec'' is greater than or equal to zero, we can't assume
336 * that the wide char. string ends in a null character.
337 */
338static char *
339__wcsconv(wchar_t *wcsarg, int prec)
340{
341	static const mbstate_t initial;
342	mbstate_t mbs;
343	char buf[MB_LEN_MAX];
344	wchar_t *p;
345	char *convbuf, *mbp;
346	size_t clen, nbytes;
347
348	/*
349	 * Determine the number of bytes to output and allocate space for
350	 * the output.
351	 */
352	if (prec >= 0) {
353		nbytes = 0;
354		p = wcsarg;
355		mbs = initial;
356		for (;;) {
357			clen = wcrtomb(buf, *p++, &mbs);
358			if (clen == 0 || clen == (size_t)-1 ||
359			    nbytes + clen > prec)
360				break;
361			nbytes += clen;
362		}
363	} else {
364		p = wcsarg;
365		mbs = initial;
366		nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
367		if (nbytes == (size_t)-1)
368			return (NULL);
369	}
370	if ((convbuf = malloc(nbytes + 1)) == NULL)
371		return (NULL);
372
373	/*
374	 * Fill the output buffer with the multibyte representations of as
375	 * many wide characters as will fit.
376	 */
377	mbp = convbuf;
378	p = wcsarg;
379	mbs = initial;
380	while (mbp - convbuf < nbytes) {
381		clen = wcrtomb(mbp, *p++, &mbs);
382		if (clen == 0 || clen == (size_t)-1)
383			break;
384		mbp += clen;
385	}
386	if (clen == (size_t)-1) {
387		free(convbuf);
388		return (NULL);
389	}
390	*mbp = '\0';
391
392	return (convbuf);
393}
394
395/*
396 * MT-safe version
397 */
398int
399vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
400
401{
402	int ret;
403
404	FLOCKFILE(fp);
405	ret = __vfprintf(fp, fmt0, ap);
406	FUNLOCKFILE(fp);
407	return (ret);
408}
409
410#ifndef NO_FLOATING_POINT
411
412#define	dtoa		__dtoa
413#define	freedtoa	__freedtoa
414
415#include <float.h>
416#include <math.h>
417#include "floatio.h"
418#include "gdtoa.h"
419
420#define	DEFPREC		6
421
422static int exponent(char *, int, int);
423
424#endif /* !NO_FLOATING_POINT */
425
426/*
427 * The size of the buffer we use as scratch space for integer
428 * conversions, among other things.  Technically, we would need the
429 * most space for base 10 conversions with thousands' grouping
430 * characters between each pair of digits.  100 bytes is a
431 * conservative overestimate even for a 128-bit uintmax_t.
432 */
433#define	BUF	100
434
435#define STATIC_ARG_TBL_SIZE 8           /* Size of static argument table. */
436
437/*
438 * Flags used during conversion.
439 */
440#define	ALT		0x001		/* alternate form */
441#define	LADJUST		0x004		/* left adjustment */
442#define	LONGDBL		0x008		/* long double */
443#define	LONGINT		0x010		/* long integer */
444#define	LLONGINT	0x020		/* long long integer */
445#define	SHORTINT	0x040		/* short integer */
446#define	ZEROPAD		0x080		/* zero (as opposed to blank) pad */
447#define	FPT		0x100		/* Floating point number */
448#define	GROUPING	0x200		/* use grouping ("'" flag) */
449					/* C99 additional size modifiers: */
450#define	SIZET		0x400		/* size_t */
451#define	PTRDIFFT	0x800		/* ptrdiff_t */
452#define	INTMAXT		0x1000		/* intmax_t */
453#define	CHARINT		0x2000		/* print char using int format */
454
455/*
456 * Non-MT-safe version
457 */
458int
459__vfprintf(FILE *fp, const char *fmt0, va_list ap)
460{
461	char *fmt;		/* format string */
462	int ch;			/* character from fmt */
463	int n, n2;		/* handy integer (short term usage) */
464	char *cp;		/* handy char pointer (short term usage) */
465	struct __siov *iovp;	/* for PRINT macro */
466	int flags;		/* flags as above */
467	int ret;		/* return value accumulator */
468	int width;		/* width from format (%8d), or 0 */
469	int prec;		/* precision from format; <0 for N/A */
470	char sign;		/* sign prefix (' ', '+', '-', or \0) */
471	char thousands_sep;	/* locale specific thousands separator */
472	const char *grouping;	/* locale specific numeric grouping rules */
473#ifndef NO_FLOATING_POINT
474	/*
475	 * We can decompose the printed representation of floating
476	 * point numbers into several parts, some of which may be empty:
477	 *
478	 * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
479	 *    A       B     ---C---      D       E   F
480	 *
481	 * A:	'sign' holds this value if present; '\0' otherwise
482	 * B:	ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
483	 * C:	cp points to the string MMMNNN.  Leading and trailing
484	 *	zeros are not in the string and must be added.
485	 * D:	expchar holds this character; '\0' if no exponent, e.g. %f
486	 * F:	at least two digits for decimal, at least one digit for hex
487	 */
488	char *decimal_point;	/* locale specific decimal point */
489	int signflag;		/* true if float is negative */
490	union {			/* floating point arguments %[aAeEfFgG] */
491		double dbl;
492		long double ldbl;
493	} fparg;
494	int expt;		/* integer value of exponent */
495	char expchar;		/* exponent character: [eEpP\0] */
496	char *dtoaend;		/* pointer to end of converted digits */
497	int expsize;		/* character count for expstr */
498	int lead;		/* sig figs before decimal or group sep */
499	int ndig;		/* actual number of digits returned by dtoa */
500	char expstr[MAXEXPDIG+2];	/* buffer for exponent string: e+ZZZ */
501	char *dtoaresult;	/* buffer allocated by dtoa */
502	int nseps;		/* number of group separators with ' */
503	int nrepeats;		/* number of repeats of the last group */
504#endif
505	u_long	ulval;		/* integer arguments %[diouxX] */
506	uintmax_t ujval;	/* %j, %ll, %q, %t, %z integers */
507	int base;		/* base for [diouxX] conversion */
508	int dprec;		/* a copy of prec if [diouxX], 0 otherwise */
509	int realsz;		/* field size expanded by dprec, sign, etc */
510	int size;		/* size of converted field or string */
511	int prsize;             /* max size of printed field */
512	const char *xdigs;     	/* digits for %[xX] conversion */
513#define NIOV 8
514	struct __suio uio;	/* output information: summary */
515	struct __siov iov[NIOV];/* ... and individual io vectors */
516	char buf[BUF];		/* buffer with space for digits of uintmax_t */
517	char ox[2];		/* space for 0x; ox[1] is either x, X, or \0 */
518	union arg *argtable;    /* args, built due to positional arg */
519	union arg statargtable [STATIC_ARG_TBL_SIZE];
520	int nextarg;            /* 1-based argument index */
521	va_list orgap;          /* original argument pointer */
522	char *convbuf;		/* wide to multibyte conversion result */
523
524	/*
525	 * Choose PADSIZE to trade efficiency vs. size.  If larger printf
526	 * fields occur frequently, increase PADSIZE and make the initialisers
527	 * below longer.
528	 */
529#define	PADSIZE	16		/* pad chunk size */
530	static char blanks[PADSIZE] =
531	 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
532	static char zeroes[PADSIZE] =
533	 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
534
535	static const char xdigs_lower[16] = "0123456789abcdef";
536	static const char xdigs_upper[16] = "0123456789ABCDEF";
537
538	/*
539	 * BEWARE, these `goto error' on error, and PAD uses `n'.
540	 */
541#define	PRINT(ptr, len) { \
542	iovp->iov_base = (ptr); \
543	iovp->iov_len = (len); \
544	uio.uio_resid += (len); \
545	iovp++; \
546	if (++uio.uio_iovcnt >= NIOV) { \
547		if (__sprint(fp, &uio)) \
548			goto error; \
549		iovp = iov; \
550	} \
551}
552#define	PAD(howmany, with) { \
553	if ((n = (howmany)) > 0) { \
554		while (n > PADSIZE) { \
555			PRINT(with, PADSIZE); \
556			n -= PADSIZE; \
557		} \
558		PRINT(with, n); \
559	} \
560}
561#define	PRINTANDPAD(p, ep, len, with) do {	\
562	n2 = (ep) - (p);       			\
563	if (n2 > (len))				\
564		n2 = (len);			\
565	if (n2 > 0)				\
566		PRINT((p), n2);			\
567	PAD((len) - (n2 > 0 ? n2 : 0), (with));	\
568} while(0)
569#define	FLUSH() { \
570	if (uio.uio_resid && __sprint(fp, &uio)) \
571		goto error; \
572	uio.uio_iovcnt = 0; \
573	iovp = iov; \
574}
575
576	/*
577	 * Get the argument indexed by nextarg.   If the argument table is
578	 * built, use it to get the argument.  If its not, get the next
579	 * argument (and arguments must be gotten sequentially).
580	 */
581#define GETARG(type) \
582	((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \
583	    (nextarg++, va_arg(ap, type)))
584
585	/*
586	 * To extend shorts properly, we need both signed and unsigned
587	 * argument extraction methods.
588	 */
589#define	SARG() \
590	(flags&LONGINT ? GETARG(long) : \
591	    flags&SHORTINT ? (long)(short)GETARG(int) : \
592	    flags&CHARINT ? (long)(signed char)GETARG(int) : \
593	    (long)GETARG(int))
594#define	UARG() \
595	(flags&LONGINT ? GETARG(u_long) : \
596	    flags&SHORTINT ? (u_long)(u_short)GETARG(int) : \
597	    flags&CHARINT ? (u_long)(u_char)GETARG(int) : \
598	    (u_long)GETARG(u_int))
599#define	INTMAX_SIZE	(INTMAXT|SIZET|PTRDIFFT|LLONGINT)
600#define SJARG() \
601	(flags&INTMAXT ? GETARG(intmax_t) : \
602	    flags&SIZET ? (intmax_t)GETARG(size_t) : \
603	    flags&PTRDIFFT ? (intmax_t)GETARG(ptrdiff_t) : \
604	    (intmax_t)GETARG(long long))
605#define	UJARG() \
606	(flags&INTMAXT ? GETARG(uintmax_t) : \
607	    flags&SIZET ? (uintmax_t)GETARG(size_t) : \
608	    flags&PTRDIFFT ? (uintmax_t)GETARG(ptrdiff_t) : \
609	    (uintmax_t)GETARG(unsigned long long))
610
611	/*
612	 * Get * arguments, including the form *nn$.  Preserve the nextarg
613	 * that the argument can be gotten once the type is determined.
614	 */
615#define GETASTER(val) \
616	n2 = 0; \
617	cp = fmt; \
618	while (is_digit(*cp)) { \
619		n2 = 10 * n2 + to_digit(*cp); \
620		cp++; \
621	} \
622	if (*cp == '$') { \
623		int hold = nextarg; \
624		if (argtable == NULL) { \
625			argtable = statargtable; \
626			__find_arguments (fmt0, orgap, &argtable); \
627		} \
628		nextarg = n2; \
629		val = GETARG (int); \
630		nextarg = hold; \
631		fmt = ++cp; \
632	} else { \
633		val = GETARG (int); \
634	}
635
636
637	thousands_sep = '\0';
638	grouping = NULL;
639	convbuf = NULL;
640#ifndef NO_FLOATING_POINT
641	dtoaresult = NULL;
642	decimal_point = localeconv()->decimal_point;
643#endif
644	/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
645	if (cantwrite(fp))
646		return (EOF);
647
648	/* optimise fprintf(stderr) (and other unbuffered Unix files) */
649	if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
650	    fp->_file >= 0)
651		return (__sbprintf(fp, fmt0, ap));
652
653	fmt = (char *)fmt0;
654	argtable = NULL;
655	nextarg = 1;
656	va_copy(orgap, ap);
657	uio.uio_iov = iovp = iov;
658	uio.uio_resid = 0;
659	uio.uio_iovcnt = 0;
660	ret = 0;
661
662	/*
663	 * Scan the format for conversions (`%' character).
664	 */
665	for (;;) {
666		for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
667			/* void */;
668		if ((n = fmt - cp) != 0) {
669			if ((unsigned)ret + n > INT_MAX) {
670				ret = EOF;
671				goto error;
672			}
673			PRINT(cp, n);
674			ret += n;
675		}
676		if (ch == '\0')
677			goto done;
678		fmt++;		/* skip over '%' */
679
680		flags = 0;
681		dprec = 0;
682		width = 0;
683		prec = -1;
684		sign = '\0';
685		ox[1] = '\0';
686
687rflag:		ch = *fmt++;
688reswitch:	switch (ch) {
689		case ' ':
690			/*-
691			 * ``If the space and + flags both appear, the space
692			 * flag will be ignored.''
693			 *	-- ANSI X3J11
694			 */
695			if (!sign)
696				sign = ' ';
697			goto rflag;
698		case '#':
699			flags |= ALT;
700			goto rflag;
701		case '*':
702			/*-
703			 * ``A negative field width argument is taken as a
704			 * - flag followed by a positive field width.''
705			 *	-- ANSI X3J11
706			 * They don't exclude field widths read from args.
707			 */
708			GETASTER (width);
709			if (width >= 0)
710				goto rflag;
711			width = -width;
712			/* FALLTHROUGH */
713		case '-':
714			flags |= LADJUST;
715			goto rflag;
716		case '+':
717			sign = '+';
718			goto rflag;
719		case '\'':
720			flags |= GROUPING;
721			thousands_sep = *(localeconv()->thousands_sep);
722			grouping = localeconv()->grouping;
723			goto rflag;
724		case '.':
725			if ((ch = *fmt++) == '*') {
726				GETASTER (prec);
727				goto rflag;
728			}
729			prec = 0;
730			while (is_digit(ch)) {
731				prec = 10 * prec + to_digit(ch);
732				ch = *fmt++;
733			}
734			goto reswitch;
735		case '0':
736			/*-
737			 * ``Note that 0 is taken as a flag, not as the
738			 * beginning of a field width.''
739			 *	-- ANSI X3J11
740			 */
741			flags |= ZEROPAD;
742			goto rflag;
743		case '1': case '2': case '3': case '4':
744		case '5': case '6': case '7': case '8': case '9':
745			n = 0;
746			do {
747				n = 10 * n + to_digit(ch);
748				ch = *fmt++;
749			} while (is_digit(ch));
750			if (ch == '$') {
751				nextarg = n;
752				if (argtable == NULL) {
753					argtable = statargtable;
754					__find_arguments (fmt0, orgap,
755					    &argtable);
756				}
757				goto rflag;
758			}
759			width = n;
760			goto reswitch;
761#ifndef NO_FLOATING_POINT
762		case 'L':
763			flags |= LONGDBL;
764			goto rflag;
765#endif
766		case 'h':
767			if (flags & SHORTINT) {
768				flags &= ~SHORTINT;
769				flags |= CHARINT;
770			} else
771				flags |= SHORTINT;
772			goto rflag;
773		case 'j':
774			flags |= INTMAXT;
775			goto rflag;
776		case 'l':
777			if (flags & LONGINT) {
778				flags &= ~LONGINT;
779				flags |= LLONGINT;
780			} else
781				flags |= LONGINT;
782			goto rflag;
783		case 'q':
784			flags |= LLONGINT;	/* not necessarily */
785			goto rflag;
786		case 't':
787			flags |= PTRDIFFT;
788			goto rflag;
789		case 'z':
790			flags |= SIZET;
791			goto rflag;
792		case 'C':
793			flags |= LONGINT;
794			/*FALLTHROUGH*/
795		case 'c':
796			if (flags & LONGINT) {
797				static const mbstate_t initial;
798				mbstate_t mbs;
799				size_t mbseqlen;
800
801				mbs = initial;
802				mbseqlen = wcrtomb(cp = buf,
803				    (wchar_t)GETARG(wint_t), &mbs);
804				if (mbseqlen == (size_t)-1) {
805					fp->_flags |= __SERR;
806					goto error;
807				}
808				size = (int)mbseqlen;
809			} else {
810				*(cp = buf) = GETARG(int);
811				size = 1;
812			}
813			sign = '\0';
814			break;
815		case 'D':
816			flags |= LONGINT;
817			/*FALLTHROUGH*/
818		case 'd':
819		case 'i':
820			if (flags & INTMAX_SIZE) {
821				ujval = SJARG();
822				if ((intmax_t)ujval < 0) {
823					ujval = -ujval;
824					sign = '-';
825				}
826			} else {
827				ulval = SARG();
828				if ((long)ulval < 0) {
829					ulval = -ulval;
830					sign = '-';
831				}
832			}
833			base = 10;
834			goto number;
835#ifndef NO_FLOATING_POINT
836		case 'a':
837		case 'A':
838			if (ch == 'a') {
839				ox[1] = 'x';
840				xdigs = xdigs_lower;
841				expchar = 'p';
842			} else {
843				ox[1] = 'X';
844				xdigs = xdigs_upper;
845				expchar = 'P';
846			}
847			if (prec >= 0)
848				prec++;
849			if (dtoaresult != NULL)
850				freedtoa(dtoaresult);
851			if (flags & LONGDBL) {
852				fparg.ldbl = GETARG(long double);
853				dtoaresult = cp =
854				    __hldtoa(fparg.ldbl, xdigs, prec,
855				    &expt, &signflag, &dtoaend);
856			} else {
857				fparg.dbl = GETARG(double);
858				dtoaresult = cp =
859				    __hdtoa(fparg.dbl, xdigs, prec,
860				    &expt, &signflag, &dtoaend);
861			}
862			if (prec < 0)
863				prec = dtoaend - cp;
864			if (expt == INT_MAX)
865				ox[1] = '\0';
866			goto fp_common;
867		case 'e':
868		case 'E':
869			expchar = ch;
870			if (prec < 0)	/* account for digit before decpt */
871				prec = DEFPREC + 1;
872			else
873				prec++;
874			goto fp_begin;
875		case 'f':
876		case 'F':
877			expchar = '\0';
878			goto fp_begin;
879		case 'g':
880		case 'G':
881			expchar = ch - ('g' - 'e');
882			if (prec == 0)
883				prec = 1;
884fp_begin:
885			if (prec < 0)
886				prec = DEFPREC;
887			if (dtoaresult != NULL)
888				freedtoa(dtoaresult);
889			if (flags & LONGDBL) {
890				fparg.ldbl = GETARG(long double);
891				dtoaresult = cp =
892				    __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
893				    &expt, &signflag, &dtoaend);
894			} else {
895				fparg.dbl = GETARG(double);
896				dtoaresult = cp =
897				    dtoa(fparg.dbl, expchar ? 2 : 3, prec,
898				    &expt, &signflag, &dtoaend);
899				if (expt == 9999)
900					expt = INT_MAX;
901			}
902fp_common:
903			if (signflag)
904				sign = '-';
905			if (expt == INT_MAX) {	/* inf or nan */
906				if (*cp == 'N') {
907					cp = (ch >= 'a') ? "nan" : "NAN";
908					sign = '\0';
909				} else
910					cp = (ch >= 'a') ? "inf" : "INF";
911				size = 3;
912				break;
913			}
914			flags |= FPT;
915			ndig = dtoaend - cp;
916			if (ch == 'g' || ch == 'G') {
917				if (expt > -4 && expt <= prec) {
918					/* Make %[gG] smell like %[fF] */
919					expchar = '\0';
920					if (flags & ALT)
921						prec -= expt;
922					else
923						prec = ndig - expt;
924					if (prec < 0)
925						prec = 0;
926				} else {
927					/*
928					 * Make %[gG] smell like %[eE], but
929					 * trim trailing zeroes if no # flag.
930					 */
931					if (!(flags & ALT))
932						prec = ndig;
933				}
934			}
935			if (expchar) {
936				expsize = exponent(expstr, expt - 1, expchar);
937				size = expsize + prec;
938				if (prec > 1 || flags & ALT)
939					++size;
940			} else {
941				/* space for digits before decimal point */
942				if (expt > 0)
943					size = expt;
944				else	/* "0" */
945					size = 1;
946				/* space for decimal pt and following digits */
947				if (prec || flags & ALT)
948					size += prec + 1;
949				if (grouping && expt > 0) {
950					/* space for thousands' grouping */
951					nseps = nrepeats = 0;
952					lead = expt;
953					while (*grouping != CHAR_MAX) {
954						if (lead <= *grouping)
955							break;
956						lead -= *grouping;
957						if (*(grouping+1)) {
958							nseps++;
959							grouping++;
960						} else
961							nrepeats++;
962					}
963					size += nseps + nrepeats;
964				} else
965					lead = expt;
966			}
967			break;
968#endif /* !NO_FLOATING_POINT */
969		case 'n':
970			/*
971			 * Assignment-like behavior is specified if the
972			 * value overflows or is otherwise unrepresentable.
973			 * C99 says to use `signed char' for %hhn conversions.
974			 */
975			if (flags & LLONGINT)
976				*GETARG(long long *) = ret;
977			else if (flags & SIZET)
978				*GETARG(ssize_t *) = (ssize_t)ret;
979			else if (flags & PTRDIFFT)
980				*GETARG(ptrdiff_t *) = ret;
981			else if (flags & INTMAXT)
982				*GETARG(intmax_t *) = ret;
983			else if (flags & LONGINT)
984				*GETARG(long *) = ret;
985			else if (flags & SHORTINT)
986				*GETARG(short *) = ret;
987			else if (flags & CHARINT)
988				*GETARG(signed char *) = ret;
989			else
990				*GETARG(int *) = ret;
991			continue;	/* no output */
992		case 'O':
993			flags |= LONGINT;
994			/*FALLTHROUGH*/
995		case 'o':
996			if (flags & INTMAX_SIZE)
997				ujval = UJARG();
998			else
999				ulval = UARG();
1000			base = 8;
1001			goto nosign;
1002		case 'p':
1003			/*-
1004			 * ``The argument shall be a pointer to void.  The
1005			 * value of the pointer is converted to a sequence
1006			 * of printable characters, in an implementation-
1007			 * defined manner.''
1008			 *	-- ANSI X3J11
1009			 */
1010			ujval = (uintmax_t)(uintptr_t)GETARG(void *);
1011			base = 16;
1012			xdigs = xdigs_lower;
1013			flags = flags | INTMAXT;
1014			ox[1] = 'x';
1015			goto nosign;
1016		case 'S':
1017			flags |= LONGINT;
1018			/*FALLTHROUGH*/
1019		case 's':
1020			if (flags & LONGINT) {
1021				wchar_t *wcp;
1022
1023				if (convbuf != NULL)
1024					free(convbuf);
1025				if ((wcp = GETARG(wchar_t *)) == NULL)
1026					cp = "(null)";
1027				else {
1028					convbuf = __wcsconv(wcp, prec);
1029					if (convbuf == NULL) {
1030						fp->_flags |= __SERR;
1031						goto error;
1032					}
1033					cp = convbuf;
1034				}
1035			} else if ((cp = GETARG(char *)) == NULL)
1036				cp = "(null)";
1037			if (prec >= 0) {
1038				/*
1039				 * can't use strlen; can only look for the
1040				 * NUL in the first `prec' characters, and
1041				 * strlen() will go further.
1042				 */
1043				char *p = memchr(cp, 0, (size_t)prec);
1044
1045				if (p != NULL) {
1046					size = p - cp;
1047					if (size > prec)
1048						size = prec;
1049				} else
1050					size = prec;
1051			} else
1052				size = strlen(cp);
1053			sign = '\0';
1054			break;
1055		case 'U':
1056			flags |= LONGINT;
1057			/*FALLTHROUGH*/
1058		case 'u':
1059			if (flags & INTMAX_SIZE)
1060				ujval = UJARG();
1061			else
1062				ulval = UARG();
1063			base = 10;
1064			goto nosign;
1065		case 'X':
1066			xdigs = xdigs_upper;
1067			goto hex;
1068		case 'x':
1069			xdigs = xdigs_lower;
1070hex:
1071			if (flags & INTMAX_SIZE)
1072				ujval = UJARG();
1073			else
1074				ulval = UARG();
1075			base = 16;
1076			/* leading 0x/X only if non-zero */
1077			if (flags & ALT &&
1078			    (flags & INTMAX_SIZE ? ujval != 0 : ulval != 0))
1079				ox[1] = ch;
1080
1081			flags &= ~GROUPING;
1082			/* unsigned conversions */
1083nosign:			sign = '\0';
1084			/*-
1085			 * ``... diouXx conversions ... if a precision is
1086			 * specified, the 0 flag will be ignored.''
1087			 *	-- ANSI X3J11
1088			 */
1089number:			if ((dprec = prec) >= 0)
1090				flags &= ~ZEROPAD;
1091
1092			/*-
1093			 * ``The result of converting a zero value with an
1094			 * explicit precision of zero is no characters.''
1095			 *	-- ANSI X3J11
1096			 */
1097			cp = buf + BUF;
1098			if (flags & INTMAX_SIZE) {
1099				if (ujval != 0 || prec != 0)
1100					cp = __ujtoa(ujval, cp, base,
1101					    flags & ALT, xdigs,
1102					    flags & GROUPING, thousands_sep,
1103					    grouping);
1104			} else {
1105				if (ulval != 0 || prec != 0)
1106					cp = __ultoa(ulval, cp, base,
1107					    flags & ALT, xdigs,
1108					    flags & GROUPING, thousands_sep,
1109					    grouping);
1110			}
1111			size = buf + BUF - cp;
1112			if (size > BUF)	/* should never happen */
1113				abort();
1114			break;
1115		default:	/* "%?" prints ?, unless ? is NUL */
1116			if (ch == '\0')
1117				goto done;
1118			/* pretend it was %c with argument ch */
1119			cp = buf;
1120			*cp = ch;
1121			size = 1;
1122			sign = '\0';
1123			break;
1124		}
1125
1126		/*
1127		 * All reasonable formats wind up here.  At this point, `cp'
1128		 * points to a string which (if not flags&LADJUST) should be
1129		 * padded out to `width' places.  If flags&ZEROPAD, it should
1130		 * first be prefixed by any sign or other prefix; otherwise,
1131		 * it should be blank padded before the prefix is emitted.
1132		 * After any left-hand padding and prefixing, emit zeroes
1133		 * required by a decimal [diouxX] precision, then print the
1134		 * string proper, then emit zeroes required by any leftover
1135		 * floating precision; finally, if LADJUST, pad with blanks.
1136		 *
1137		 * Compute actual size, so we know how much to pad.
1138		 * size excludes decimal prec; realsz includes it.
1139		 */
1140		realsz = dprec > size ? dprec : size;
1141		if (sign)
1142			realsz++;
1143		if (ox[1])
1144			realsz += 2;
1145
1146		prsize = width > realsz ? width : realsz;
1147		if ((unsigned)ret + prsize > INT_MAX) {
1148			ret = EOF;
1149			goto error;
1150		}
1151
1152		/* right-adjusting blank padding */
1153		if ((flags & (LADJUST|ZEROPAD)) == 0)
1154			PAD(width - realsz, blanks);
1155
1156		/* prefix */
1157		if (sign)
1158			PRINT(&sign, 1);
1159
1160		if (ox[1]) {	/* ox[1] is either x, X, or \0 */
1161			ox[0] = '0';
1162			PRINT(ox, 2);
1163		}
1164
1165		/* right-adjusting zero padding */
1166		if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
1167			PAD(width - realsz, zeroes);
1168
1169		/* leading zeroes from decimal precision */
1170		PAD(dprec - size, zeroes);
1171
1172		/* the string or number proper */
1173#ifndef NO_FLOATING_POINT
1174		if ((flags & FPT) == 0) {
1175			PRINT(cp, size);
1176		} else {	/* glue together f_p fragments */
1177			if (!expchar) {	/* %[fF] or sufficiently short %[gG] */
1178				if (expt <= 0) {
1179					PRINT(zeroes, 1);
1180					if (prec || flags & ALT)
1181						PRINT(decimal_point, 1);
1182					PAD(-expt, zeroes);
1183					/* already handled initial 0's */
1184					prec += expt;
1185				} else {
1186					PRINTANDPAD(cp, dtoaend, lead, zeroes);
1187					cp += lead;
1188					if (grouping) {
1189						while (nseps>0 || nrepeats>0) {
1190							if (nrepeats > 0)
1191								nrepeats--;
1192							else {
1193								grouping--;
1194								nseps--;
1195							}
1196							PRINT(&thousands_sep,
1197							    1);
1198							PRINTANDPAD(cp,dtoaend,
1199							    *grouping, zeroes);
1200							cp += *grouping;
1201						}
1202						if (cp > dtoaend)
1203							cp = dtoaend;
1204					}
1205					if (prec || flags & ALT)
1206						PRINT(decimal_point,1);
1207				}
1208				PRINTANDPAD(cp, dtoaend, prec, zeroes);
1209			} else {	/* %[eE] or sufficiently long %[gG] */
1210				if (prec > 1 || flags & ALT) {
1211					buf[0] = *cp++;
1212					buf[1] = *decimal_point;
1213					PRINT(buf, 2);
1214					PRINT(cp, ndig-1);
1215					PAD(prec - ndig, zeroes);
1216				} else	/* XeYYY */
1217					PRINT(cp, 1);
1218				PRINT(expstr, expsize);
1219			}
1220		}
1221#else
1222		PRINT(cp, size);
1223#endif
1224		/* left-adjusting padding (always blank) */
1225		if (flags & LADJUST)
1226			PAD(width - realsz, blanks);
1227
1228		/* finally, adjust ret */
1229		ret += prsize;
1230
1231		FLUSH();	/* copy out the I/O vectors */
1232	}
1233done:
1234	FLUSH();
1235error:
1236#ifndef NO_FLOATING_POINT
1237	if (dtoaresult != NULL)
1238		freedtoa(dtoaresult);
1239#endif
1240	if (convbuf != NULL)
1241		free(convbuf);
1242	if (__sferror(fp))
1243		ret = EOF;
1244	if ((argtable != NULL) && (argtable != statargtable))
1245		free (argtable);
1246	return (ret);
1247	/* NOTREACHED */
1248}
1249
1250/*
1251 * Find all arguments when a positional parameter is encountered.  Returns a
1252 * table, indexed by argument number, of pointers to each arguments.  The
1253 * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
1254 * It will be replaces with a malloc-ed one if it overflows.
1255 */
1256static void
1257__find_arguments (const char *fmt0, va_list ap, union arg **argtable)
1258{
1259	char *fmt;		/* format string */
1260	int ch;			/* character from fmt */
1261	int n, n2;		/* handy integer (short term usage) */
1262	char *cp;		/* handy char pointer (short term usage) */
1263	int flags;		/* flags as above */
1264	int width;		/* width from format (%8d), or 0 */
1265	enum typeid *typetable; /* table of types */
1266	enum typeid stattypetable [STATIC_ARG_TBL_SIZE];
1267	int tablesize;		/* current size of type table */
1268	int tablemax;		/* largest used index in table */
1269	int nextarg;		/* 1-based argument index */
1270
1271	/*
1272	 * Add an argument type to the table, expanding if necessary.
1273	 */
1274#define ADDTYPE(type) \
1275	((nextarg >= tablesize) ? \
1276		__grow_type_table(nextarg, &typetable, &tablesize) : 0, \
1277	(nextarg > tablemax) ? tablemax = nextarg : 0, \
1278	typetable[nextarg++] = type)
1279
1280#define	ADDSARG() \
1281	((flags&INTMAXT) ? ADDTYPE(T_INTMAXT) : \
1282		((flags&SIZET) ? ADDTYPE(T_SIZET) : \
1283		((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
1284		((flags&LLONGINT) ? ADDTYPE(T_LLONG) : \
1285		((flags&LONGINT) ? ADDTYPE(T_LONG) : ADDTYPE(T_INT))))))
1286
1287#define	ADDUARG() \
1288	((flags&INTMAXT) ? ADDTYPE(T_UINTMAXT) : \
1289		((flags&SIZET) ? ADDTYPE(T_SIZET) : \
1290		((flags&PTRDIFFT) ? ADDTYPE(T_PTRDIFFT) : \
1291		((flags&LLONGINT) ? ADDTYPE(T_U_LLONG) : \
1292		((flags&LONGINT) ? ADDTYPE(T_U_LONG) : ADDTYPE(T_U_INT))))))
1293
1294	/*
1295	 * Add * arguments to the type array.
1296	 */
1297#define ADDASTER() \
1298	n2 = 0; \
1299	cp = fmt; \
1300	while (is_digit(*cp)) { \
1301		n2 = 10 * n2 + to_digit(*cp); \
1302		cp++; \
1303	} \
1304	if (*cp == '$') { \
1305		int hold = nextarg; \
1306		nextarg = n2; \
1307		ADDTYPE (T_INT); \
1308		nextarg = hold; \
1309		fmt = ++cp; \
1310	} else { \
1311		ADDTYPE (T_INT); \
1312	}
1313	fmt = (char *)fmt0;
1314	typetable = stattypetable;
1315	tablesize = STATIC_ARG_TBL_SIZE;
1316	tablemax = 0;
1317	nextarg = 1;
1318	for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
1319		typetable[n] = T_UNUSED;
1320
1321	/*
1322	 * Scan the format for conversions (`%' character).
1323	 */
1324	for (;;) {
1325		for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
1326			/* void */;
1327		if (ch == '\0')
1328			goto done;
1329		fmt++;		/* skip over '%' */
1330
1331		flags = 0;
1332		width = 0;
1333
1334rflag:		ch = *fmt++;
1335reswitch:	switch (ch) {
1336		case ' ':
1337		case '#':
1338			goto rflag;
1339		case '*':
1340			ADDASTER ();
1341			goto rflag;
1342		case '-':
1343		case '+':
1344		case '\'':
1345			goto rflag;
1346		case '.':
1347			if ((ch = *fmt++) == '*') {
1348				ADDASTER ();
1349				goto rflag;
1350			}
1351			while (is_digit(ch)) {
1352				ch = *fmt++;
1353			}
1354			goto reswitch;
1355		case '0':
1356			goto rflag;
1357		case '1': case '2': case '3': case '4':
1358		case '5': case '6': case '7': case '8': case '9':
1359			n = 0;
1360			do {
1361				n = 10 * n + to_digit(ch);
1362				ch = *fmt++;
1363			} while (is_digit(ch));
1364			if (ch == '$') {
1365				nextarg = n;
1366				goto rflag;
1367			}
1368			width = n;
1369			goto reswitch;
1370#ifndef NO_FLOATING_POINT
1371		case 'L':
1372			flags |= LONGDBL;
1373			goto rflag;
1374#endif
1375		case 'h':
1376			if (flags & SHORTINT) {
1377				flags &= ~SHORTINT;
1378				flags |= CHARINT;
1379			} else
1380				flags |= SHORTINT;
1381			goto rflag;
1382		case 'j':
1383			flags |= INTMAXT;
1384			goto rflag;
1385		case 'l':
1386			if (flags & LONGINT) {
1387				flags &= ~LONGINT;
1388				flags |= LLONGINT;
1389			} else
1390				flags |= LONGINT;
1391			goto rflag;
1392		case 'q':
1393			flags |= LLONGINT;	/* not necessarily */
1394			goto rflag;
1395		case 't':
1396			flags |= PTRDIFFT;
1397			goto rflag;
1398		case 'z':
1399			flags |= SIZET;
1400			goto rflag;
1401		case 'C':
1402			flags |= LONGINT;
1403			/*FALLTHROUGH*/
1404		case 'c':
1405			if (flags & LONGINT)
1406				ADDTYPE(T_WINT);
1407			else
1408				ADDTYPE(T_INT);
1409			break;
1410		case 'D':
1411			flags |= LONGINT;
1412			/*FALLTHROUGH*/
1413		case 'd':
1414		case 'i':
1415			ADDSARG();
1416			break;
1417#ifndef NO_FLOATING_POINT
1418		case 'a':
1419		case 'A':
1420		case 'e':
1421		case 'E':
1422		case 'f':
1423		case 'g':
1424		case 'G':
1425			if (flags & LONGDBL)
1426				ADDTYPE(T_LONG_DOUBLE);
1427			else
1428				ADDTYPE(T_DOUBLE);
1429			break;
1430#endif /* !NO_FLOATING_POINT */
1431		case 'n':
1432			if (flags & INTMAXT)
1433				ADDTYPE(TP_INTMAXT);
1434			else if (flags & PTRDIFFT)
1435				ADDTYPE(TP_PTRDIFFT);
1436			else if (flags & SIZET)
1437				ADDTYPE(TP_SIZET);
1438			else if (flags & LLONGINT)
1439				ADDTYPE(TP_LLONG);
1440			else if (flags & LONGINT)
1441				ADDTYPE(TP_LONG);
1442			else if (flags & SHORTINT)
1443				ADDTYPE(TP_SHORT);
1444			else if (flags & CHARINT)
1445				ADDTYPE(TP_SCHAR);
1446			else
1447				ADDTYPE(TP_INT);
1448			continue;	/* no output */
1449		case 'O':
1450			flags |= LONGINT;
1451			/*FALLTHROUGH*/
1452		case 'o':
1453			ADDUARG();
1454			break;
1455		case 'p':
1456			ADDTYPE(TP_VOID);
1457			break;
1458		case 'S':
1459			flags |= LONGINT;
1460			/*FALLTHROUGH*/
1461		case 's':
1462			if (flags & LONGINT)
1463				ADDTYPE(TP_WCHAR);
1464			else
1465				ADDTYPE(TP_CHAR);
1466			break;
1467		case 'U':
1468			flags |= LONGINT;
1469			/*FALLTHROUGH*/
1470		case 'u':
1471		case 'X':
1472		case 'x':
1473			ADDUARG();
1474			break;
1475		default:	/* "%?" prints ?, unless ? is NUL */
1476			if (ch == '\0')
1477				goto done;
1478			break;
1479		}
1480	}
1481done:
1482	/*
1483	 * Build the argument table.
1484	 */
1485	if (tablemax >= STATIC_ARG_TBL_SIZE) {
1486		*argtable = (union arg *)
1487		    malloc (sizeof (union arg) * (tablemax + 1));
1488	}
1489
1490	(*argtable) [0].intarg = 0;
1491	for (n = 1; n <= tablemax; n++) {
1492		switch (typetable [n]) {
1493		    case T_UNUSED: /* whoops! */
1494			(*argtable) [n].intarg = va_arg (ap, int);
1495			break;
1496		    case TP_SCHAR:
1497			(*argtable) [n].pschararg = va_arg (ap, signed char *);
1498			break;
1499		    case TP_SHORT:
1500			(*argtable) [n].pshortarg = va_arg (ap, short *);
1501			break;
1502		    case T_INT:
1503			(*argtable) [n].intarg = va_arg (ap, int);
1504			break;
1505		    case T_U_INT:
1506			(*argtable) [n].uintarg = va_arg (ap, unsigned int);
1507			break;
1508		    case TP_INT:
1509			(*argtable) [n].pintarg = va_arg (ap, int *);
1510			break;
1511		    case T_LONG:
1512			(*argtable) [n].longarg = va_arg (ap, long);
1513			break;
1514		    case T_U_LONG:
1515			(*argtable) [n].ulongarg = va_arg (ap, unsigned long);
1516			break;
1517		    case TP_LONG:
1518			(*argtable) [n].plongarg = va_arg (ap, long *);
1519			break;
1520		    case T_LLONG:
1521			(*argtable) [n].longlongarg = va_arg (ap, long long);
1522			break;
1523		    case T_U_LLONG:
1524			(*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
1525			break;
1526		    case TP_LLONG:
1527			(*argtable) [n].plonglongarg = va_arg (ap, long long *);
1528			break;
1529		    case T_PTRDIFFT:
1530			(*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
1531			break;
1532		    case TP_PTRDIFFT:
1533			(*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
1534			break;
1535		    case T_SIZET:
1536			(*argtable) [n].sizearg = va_arg (ap, size_t);
1537			break;
1538		    case TP_SIZET:
1539			(*argtable) [n].psizearg = va_arg (ap, ssize_t *);
1540			break;
1541		    case T_INTMAXT:
1542			(*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
1543			break;
1544		    case T_UINTMAXT:
1545			(*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
1546			break;
1547		    case TP_INTMAXT:
1548			(*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
1549			break;
1550#ifndef NO_FLOATING_POINT
1551		    case T_DOUBLE:
1552			(*argtable) [n].doublearg = va_arg (ap, double);
1553			break;
1554		    case T_LONG_DOUBLE:
1555			(*argtable) [n].longdoublearg = va_arg (ap, long double);
1556			break;
1557#endif
1558		    case TP_CHAR:
1559			(*argtable) [n].pchararg = va_arg (ap, char *);
1560			break;
1561		    case TP_VOID:
1562			(*argtable) [n].pvoidarg = va_arg (ap, void *);
1563			break;
1564		    case T_WINT:
1565			(*argtable) [n].wintarg = va_arg (ap, wint_t);
1566			break;
1567		    case TP_WCHAR:
1568			(*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
1569			break;
1570		}
1571	}
1572
1573	if ((typetable != NULL) && (typetable != stattypetable))
1574		free (typetable);
1575}
1576
1577/*
1578 * Increase the size of the type table.
1579 */
1580static void
1581__grow_type_table (int nextarg, enum typeid **typetable, int *tablesize)
1582{
1583	enum typeid *const oldtable = *typetable;
1584	const int oldsize = *tablesize;
1585	enum typeid *newtable;
1586	int n, newsize = oldsize * 2;
1587
1588	if (newsize < nextarg + 1)
1589		newsize = nextarg + 1;
1590	if (oldsize == STATIC_ARG_TBL_SIZE) {
1591		if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
1592			abort();			/* XXX handle better */
1593		bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
1594	} else {
1595		newtable = reallocf(oldtable, newsize * sizeof(enum typeid));
1596		if (newtable == NULL)
1597			abort();			/* XXX handle better */
1598	}
1599	for (n = oldsize; n < newsize; n++)
1600		newtable[n] = T_UNUSED;
1601
1602	*typetable = newtable;
1603	*tablesize = newsize;
1604}
1605
1606
1607#ifndef NO_FLOATING_POINT
1608
1609static int
1610exponent(char *p0, int exp, int fmtch)
1611{
1612	char *p, *t;
1613	char expbuf[MAXEXPDIG];
1614
1615	p = p0;
1616	*p++ = fmtch;
1617	if (exp < 0) {
1618		exp = -exp;
1619		*p++ = '-';
1620	}
1621	else
1622		*p++ = '+';
1623	t = expbuf + MAXEXPDIG;
1624	if (exp > 9) {
1625		do {
1626			*--t = to_char(exp % 10);
1627		} while ((exp /= 10) > 9);
1628		*--t = to_char(exp);
1629		for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
1630	}
1631	else {
1632		/*
1633		 * Exponents for decimal floating point conversions
1634		 * (%[eEgG]) must be at least two characters long,
1635		 * whereas exponents for hexadecimal conversions can
1636		 * be only one character long.
1637		 */
1638		if (fmtch == 'e' || fmtch == 'E')
1639			*p++ = '0';
1640		*p++ = to_char(exp);
1641	}
1642	return (p - p0);
1643}
1644#endif /* !NO_FLOATING_POINT */
1645