1/*
2 * Copyright (c) 1999-2005, 2008, 2010
3 *	Todd C. Miller <Todd.Miller@courtesan.com>
4 * Copyright (c) 1990, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * From: @(#)vfprintf.c	8.1 (Berkeley) 6/4/93
35 */
36
37/*
38 * v?snprintf/v?asprintf based on 4.4BSD stdio.
39 * NOTE: does not support floating point.
40 */
41
42#include <config.h>
43
44#include <sys/types.h>
45#include <sys/param.h>
46
47#include <stdio.h>
48#ifdef STDC_HEADERS
49# include <stdlib.h>
50# include <stddef.h>
51#else
52# ifdef HAVE_STDLIB_H
53#  include <stdlib.h>
54# endif
55#endif /* STDC_HEADERS */
56#ifdef HAVE_STDINT_H
57# include <stdint.h>
58#endif
59#ifdef HAVE_STRING_H
60# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
61#  include <memory.h>
62# endif
63# include <string.h>
64#endif /* HAVE_STRING_H */
65#ifdef HAVE_STRINGS_H
66# include <strings.h>
67#endif /* HAVE_STRINGS_H */
68#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
69# include <malloc.h>
70#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
71#include <limits.h>
72
73#ifdef __STDC__
74# include <stdarg.h>
75#else
76# include <varargs.h>
77#endif
78
79#include "missing.h"
80
81static int xxxprintf	 __P((char **, size_t, int, const char *, va_list));
82
83/*
84 * Some systems may not have these defined in <limits.h>
85 */
86#ifndef ULONG_MAX
87# define ULONG_MAX	((unsigned long)-1)
88#endif
89#ifndef LONG_MAX
90# define LONG_MAX	(ULONG_MAX / 2)
91#endif
92#ifdef HAVE_LONG_LONG_INT
93# ifndef ULLONG_MAX
94#  ifdef UQUAD_MAX
95#   define ULLONG_MAX	UQUAD_MAX
96#  else
97#   define ULLONG_MAX	((unsigned long long)-1)
98#  endif
99# endif
100# ifndef LLONG_MAX
101#  ifdef QUAD_MAX
102#   define LLONG_MAX	QUAD_MAX
103#  else
104#   define LLONG_MAX	(ULLONG_MAX / 2)
105#  endif
106# endif
107#endif /* HAVE_LONG_LONG_INT */
108
109/*
110 * Macros for converting digits to letters and vice versa
111 */
112#define	to_digit(c)	((c) - '0')
113#define is_digit(c)	((unsigned int)to_digit(c) <= 9)
114#define	to_char(n)	((n) + '0')
115
116/*
117 * Flags used during conversion.
118 */
119#define	ALT		0x001		/* alternate form */
120#define	HEXPREFIX	0x002		/* add 0x or 0X prefix */
121#define	LADJUST		0x004		/* left adjustment */
122#define	LONGDBL		0x008		/* long double; unimplemented */
123#define	LONGINT		0x010		/* long integer */
124#define	QUADINT		0x020		/* quad integer */
125#define	SHORTINT	0x040		/* short integer */
126#define	ZEROPAD		0x080		/* zero (as opposed to blank) pad */
127
128#define BUF		68
129
130#ifndef HAVE_MEMCHR
131void *
132memchr(s, c, n)
133	const void *s;
134	unsigned char c;
135	size_t n;
136{
137	if (n != 0) {
138		const unsigned char *p = s;
139
140		do {
141			if (*p++ == c)
142				return (void *)(p - 1);
143		} while (--n != 0);
144	}
145	return NULL;
146}
147#endif /* !HAVE_MEMCHR */
148
149/*
150 * Convert an unsigned long to ASCII for printf purposes, returning
151 * a pointer to the first character of the string representation.
152 * Octal numbers can be forced to have a leading zero; hex numbers
153 * use the given digits.
154 */
155static char *
156__ultoa(val, endp, base, octzero, xdigs)
157	unsigned long val;
158	char *endp;
159	int base, octzero;
160	char *xdigs;
161{
162	char *cp = endp;
163	long sval;
164
165	/*
166	 * Handle the three cases separately, in the hope of getting
167	 * better/faster code.
168	 */
169	switch (base) {
170	case 10:
171		if (val < 10) {	/* many numbers are 1 digit */
172			*--cp = to_char(val);
173			return cp;
174		}
175		/*
176		 * On many machines, unsigned arithmetic is harder than
177		 * signed arithmetic, so we do at most one unsigned mod and
178		 * divide; this is sufficient to reduce the range of
179		 * the incoming value to where signed arithmetic works.
180		 */
181		if (val > LONG_MAX) {
182			*--cp = to_char(val % 10);
183			sval = val / 10;
184		} else
185			sval = val;
186		do {
187			*--cp = to_char(sval % 10);
188			sval /= 10;
189		} while (sval != 0);
190		break;
191
192	case 8:
193		do {
194			*--cp = to_char(val & 7);
195			val >>= 3;
196		} while (val);
197		if (octzero && *cp != '0')
198			*--cp = '0';
199		break;
200
201	case 16:
202		do {
203			*--cp = xdigs[val & 15];
204			val >>= 4;
205		} while (val);
206		break;
207
208	default:			/* oops */
209		abort();
210	}
211	return cp;
212}
213
214/* Identical to __ultoa, but for quads. */
215#ifdef HAVE_LONG_LONG_INT
216# if SIZEOF_LONG_INT == 8
217#  define __uqtoa(v, e, b, o, x) __ultoa((unsigned long)(v), (e), (b), (o), (x))
218# else
219static char *
220__uqtoa(val, endp, base, octzero, xdigs)
221	unsigned long long val;
222	char *endp;
223	int base, octzero;
224	char *xdigs;
225{
226	char *cp = endp;
227	long long sval;
228
229	/* quick test for small values; __ultoa is typically much faster */
230	/* (perhaps instead we should run until small, then call __ultoa?) */
231	if (val <= (unsigned long long)ULONG_MAX)
232		return __ultoa((unsigned long)val, endp, base, octzero, xdigs);
233	switch (base) {
234	case 10:
235		if (val < 10) {
236			*--cp = to_char(val % 10);
237			return cp;
238		}
239		if (val > LLONG_MAX) {
240			*--cp = to_char(val % 10);
241			sval = val / 10;
242		} else
243			sval = val;
244		do {
245			*--cp = to_char(sval % 10);
246			sval /= 10;
247		} while (sval != 0);
248		break;
249
250	case 8:
251		do {
252			*--cp = to_char(val & 7);
253			val >>= 3;
254		} while (val);
255		if (octzero && *cp != '0')
256			*--cp = '0';
257		break;
258
259	case 16:
260		do {
261			*--cp = xdigs[val & 15];
262			val >>= 4;
263		} while (val);
264		break;
265
266	default:			/* oops */
267		abort();
268	}
269	return cp;
270}
271# endif /* !SIZEOF_LONG_INT */
272#endif /* HAVE_LONG_LONG_INT */
273
274/*
275 * Actual printf innards.
276 */
277static int
278xxxprintf(strp, strsize, alloc, fmt0, ap)
279	char **strp;
280	size_t strsize;
281	int alloc;
282	const char *fmt0;
283	va_list ap;
284{
285	char *fmt;		/* format string */
286	int ch;			/* character from fmt */
287	int n;			/* handy integer (short term usage) */
288	char *cp;		/* handy char pointer (short term usage) */
289	int flags;		/* flags as above */
290	int ret;		/* return value accumulator */
291	int width;		/* width from format (%8d), or 0 */
292	int prec;		/* precision from format (%.3d), or -1 */
293	char sign;		/* sign prefix (' ', '+', '-', or \0) */
294	unsigned long ulval = 0; /* integer arguments %[diouxX] */
295#ifdef HAVE_LONG_LONG_INT
296	unsigned long long uqval = 0; /* %q (quad) integers */
297#endif
298	int base;		/* base for [diouxX] conversion */
299	int dprec;		/* a copy of prec if [diouxX], 0 otherwise */
300	int fieldsz;		/* field size expanded by sign, etc */
301	int realsz;		/* field size expanded by dprec */
302	int size;		/* size of converted field or string */
303	char *xdigs = "";	/* digits for [xX] conversion */
304	char buf[BUF];		/* space for %c, %[diouxX], %[eEfgG] */
305	char ox[2];		/* space for 0x hex-prefix */
306	char *str;		/* pointer to string to fill */
307	char *estr;		/* pointer to last char in str */
308
309	/*
310	 * Choose PADSIZE to trade efficiency vs. size.  If larger printf
311	 * fields occur frequently, increase PADSIZE and make the initialisers
312	 * below longer.
313	 */
314#define	PADSIZE	16		/* pad chunk size */
315	static char blanks[PADSIZE] =
316	 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
317	static char zeroes[PADSIZE] =
318	 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
319
320	/* Print chars to "str", (allocate as needed if alloc is set). */
321#define	PRINT(ptr, len) do { \
322	const char *p = ptr; \
323	const char *endp = ptr + len; \
324	while (p < endp && (str < estr || alloc)) { \
325		if (alloc && str >= estr) { \
326			char *t; \
327			strsize = (strsize << 1) + 1; \
328			if (!(t = (char *)realloc(*strp, strsize))) { \
329				free(str); \
330				*strp = NULL; \
331				ret = -1; \
332				goto done; \
333			} \
334			str = t + (str - *strp); \
335			estr = t + strsize - 1; \
336			*strp = t; \
337		} \
338		*str++ = *p++; \
339	} \
340} while (0)
341
342	/* BEWARE, PAD uses `n'. */
343#define	PAD(plen, pstr) do { \
344	if ((n = (plen)) > 0) { \
345		while (n > PADSIZE) { \
346			PRINT(pstr, PADSIZE); \
347			n -= PADSIZE; \
348		} \
349		PRINT(pstr, n); \
350	} \
351} while (0)
352
353	/*
354	 * To extend shorts properly, we need both signed and unsigned
355	 * argument extraction methods.
356	 */
357#define	SARG() \
358	(flags&LONGINT ? va_arg(ap, long) : \
359	    flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
360	    (long)va_arg(ap, int))
361#define	UARG() \
362	(flags&LONGINT ? va_arg(ap, unsigned long) : \
363	    flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \
364	    (unsigned long)va_arg(ap, unsigned int))
365
366	fmt = (char *)fmt0;
367	ret = 0;
368
369	if (alloc) {
370		strsize = 128;
371		*strp = str = (char *)malloc(strsize);
372		if (str == NULL) {
373			ret = -1;
374			goto done;
375		}
376		estr = str + 127;
377	} else {
378		str = *strp;
379		if (strsize)
380			estr = str + strsize - 1;
381		else
382			estr = NULL;
383	}
384
385	/*
386	 * Scan the format for conversions (`%' character).
387	 */
388	for (;;) {
389		for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
390			/* void */;
391		if ((n = fmt - cp) != 0) {
392			PRINT(cp, n);
393			ret += n;
394		}
395		if (ch == '\0')
396			goto done;
397		fmt++;		/* skip over '%' */
398
399		flags = 0;
400		dprec = 0;
401		width = 0;
402		prec = -1;
403		sign = '\0';
404
405rflag:		ch = *fmt++;
406reswitch:	switch (ch) {
407		case ' ':
408			/*
409			 * ``If the space and + flags both appear, the space
410			 * flag will be ignored.''
411			 *	-- ANSI X3J11
412			 */
413			if (!sign)
414				sign = ' ';
415			goto rflag;
416		case '#':
417			flags |= ALT;
418			goto rflag;
419		case '*':
420			/*
421			 * ``A negative field width argument is taken as a
422			 * - flag followed by a positive field width.''
423			 *	-- ANSI X3J11
424			 * They don't exclude field widths read from args.
425			 */
426			if ((width = va_arg(ap, int)) >= 0)
427				goto rflag;
428			width = -width;
429			/* FALLTHROUGH */
430		case '-':
431			flags |= LADJUST;
432			goto rflag;
433		case '+':
434			sign = '+';
435			goto rflag;
436		case '.':
437			if ((ch = *fmt++) == '*') {
438				n = va_arg(ap, int);
439				prec = n < 0 ? -1 : n;
440				goto rflag;
441			}
442			n = 0;
443			while (is_digit(ch)) {
444				n = 10 * n + to_digit(ch);
445				ch = *fmt++;
446			}
447			prec = n < 0 ? -1 : n;
448			goto reswitch;
449		case '0':
450			/*
451			 * ``Note that 0 is taken as a flag, not as the
452			 * beginning of a field width.''
453			 *	-- ANSI X3J11
454			 */
455			flags |= ZEROPAD;
456			goto rflag;
457		case '1': case '2': case '3': case '4':
458		case '5': case '6': case '7': case '8': case '9':
459			n = 0;
460			do {
461				n = 10 * n + to_digit(ch);
462				ch = *fmt++;
463			} while (is_digit(ch));
464			width = n;
465			goto reswitch;
466		case 'h':
467			flags |= SHORTINT;
468			goto rflag;
469		case 'l':
470			flags |= LONGINT;
471			goto rflag;
472#ifdef HAVE_LONG_LONG_INT
473		case 'q':
474			flags |= QUADINT;
475			goto rflag;
476#endif /* HAVE_LONG_LONG_INT */
477		case 'c':
478			*(cp = buf) = va_arg(ap, int);
479			size = 1;
480			sign = '\0';
481			break;
482		case 'D':
483			flags |= LONGINT;
484			/*FALLTHROUGH*/
485		case 'd':
486		case 'i':
487#ifdef HAVE_LONG_LONG_INT
488			if (flags & QUADINT) {
489				uqval = va_arg(ap, long long);
490				if ((long long)uqval < 0) {
491					uqval = -uqval;
492					sign = '-';
493				}
494			}
495			else
496#endif /* HAVE_LONG_LONG_INT */
497			{
498				ulval = SARG();
499				if ((long)ulval < 0) {
500					ulval = -ulval;
501					sign = '-';
502				}
503			}
504			base = 10;
505			goto number;
506		case 'n':
507#ifdef HAVE_LONG_LONG_INT
508			if (flags & QUADINT)
509				*va_arg(ap, long long *) = ret;
510			else
511#endif /* HAVE_LONG_LONG_INT */
512			if (flags & LONGINT)
513				*va_arg(ap, long *) = ret;
514			else if (flags & SHORTINT)
515				*va_arg(ap, short *) = ret;
516			else
517				*va_arg(ap, int *) = ret;
518			continue;	/* no output */
519		case 'O':
520			flags |= LONGINT;
521			/*FALLTHROUGH*/
522		case 'o':
523#ifdef HAVE_LONG_LONG_INT
524			if (flags & QUADINT)
525				uqval = va_arg(ap, unsigned long long);
526			else
527#endif /* HAVE_LONG_LONG_INT */
528				ulval = UARG();
529			base = 8;
530			goto nosign;
531		case 'p':
532			/*
533			 * ``The argument shall be a pointer to void.  The
534			 * value of the pointer is converted to a sequence
535			 * of printable characters, in an implementation-
536			 * defined manner.''
537			 *	-- ANSI X3J11
538			 */
539			ulval = (unsigned long)va_arg(ap, void *);
540			base = 16;
541			xdigs = "0123456789abcdef";
542			flags = (flags & ~QUADINT) | HEXPREFIX;
543			ch = 'x';
544			goto nosign;
545		case 's':
546			if ((cp = va_arg(ap, char *)) == NULL)
547				cp = "(null)";
548			if (prec >= 0) {
549				/*
550				 * can't use strlen; can only look for the
551				 * NUL in the first `prec' characters, and
552				 * strlen() will go further.
553				 */
554				char *p = memchr(cp, 0, prec);
555
556				if (p != NULL) {
557					size = p - cp;
558					if (size > prec)
559						size = prec;
560				} else
561					size = prec;
562			} else
563				size = strlen(cp);
564			sign = '\0';
565			break;
566		case 'U':
567			flags |= LONGINT;
568			/*FALLTHROUGH*/
569		case 'u':
570#ifdef HAVE_LONG_LONG_INT
571			if (flags & QUADINT)
572				uqval = va_arg(ap, unsigned long long);
573			else
574#endif /* HAVE_LONG_LONG_INT */
575				ulval = UARG();
576			base = 10;
577			goto nosign;
578		case 'X':
579			xdigs = "0123456789ABCDEF";
580			goto hex;
581		case 'x':
582			xdigs = "0123456789abcdef";
583hex:
584#ifdef HAVE_LONG_LONG_INT
585			if (flags & QUADINT)
586				uqval = va_arg(ap, unsigned long long);
587			else
588#endif /* HAVE_LONG_LONG_INT */
589				ulval = UARG();
590			base = 16;
591			/* leading 0x/X only if non-zero */
592			if (flags & ALT &&
593#ifdef HAVE_LONG_LONG_INT
594			    (flags & QUADINT ? uqval != 0 : ulval != 0))
595#else
596			    ulval != 0)
597#endif /* HAVE_LONG_LONG_INT */
598				flags |= HEXPREFIX;
599
600			/* unsigned conversions */
601nosign:			sign = '\0';
602			/*
603			 * ``... diouXx conversions ... if a precision is
604			 * specified, the 0 flag will be ignored.''
605			 *	-- ANSI X3J11
606			 */
607number:			if ((dprec = prec) >= 0)
608				flags &= ~ZEROPAD;
609
610			/*
611			 * ``The result of converting a zero value with an
612			 * explicit precision of zero is no characters.''
613			 *	-- ANSI X3J11
614			 */
615			cp = buf + BUF;
616#ifdef HAVE_LONG_LONG_INT
617			if (flags & QUADINT) {
618				if (uqval != 0 || prec != 0)
619					cp = __uqtoa(uqval, cp, base,
620					    flags & ALT, xdigs);
621			}
622			else
623#endif /* HAVE_LONG_LONG_INT */
624			{
625				if (ulval != 0 || prec != 0)
626					cp = __ultoa(ulval, cp, base,
627					    flags & ALT, xdigs);
628			}
629			size = buf + BUF - cp;
630			break;
631		default:	/* "%?" prints ?, unless ? is NUL */
632			if (ch == '\0')
633				goto done;
634			/* pretend it was %c with argument ch */
635			cp = buf;
636			*cp = ch;
637			size = 1;
638			sign = '\0';
639			break;
640		}
641
642		/*
643		 * All reasonable formats wind up here.  At this point, `cp'
644		 * points to a string which (if not flags&LADJUST) should be
645		 * padded out to `width' places.  If flags&ZEROPAD, it should
646		 * first be prefixed by any sign or other prefix; otherwise,
647		 * it should be blank padded before the prefix is emitted.
648		 * After any left-hand padding and prefixing, emit zeroes
649		 * required by a decimal [diouxX] precision, then print the
650		 * string proper, then emit zeroes required by any leftover
651		 * floating precision; finally, if LADJUST, pad with blanks.
652		 *
653		 * Compute actual size, so we know how much to pad.
654		 * fieldsz excludes decimal prec; realsz includes it.
655		 */
656		fieldsz = size;
657		if (sign)
658			fieldsz++;
659		else if (flags & HEXPREFIX)
660			fieldsz += 2;
661		realsz = dprec > fieldsz ? dprec : fieldsz;
662
663		/* right-adjusting blank padding */
664		if ((flags & (LADJUST|ZEROPAD)) == 0)
665			PAD(width - realsz, blanks);
666
667		/* prefix */
668		if (sign) {
669			PRINT(&sign, 1);
670		} else if (flags & HEXPREFIX) {
671			ox[0] = '0';
672			ox[1] = ch;
673			PRINT(ox, 2);
674		}
675
676		/* right-adjusting zero padding */
677		if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
678			PAD(width - realsz, zeroes);
679
680		/* leading zeroes from decimal precision */
681		PAD(dprec - fieldsz, zeroes);
682
683		/* the string or number proper */
684		PRINT(cp, size);
685
686		/* left-adjusting padding (always blank) */
687		if (flags & LADJUST)
688			PAD(width - realsz, blanks);
689
690		/* finally, adjust ret */
691		ret += width > realsz ? width : realsz;
692	}
693done:
694	if (strsize)
695		*str = '\0';
696	return ret;
697	/* NOTREACHED */
698}
699
700#ifndef HAVE_VSNPRINTF
701int
702vsnprintf(str, n, fmt, ap)
703	char *str;
704	size_t n;
705	const char *fmt;
706	va_list ap;
707{
708
709	return xxxprintf(&str, n, 0, fmt, ap);
710}
711#endif /* HAVE_VSNPRINTF */
712
713#ifndef HAVE_SNPRINTF
714int
715#ifdef __STDC__
716snprintf(char *str, size_t n, char const *fmt, ...)
717#else
718snprintf(str, n, fmt, va_alist)
719	char *str;
720	size_t n;
721	char const *fmt;
722	va_dcl
723#endif
724{
725	int ret;
726	va_list ap;
727
728#ifdef __STDC__
729	va_start(ap, fmt);
730#else
731	va_start(ap);
732#endif
733	ret = xxxprintf(&str, n, 0, fmt, ap);
734	va_end(ap);
735	return ret;
736}
737#endif /* HAVE_SNPRINTF */
738
739#ifndef HAVE_VASPRINTF
740int
741vasprintf(str, fmt, ap)
742	char **str;
743	const char *fmt;
744	va_list ap;
745{
746
747	return xxxprintf(str, 0, 1, fmt, ap);
748}
749#endif /* HAVE_VASPRINTF */
750
751#ifndef HAVE_ASPRINTF
752int
753#ifdef __STDC__
754asprintf(char **str, char const *fmt, ...)
755#else
756asprintf(str, fmt, va_alist)
757	char **str;
758	char const *fmt;
759	va_dcl
760#endif
761{
762	int ret;
763	va_list ap;
764
765#ifdef __STDC__
766	va_start(ap, fmt);
767#else
768	va_start(ap);
769#endif
770	ret = xxxprintf(str, 0, 1, fmt, ap);
771	va_end(ap);
772	return ret;
773}
774#endif /* HAVE_ASPRINTF */
775