1/*
2 * Copyright (c) 1995 Patrick Powell.
3 *
4 * This code is based on code written by Patrick Powell <papowell@astart.com>.
5 * It may be used for any purpose as long as this notice remains intact on all
6 * source code distributions.
7 */
8
9/*
10 * Copyright (c) 2008 Holger Weiss.
11 *
12 * This version of the code is maintained by Holger Weiss <holger@jhweiss.de>.
13 * My changes to the code may freely be used, modified and/or redistributed for
14 * any purpose.  It would be nice if additions and fixes to this file (including
15 * trivial code cleanups) would be sent back in order to let me include them in
16 * the version available at <http://www.jhweiss.de/software/snprintf.html>.
17 * However, this is not a requirement for using or redistributing (possibly
18 * modified) versions of this file, nor is leaving this notice intact mandatory.
19 */
20
21/*
22 * History
23 *
24 * 2008-01-20 Holger Weiss <holger@jhweiss.de> for C99-snprintf 1.1:
25 *
26 * 	Fixed the detection of infinite floating point values on IRIX (and
27 * 	possibly other systems) and applied another few minor cleanups.
28 *
29 * 2008-01-06 Holger Weiss <holger@jhweiss.de> for C99-snprintf 1.0:
30 *
31 * 	Added a lot of new features, fixed many bugs, and incorporated various
32 * 	improvements done by Andrew Tridgell <tridge@samba.org>, Russ Allbery
33 * 	<rra@stanford.edu>, Hrvoje Niksic <hniksic@xemacs.org>, Damien Miller
34 * 	<djm@mindrot.org>, and others for the Samba, INN, Wget, and OpenSSH
35 * 	projects.  The additions include: support the "e", "E", "g", "G", and
36 * 	"F" conversion specifiers (and use conversion style "f" or "F" for the
37 * 	still unsupported "a" and "A" specifiers); support the "hh", "ll", "j",
38 * 	"t", and "z" length modifiers; support the "#" flag and the (non-C99)
39 * 	"'" flag; use localeconv(3) (if available) to get both the current
40 * 	locale's decimal point character and the separator between groups of
41 * 	digits; fix the handling of various corner cases of field width and
42 * 	precision specifications; fix various floating point conversion bugs;
43 * 	handle infinite and NaN floating point values; don't attempt to write to
44 * 	the output buffer (which may be NULL) if a size of zero was specified;
45 * 	check for integer overflow of the field width, precision, and return
46 * 	values and during the floating point conversion; use the OUTCHAR() macro
47 * 	instead of a function for better performance; provide asprintf(3) and
48 * 	vasprintf(3) functions; add new test cases.  The replacement functions
49 * 	have been renamed to use an "rpl_" prefix, the function calls in the
50 * 	main project (and in this file) must be redefined accordingly for each
51 * 	replacement function which is needed (by using Autoconf or other means).
52 * 	Various other minor improvements have been applied and the coding style
53 * 	was cleaned up for consistency.
54 *
55 * 2007-07-23 Holger Weiss <holger@jhweiss.de> for Mutt 1.5.13:
56 *
57 * 	C99 compliant snprintf(3) and vsnprintf(3) functions return the number
58 * 	of characters that would have been written to a sufficiently sized
59 * 	buffer (excluding the '\0').  The original code simply returned the
60 * 	length of the resulting output string, so that's been fixed.
61 *
62 * 1998-03-05 Michael Elkins <me@mutt.org> for Mutt 0.90.8:
63 *
64 * 	The original code assumed that both snprintf(3) and vsnprintf(3) were
65 * 	missing.  Some systems only have snprintf(3) but not vsnprintf(3), so
66 * 	the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
67 *
68 * 1998-01-27 Thomas Roessler <roessler@does-not-exist.org> for Mutt 0.89i:
69 *
70 * 	The PGP code was using unsigned hexadecimal formats.  Unfortunately,
71 * 	unsigned formats simply didn't work.
72 *
73 * 1997-10-22 Brandon Long <blong@fiction.net> for Mutt 0.87.1:
74 *
75 * 	Ok, added some minimal floating point support, which means this probably
76 * 	requires libm on most operating systems.  Don't yet support the exponent
77 * 	(e,E) and sigfig (g,G).  Also, fmtint() was pretty badly broken, it just
78 * 	wasn't being exercised in ways which showed it, so that's been fixed.
79 * 	Also, formatted the code to Mutt conventions, and removed dead code left
80 * 	over from the original.  Also, there is now a builtin-test, run with:
81 * 	gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf
82 *
83 * 2996-09-15 Brandon Long <blong@fiction.net> for Mutt 0.43:
84 *
85 * 	This was ugly.  It is still ugly.  I opted out of floating point
86 * 	numbers, but the formatter understands just about everything from the
87 * 	normal C string format, at least as far as I can tell from the Solaris
88 * 	2.5 printf(3S) man page.
89 */
90
91/*
92 * ToDo
93 *
94 * - Add wide character support.
95 * - Add support for "%a" and "%A" conversions.
96 * - Create test routines which predefine the expected results.  Our test cases
97 *   usually expose bugs in system implementations rather than in ours :-)
98 */
99
100/*
101 * Usage
102 *
103 * 1) The following preprocessor macros should be defined to 1 if the feature or
104 *    file in question is available on the target system (by using Autoconf or
105 *    other means), though basic functionality should be available as long as
106 *    HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly:
107 *
108 *    	HAVE_VSNPRINTF
109 *    	HAVE_SNPRINTF
110 *    	HAVE_VASPRINTF
111 *    	HAVE_ASPRINTF
112 *    	HAVE_STDARG_H
113 *    	HAVE_STDDEF_H
114 *    	HAVE_STDINT_H
115 *    	HAVE_STDLIB_H
116 *    	HAVE_INTTYPES_H
117 *    	HAVE_LOCALE_H
118 *    	HAVE_LOCALECONV
119 *    	HAVE_LCONV_DECIMAL_POINT
120 *    	HAVE_LCONV_THOUSANDS_SEP
121 *    	HAVE_LONG_DOUBLE
122 *    	HAVE_LONG_LONG_INT
123 *    	HAVE_UNSIGNED_LONG_LONG_INT
124 *    	HAVE_INTMAX_T
125 *    	HAVE_UINTMAX_T
126 *    	HAVE_UINTPTR_T
127 *    	HAVE_PTRDIFF_T
128 *    	HAVE_VA_COPY
129 *    	HAVE___VA_COPY
130 *
131 * 2) The calls to the functions which should be replaced must be redefined
132 *    throughout the project files (by using Autoconf or other means):
133 *
134 *    	#define vsnprintf rpl_vsnprintf
135 *    	#define snprintf rpl_snprintf
136 *    	#define vasprintf rpl_vasprintf
137 *    	#define asprintf rpl_asprintf
138 *
139 * 3) The required replacement functions should be declared in some header file
140 *    included throughout the project files:
141 *
142 *    	#if HAVE_CONFIG_H
143 *    	#include <config.h>
144 *    	#endif
145 *    	#if HAVE_STDARG_H
146 *    	#include <stdarg.h>
147 *    	#if !HAVE_VSNPRINTF
148 *    	int rpl_vsnprintf(char *, size_t, const char *, va_list);
149 *    	#endif
150 *    	#if !HAVE_SNPRINTF
151 *    	int rpl_snprintf(char *, size_t, const char *, ...);
152 *    	#endif
153 *    	#if !HAVE_VASPRINTF
154 *    	int rpl_vasprintf(char **, const char *, va_list);
155 *    	#endif
156 *    	#if !HAVE_ASPRINTF
157 *    	int rpl_asprintf(char **, const char *, ...);
158 *    	#endif
159 *    	#endif
160 *
161 * Autoconf macros for handling step 1 and step 2 are available at
162 * <http://www.jhweiss.de/software/snprintf.html>.
163 */
164
165#include "pipe/p_config.h"
166
167#if HAVE_CONFIG_H
168#include <config.h>
169#else
170#ifdef WIN32
171#define vsnprintf util_vsnprintf
172#define snprintf util_snprintf
173#define HAVE_VSNPRINTF 0
174#define HAVE_SNPRINTF 0
175#define HAVE_VASPRINTF 1 /* not needed */
176#define HAVE_ASPRINTF 1 /* not needed */
177#define HAVE_STDARG_H 1
178#define HAVE_STDDEF_H 1
179#define HAVE_STDINT_H 0
180#define HAVE_STDLIB_H 1
181#define HAVE_INTTYPES_H 0
182#define HAVE_LOCALE_H 0
183#define HAVE_LOCALECONV 0
184#define HAVE_LCONV_DECIMAL_POINT 0
185#define HAVE_LCONV_THOUSANDS_SEP 0
186#define HAVE_LONG_DOUBLE 0
187#define HAVE_LONG_LONG_INT 1
188#define HAVE_UNSIGNED_LONG_LONG_INT 1
189#define HAVE_INTMAX_T 0
190#define HAVE_UINTMAX_T 0
191#define HAVE_UINTPTR_T 1
192#define HAVE_PTRDIFF_T 1
193#define HAVE_VA_COPY 0
194#define HAVE___VA_COPY 0
195#else
196#define HAVE_VSNPRINTF 1
197#define HAVE_SNPRINTF 1
198#define HAVE_VASPRINTF 1
199#define HAVE_ASPRINTF 1
200#endif
201#endif	/* HAVE_CONFIG_H */
202
203#if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF
204#include <stdio.h>	/* For NULL, size_t, vsnprintf(3), and vasprintf(3). */
205#ifdef VA_START
206#undef VA_START
207#endif	/* defined(VA_START) */
208#ifdef VA_SHIFT
209#undef VA_SHIFT
210#endif	/* defined(VA_SHIFT) */
211#if HAVE_STDARG_H
212#include <stdarg.h>
213#define VA_START(ap, last) va_start(ap, last)
214#define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */
215#else	/* Assume <varargs.h> is available. */
216#include <varargs.h>
217#define VA_START(ap, last) va_start(ap)	/* "last" is ignored. */
218#define VA_SHIFT(ap, value, type) value = va_arg(ap, type)
219#endif	/* HAVE_STDARG_H */
220
221#if !HAVE_VASPRINTF
222#if HAVE_STDLIB_H
223#include <stdlib.h>	/* For malloc(3). */
224#endif	/* HAVE_STDLIB_H */
225#ifdef VA_COPY
226#undef VA_COPY
227#endif	/* defined(VA_COPY) */
228#ifdef VA_END_COPY
229#undef VA_END_COPY
230#endif	/* defined(VA_END_COPY) */
231#if HAVE_VA_COPY
232#define VA_COPY(dest, src) va_copy(dest, src)
233#define VA_END_COPY(ap) va_end(ap)
234#elif HAVE___VA_COPY
235#define VA_COPY(dest, src) __va_copy(dest, src)
236#define VA_END_COPY(ap) va_end(ap)
237#else
238#define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list))
239#define VA_END_COPY(ap) /* No-op. */
240#define NEED_MYMEMCPY 1
241static void *mymemcpy(void *, void *, size_t);
242#endif	/* HAVE_VA_COPY */
243#endif	/* !HAVE_VASPRINTF */
244
245#if !HAVE_VSNPRINTF
246#include <limits.h>	/* For *_MAX. */
247#if HAVE_INTTYPES_H
248#include <inttypes.h>	/* For intmax_t (if not defined in <stdint.h>). */
249#endif	/* HAVE_INTTYPES_H */
250#if HAVE_LOCALE_H
251#include <locale.h>	/* For localeconv(3). */
252#endif	/* HAVE_LOCALE_H */
253#if HAVE_STDDEF_H
254#include <stddef.h>	/* For ptrdiff_t. */
255#endif	/* HAVE_STDDEF_H */
256#if HAVE_STDINT_H
257#include <stdint.h>	/* For intmax_t. */
258#endif	/* HAVE_STDINT_H */
259
260/* Support for unsigned long long int.  We may also need ULLONG_MAX. */
261#ifndef ULONG_MAX	/* We may need ULONG_MAX as a fallback. */
262#ifdef UINT_MAX
263#define ULONG_MAX UINT_MAX
264#else
265#define ULONG_MAX INT_MAX
266#endif	/* defined(UINT_MAX) */
267#endif	/* !defined(ULONG_MAX) */
268#ifdef ULLONG
269#undef ULLONG
270#endif	/* defined(ULLONG) */
271#if HAVE_UNSIGNED_LONG_LONG_INT
272#define ULLONG unsigned long long int
273#ifndef ULLONG_MAX
274#define ULLONG_MAX ULONG_MAX
275#endif	/* !defined(ULLONG_MAX) */
276#else
277#define ULLONG unsigned long int
278#ifdef ULLONG_MAX
279#undef ULLONG_MAX
280#endif	/* defined(ULLONG_MAX) */
281#define ULLONG_MAX ULONG_MAX
282#endif	/* HAVE_LONG_LONG_INT */
283
284/* Support for uintmax_t.  We also need UINTMAX_MAX. */
285#ifdef UINTMAX_T
286#undef UINTMAX_T
287#endif	/* defined(UINTMAX_T) */
288#if HAVE_UINTMAX_T || defined(uintmax_t)
289#define UINTMAX_T uintmax_t
290#ifndef UINTMAX_MAX
291#define UINTMAX_MAX ULLONG_MAX
292#endif	/* !defined(UINTMAX_MAX) */
293#else
294#define UINTMAX_T ULLONG
295#ifdef UINTMAX_MAX
296#undef UINTMAX_MAX
297#endif	/* defined(UINTMAX_MAX) */
298#define UINTMAX_MAX ULLONG_MAX
299#endif	/* HAVE_UINTMAX_T || defined(uintmax_t) */
300
301/* Support for long double. */
302#ifndef LDOUBLE
303#if HAVE_LONG_DOUBLE
304#define LDOUBLE long double
305#else
306#define LDOUBLE double
307#endif	/* HAVE_LONG_DOUBLE */
308#endif	/* !defined(LDOUBLE) */
309
310/* Support for long long int. */
311#ifndef LLONG
312#if HAVE_LONG_LONG_INT
313#define LLONG long long int
314#else
315#define LLONG long int
316#endif	/* HAVE_LONG_LONG_INT */
317#endif	/* !defined(LLONG) */
318
319/* Support for intmax_t. */
320#ifndef INTMAX_T
321#if HAVE_INTMAX_T || defined(intmax_t)
322#define INTMAX_T intmax_t
323#else
324#define INTMAX_T LLONG
325#endif	/* HAVE_INTMAX_T || defined(intmax_t) */
326#endif	/* !defined(INTMAX_T) */
327
328/* Support for uintptr_t. */
329#ifndef UINTPTR_T
330#if HAVE_UINTPTR_T || defined(uintptr_t)
331#define UINTPTR_T uintptr_t
332#else
333#define UINTPTR_T unsigned long int
334#endif	/* HAVE_UINTPTR_T || defined(uintptr_t) */
335#endif	/* !defined(UINTPTR_T) */
336
337/* WinCE5.0 does not have uintptr_t defined */
338#if (_WIN32_WCE < 600)
339#ifdef UINTPTR_T
340#undef UINTPTR_T
341#endif
342#define UINTPTR_T unsigned long int
343#endif
344
345
346/* Support for ptrdiff_t. */
347#ifndef PTRDIFF_T
348#if HAVE_PTRDIFF_T || defined(ptrdiff_t)
349#define PTRDIFF_T ptrdiff_t
350#else
351#define PTRDIFF_T long int
352#endif	/* HAVE_PTRDIFF_T || defined(ptrdiff_t) */
353#endif	/* !defined(PTRDIFF_T) */
354
355/*
356 * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99:
357 * 7.19.6.1, 7).  However, we'll simply use PTRDIFF_T and convert it to an
358 * unsigned type if necessary.  This should work just fine in practice.
359 */
360#ifndef UPTRDIFF_T
361#define UPTRDIFF_T PTRDIFF_T
362#endif	/* !defined(UPTRDIFF_T) */
363
364/*
365 * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7).
366 * However, we'll simply use size_t and convert it to a signed type if
367 * necessary.  This should work just fine in practice.
368 */
369#ifndef SSIZE_T
370#define SSIZE_T size_t
371#endif	/* !defined(SSIZE_T) */
372
373/* Either ERANGE or E2BIG should be available everywhere. */
374#ifndef ERANGE
375#define ERANGE E2BIG
376#endif	/* !defined(ERANGE) */
377#ifndef EOVERFLOW
378#define EOVERFLOW ERANGE
379#endif	/* !defined(EOVERFLOW) */
380
381/*
382 * Buffer size to hold the octal string representation of UINT128_MAX without
383 * nul-termination ("3777777777777777777777777777777777777777777").
384 */
385#ifdef MAX_CONVERT_LENGTH
386#undef MAX_CONVERT_LENGTH
387#endif	/* defined(MAX_CONVERT_LENGTH) */
388#define MAX_CONVERT_LENGTH      43
389
390/* Format read states. */
391#define PRINT_S_DEFAULT         0
392#define PRINT_S_FLAGS           1
393#define PRINT_S_WIDTH           2
394#define PRINT_S_DOT             3
395#define PRINT_S_PRECISION       4
396#define PRINT_S_MOD             5
397#define PRINT_S_CONV            6
398
399/* Format flags. */
400#define PRINT_F_MINUS           (1 << 0)
401#define PRINT_F_PLUS            (1 << 1)
402#define PRINT_F_SPACE           (1 << 2)
403#define PRINT_F_NUM             (1 << 3)
404#define PRINT_F_ZERO            (1 << 4)
405#define PRINT_F_QUOTE           (1 << 5)
406#define PRINT_F_UP              (1 << 6)
407#define PRINT_F_UNSIGNED        (1 << 7)
408#define PRINT_F_TYPE_G          (1 << 8)
409#define PRINT_F_TYPE_E          (1 << 9)
410
411/* Conversion flags. */
412#define PRINT_C_CHAR            1
413#define PRINT_C_SHORT           2
414#define PRINT_C_LONG            3
415#define PRINT_C_LLONG           4
416#define PRINT_C_LDOUBLE         5
417#define PRINT_C_SIZE            6
418#define PRINT_C_PTRDIFF         7
419#define PRINT_C_INTMAX          8
420
421#ifndef MAX
422#define MAX(x, y) ((x >= y) ? x : y)
423#endif	/* !defined(MAX) */
424#ifndef CHARTOINT
425#define CHARTOINT(ch) (ch - '0')
426#endif	/* !defined(CHARTOINT) */
427#ifndef ISDIGIT
428#define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9')
429#endif	/* !defined(ISDIGIT) */
430#ifndef ISNAN
431#define ISNAN(x) (x != x)
432#endif	/* !defined(ISNAN) */
433#ifndef ISINF
434#define ISINF(x) (x != 0.0 && x + x == x)
435#endif	/* !defined(ISINF) */
436
437#ifdef OUTCHAR
438#undef OUTCHAR
439#endif	/* defined(OUTCHAR) */
440#define OUTCHAR(str, len, size, ch)                                          \
441do {                                                                         \
442	if (len + 1 < size)                                                  \
443		str[len] = ch;                                               \
444	(len)++;                                                             \
445} while (/* CONSTCOND */ 0)
446
447static void fmtstr(char *, size_t *, size_t, const char *, int, int, int);
448static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int);
449static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *);
450static void printsep(char *, size_t *, size_t);
451static int getnumsep(int);
452static int getexponent(LDOUBLE);
453static int convert(UINTMAX_T, char *, size_t, int, int);
454static UINTMAX_T cast(LDOUBLE);
455static UINTMAX_T myround(LDOUBLE);
456static LDOUBLE mypow10(int);
457
458int
459util_vsnprintf(char *str, size_t size, const char *format, va_list args)
460{
461	LDOUBLE fvalue;
462	INTMAX_T value;
463	unsigned char cvalue;
464	const char *strvalue;
465	INTMAX_T *intmaxptr;
466	PTRDIFF_T *ptrdiffptr;
467	SSIZE_T *sizeptr;
468	LLONG *llongptr;
469	long int *longptr;
470	int *intptr;
471	short int *shortptr;
472	signed char *charptr;
473	size_t len = 0;
474	int overflow = 0;
475	int base = 0;
476	int cflags = 0;
477	int flags = 0;
478	int width = 0;
479	int precision = -1;
480	int state = PRINT_S_DEFAULT;
481	char ch = *format++;
482
483	/*
484	 * C99 says: "If `n' is zero, nothing is written, and `s' may be a null
485	 * pointer." (7.19.6.5, 2)  We're forgiving and allow a NULL pointer
486	 * even if a size larger than zero was specified.  At least NetBSD's
487	 * snprintf(3) does the same, as well as other versions of this file.
488	 * (Though some of these versions will write to a non-NULL buffer even
489	 * if a size of zero was specified, which violates the standard.)
490	 */
491	if (str == NULL && size != 0)
492		size = 0;
493
494	while (ch != '\0')
495		switch (state) {
496		case PRINT_S_DEFAULT:
497			if (ch == '%')
498				state = PRINT_S_FLAGS;
499			else
500				OUTCHAR(str, len, size, ch);
501			ch = *format++;
502			break;
503		case PRINT_S_FLAGS:
504			switch (ch) {
505			case '-':
506				flags |= PRINT_F_MINUS;
507				ch = *format++;
508				break;
509			case '+':
510				flags |= PRINT_F_PLUS;
511				ch = *format++;
512				break;
513			case ' ':
514				flags |= PRINT_F_SPACE;
515				ch = *format++;
516				break;
517			case '#':
518				flags |= PRINT_F_NUM;
519				ch = *format++;
520				break;
521			case '0':
522				flags |= PRINT_F_ZERO;
523				ch = *format++;
524				break;
525			case '\'':	/* SUSv2 flag (not in C99). */
526				flags |= PRINT_F_QUOTE;
527				ch = *format++;
528				break;
529			default:
530				state = PRINT_S_WIDTH;
531				break;
532			}
533			break;
534		case PRINT_S_WIDTH:
535			if (ISDIGIT(ch)) {
536				ch = CHARTOINT(ch);
537				if (width > (INT_MAX - ch) / 10) {
538					overflow = 1;
539					goto out;
540				}
541				width = 10 * width + ch;
542				ch = *format++;
543			} else if (ch == '*') {
544				/*
545				 * C99 says: "A negative field width argument is
546				 * taken as a `-' flag followed by a positive
547				 * field width." (7.19.6.1, 5)
548				 */
549				if ((width = va_arg(args, int)) < 0) {
550					flags |= PRINT_F_MINUS;
551					width = -width;
552				}
553				ch = *format++;
554				state = PRINT_S_DOT;
555			} else
556				state = PRINT_S_DOT;
557			break;
558		case PRINT_S_DOT:
559			if (ch == '.') {
560				state = PRINT_S_PRECISION;
561				ch = *format++;
562			} else
563				state = PRINT_S_MOD;
564			break;
565		case PRINT_S_PRECISION:
566			if (precision == -1)
567				precision = 0;
568			if (ISDIGIT(ch)) {
569				ch = CHARTOINT(ch);
570				if (precision > (INT_MAX - ch) / 10) {
571					overflow = 1;
572					goto out;
573				}
574				precision = 10 * precision + ch;
575				ch = *format++;
576			} else if (ch == '*') {
577				/*
578				 * C99 says: "A negative precision argument is
579				 * taken as if the precision were omitted."
580				 * (7.19.6.1, 5)
581				 */
582				if ((precision = va_arg(args, int)) < 0)
583					precision = -1;
584				ch = *format++;
585				state = PRINT_S_MOD;
586			} else
587				state = PRINT_S_MOD;
588			break;
589		case PRINT_S_MOD:
590			switch (ch) {
591			case 'h':
592				ch = *format++;
593				if (ch == 'h') {	/* It's a char. */
594					ch = *format++;
595					cflags = PRINT_C_CHAR;
596				} else
597					cflags = PRINT_C_SHORT;
598				break;
599			case 'l':
600				ch = *format++;
601				if (ch == 'l') {	/* It's a long long. */
602					ch = *format++;
603					cflags = PRINT_C_LLONG;
604				} else
605					cflags = PRINT_C_LONG;
606				break;
607			case 'L':
608				cflags = PRINT_C_LDOUBLE;
609				ch = *format++;
610				break;
611			case 'j':
612				cflags = PRINT_C_INTMAX;
613				ch = *format++;
614				break;
615			case 't':
616				cflags = PRINT_C_PTRDIFF;
617				ch = *format++;
618				break;
619			case 'z':
620				cflags = PRINT_C_SIZE;
621				ch = *format++;
622				break;
623			}
624			state = PRINT_S_CONV;
625			break;
626		case PRINT_S_CONV:
627			switch (ch) {
628			case 'd':
629				/* FALLTHROUGH */
630			case 'i':
631				switch (cflags) {
632				case PRINT_C_CHAR:
633					value = (signed char)va_arg(args, int);
634					break;
635				case PRINT_C_SHORT:
636					value = (short int)va_arg(args, int);
637					break;
638				case PRINT_C_LONG:
639					value = va_arg(args, long int);
640					break;
641				case PRINT_C_LLONG:
642					value = va_arg(args, LLONG);
643					break;
644				case PRINT_C_SIZE:
645					value = va_arg(args, SSIZE_T);
646					break;
647				case PRINT_C_INTMAX:
648					value = va_arg(args, INTMAX_T);
649					break;
650				case PRINT_C_PTRDIFF:
651					value = va_arg(args, PTRDIFF_T);
652					break;
653				default:
654					value = va_arg(args, int);
655					break;
656				}
657				fmtint(str, &len, size, value, 10, width,
658				    precision, flags);
659				break;
660			case 'X':
661				flags |= PRINT_F_UP;
662				/* FALLTHROUGH */
663			case 'x':
664				base = 16;
665				/* FALLTHROUGH */
666			case 'o':
667				if (base == 0)
668					base = 8;
669				/* FALLTHROUGH */
670			case 'u':
671				if (base == 0)
672					base = 10;
673				flags |= PRINT_F_UNSIGNED;
674				switch (cflags) {
675				case PRINT_C_CHAR:
676					value = (unsigned char)va_arg(args,
677					    unsigned int);
678					break;
679				case PRINT_C_SHORT:
680					value = (unsigned short int)va_arg(args,
681					    unsigned int);
682					break;
683				case PRINT_C_LONG:
684					value = va_arg(args, unsigned long int);
685					break;
686				case PRINT_C_LLONG:
687					value = va_arg(args, ULLONG);
688					break;
689				case PRINT_C_SIZE:
690					value = va_arg(args, size_t);
691					break;
692				case PRINT_C_INTMAX:
693					value = va_arg(args, UINTMAX_T);
694					break;
695				case PRINT_C_PTRDIFF:
696					value = va_arg(args, UPTRDIFF_T);
697					break;
698				default:
699					value = va_arg(args, unsigned int);
700					break;
701				}
702				fmtint(str, &len, size, value, base, width,
703				    precision, flags);
704				break;
705			case 'A':
706				/* Not yet supported, we'll use "%F". */
707				/* FALLTHROUGH */
708			case 'F':
709				flags |= PRINT_F_UP;
710			case 'a':
711				/* Not yet supported, we'll use "%f". */
712				/* FALLTHROUGH */
713			case 'f':
714				if (cflags == PRINT_C_LDOUBLE)
715					fvalue = va_arg(args, LDOUBLE);
716				else
717					fvalue = va_arg(args, double);
718				fmtflt(str, &len, size, fvalue, width,
719				    precision, flags, &overflow);
720				if (overflow)
721					goto out;
722				break;
723			case 'E':
724				flags |= PRINT_F_UP;
725				/* FALLTHROUGH */
726			case 'e':
727				flags |= PRINT_F_TYPE_E;
728				if (cflags == PRINT_C_LDOUBLE)
729					fvalue = va_arg(args, LDOUBLE);
730				else
731					fvalue = va_arg(args, double);
732				fmtflt(str, &len, size, fvalue, width,
733				    precision, flags, &overflow);
734				if (overflow)
735					goto out;
736				break;
737			case 'G':
738				flags |= PRINT_F_UP;
739				/* FALLTHROUGH */
740			case 'g':
741				flags |= PRINT_F_TYPE_G;
742				if (cflags == PRINT_C_LDOUBLE)
743					fvalue = va_arg(args, LDOUBLE);
744				else
745					fvalue = va_arg(args, double);
746				/*
747				 * If the precision is zero, it is treated as
748				 * one (cf. C99: 7.19.6.1, 8).
749				 */
750				if (precision == 0)
751					precision = 1;
752				fmtflt(str, &len, size, fvalue, width,
753				    precision, flags, &overflow);
754				if (overflow)
755					goto out;
756				break;
757			case 'c':
758				cvalue = (unsigned char)va_arg(args, int);
759				OUTCHAR(str, len, size, cvalue);
760				break;
761			case 's':
762				strvalue = va_arg(args, char *);
763				fmtstr(str, &len, size, strvalue, width,
764				    precision, flags);
765				break;
766			case 'p':
767				/*
768				 * C99 says: "The value of the pointer is
769				 * converted to a sequence of printing
770				 * characters, in an implementation-defined
771				 * manner." (C99: 7.19.6.1, 8)
772				 */
773				if ((strvalue = va_arg(args, void *)) == NULL)
774					/*
775					 * We use the glibc format.  BSD prints
776					 * "0x0", SysV "0".
777					 */
778					fmtstr(str, &len, size, "(nil)", width,
779					    -1, flags);
780				else {
781					/*
782					 * We use the BSD/glibc format.  SysV
783					 * omits the "0x" prefix (which we emit
784					 * using the PRINT_F_NUM flag).
785					 */
786					flags |= PRINT_F_NUM;
787					flags |= PRINT_F_UNSIGNED;
788					fmtint(str, &len, size,
789					    (UINTPTR_T)strvalue, 16, width,
790					    precision, flags);
791				}
792				break;
793			case 'n':
794				switch (cflags) {
795				case PRINT_C_CHAR:
796					charptr = va_arg(args, signed char *);
797					*charptr = (signed char)len;
798					break;
799				case PRINT_C_SHORT:
800					shortptr = va_arg(args, short int *);
801					*shortptr = (short int)len;
802					break;
803				case PRINT_C_LONG:
804					longptr = va_arg(args, long int *);
805					*longptr = (long int)len;
806					break;
807				case PRINT_C_LLONG:
808					llongptr = va_arg(args, LLONG *);
809					*llongptr = (LLONG)len;
810					break;
811				case PRINT_C_SIZE:
812					/*
813					 * C99 says that with the "z" length
814					 * modifier, "a following `n' conversion
815					 * specifier applies to a pointer to a
816					 * signed integer type corresponding to
817					 * size_t argument." (7.19.6.1, 7)
818					 */
819					sizeptr = va_arg(args, SSIZE_T *);
820					*sizeptr = len;
821					break;
822				case PRINT_C_INTMAX:
823					intmaxptr = va_arg(args, INTMAX_T *);
824					*intmaxptr = len;
825					break;
826				case PRINT_C_PTRDIFF:
827					ptrdiffptr = va_arg(args, PTRDIFF_T *);
828					*ptrdiffptr = len;
829					break;
830				default:
831					intptr = va_arg(args, int *);
832					*intptr = (int)len;
833					break;
834				}
835				break;
836			case '%':	/* Print a "%" character verbatim. */
837				OUTCHAR(str, len, size, ch);
838				break;
839			default:	/* Skip other characters. */
840				break;
841			}
842			ch = *format++;
843			state = PRINT_S_DEFAULT;
844			base = cflags = flags = width = 0;
845			precision = -1;
846			break;
847		}
848out:
849	if (len < size)
850		str[len] = '\0';
851	else if (size > 0)
852		str[size - 1] = '\0';
853
854	if (overflow || len >= INT_MAX) {
855		return -1;
856	}
857	return (int)len;
858}
859
860static void
861fmtstr(char *str, size_t *len, size_t size, const char *value, int width,
862       int precision, int flags)
863{
864	int padlen, strln;	/* Amount to pad. */
865	int noprecision = (precision == -1);
866
867	if (value == NULL)	/* We're forgiving. */
868		value = "(null)";
869
870	/* If a precision was specified, don't read the string past it. */
871	for (strln = 0; value[strln] != '\0' &&
872	    (noprecision || strln < precision); strln++)
873		continue;
874
875	if ((padlen = width - strln) < 0)
876		padlen = 0;
877	if (flags & PRINT_F_MINUS)	/* Left justify. */
878		padlen = -padlen;
879
880	while (padlen > 0) {	/* Leading spaces. */
881		OUTCHAR(str, *len, size, ' ');
882		padlen--;
883	}
884	while (*value != '\0' && (noprecision || precision-- > 0)) {
885		OUTCHAR(str, *len, size, *value);
886		value++;
887	}
888	while (padlen < 0) {	/* Trailing spaces. */
889		OUTCHAR(str, *len, size, ' ');
890		padlen++;
891	}
892}
893
894static void
895fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width,
896       int precision, int flags)
897{
898	UINTMAX_T uvalue;
899	char iconvert[MAX_CONVERT_LENGTH];
900	char sign = 0;
901	char hexprefix = 0;
902	int spadlen = 0;	/* Amount to space pad. */
903	int zpadlen = 0;	/* Amount to zero pad. */
904	int pos;
905	int separators = (flags & PRINT_F_QUOTE);
906	int noprecision = (precision == -1);
907
908	if (flags & PRINT_F_UNSIGNED)
909		uvalue = value;
910	else {
911		uvalue = (value >= 0) ? value : -value;
912		if (value < 0)
913			sign = '-';
914		else if (flags & PRINT_F_PLUS)	/* Do a sign. */
915			sign = '+';
916		else if (flags & PRINT_F_SPACE)
917			sign = ' ';
918	}
919
920	pos = convert(uvalue, iconvert, sizeof(iconvert), base,
921	    flags & PRINT_F_UP);
922
923	if (flags & PRINT_F_NUM && uvalue != 0) {
924		/*
925		 * C99 says: "The result is converted to an `alternative form'.
926		 * For `o' conversion, it increases the precision, if and only
927		 * if necessary, to force the first digit of the result to be a
928		 * zero (if the value and precision are both 0, a single 0 is
929		 * printed).  For `x' (or `X') conversion, a nonzero result has
930		 * `0x' (or `0X') prefixed to it." (7.19.6.1, 6)
931		 */
932		switch (base) {
933		case 8:
934			if (precision <= pos)
935				precision = pos + 1;
936			break;
937		case 16:
938			hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x';
939			break;
940		}
941	}
942
943	if (separators)	/* Get the number of group separators we'll print. */
944		separators = getnumsep(pos);
945
946	zpadlen = precision - pos - separators;
947	spadlen = width                         /* Minimum field width. */
948	    - separators                        /* Number of separators. */
949	    - MAX(precision, pos)               /* Number of integer digits. */
950	    - ((sign != 0) ? 1 : 0)             /* Will we print a sign? */
951	    - ((hexprefix != 0) ? 2 : 0);       /* Will we print a prefix? */
952
953	if (zpadlen < 0)
954		zpadlen = 0;
955	if (spadlen < 0)
956		spadlen = 0;
957
958	/*
959	 * C99 says: "If the `0' and `-' flags both appear, the `0' flag is
960	 * ignored.  For `d', `i', `o', `u', `x', and `X' conversions, if a
961	 * precision is specified, the `0' flag is ignored." (7.19.6.1, 6)
962	 */
963	if (flags & PRINT_F_MINUS)	/* Left justify. */
964		spadlen = -spadlen;
965	else if (flags & PRINT_F_ZERO && noprecision) {
966		zpadlen += spadlen;
967		spadlen = 0;
968	}
969	while (spadlen > 0) {	/* Leading spaces. */
970		OUTCHAR(str, *len, size, ' ');
971		spadlen--;
972	}
973	if (sign != 0)	/* Sign. */
974		OUTCHAR(str, *len, size, sign);
975	if (hexprefix != 0) {	/* A "0x" or "0X" prefix. */
976		OUTCHAR(str, *len, size, '0');
977		OUTCHAR(str, *len, size, hexprefix);
978	}
979	while (zpadlen > 0) {	/* Leading zeros. */
980		OUTCHAR(str, *len, size, '0');
981		zpadlen--;
982	}
983	while (pos > 0) {	/* The actual digits. */
984		pos--;
985		OUTCHAR(str, *len, size, iconvert[pos]);
986		if (separators > 0 && pos > 0 && pos % 3 == 0)
987			printsep(str, len, size);
988	}
989	while (spadlen < 0) {	/* Trailing spaces. */
990		OUTCHAR(str, *len, size, ' ');
991		spadlen++;
992	}
993}
994
995static void
996fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width,
997       int precision, int flags, int *overflow)
998{
999	LDOUBLE ufvalue;
1000	UINTMAX_T intpart;
1001	UINTMAX_T fracpart;
1002	UINTMAX_T mask;
1003	const char *infnan = NULL;
1004	char iconvert[MAX_CONVERT_LENGTH];
1005	char fconvert[MAX_CONVERT_LENGTH];
1006	char econvert[4];	/* "e-12" (without nul-termination). */
1007	char esign = 0;
1008	char sign = 0;
1009	int leadfraczeros = 0;
1010	int exponent = 0;
1011	int emitpoint = 0;
1012	int omitzeros = 0;
1013	int omitcount = 0;
1014	int padlen = 0;
1015	int epos = 0;
1016	int fpos = 0;
1017	int ipos = 0;
1018	int separators = (flags & PRINT_F_QUOTE);
1019	int estyle = (flags & PRINT_F_TYPE_E);
1020#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT
1021	struct lconv *lc = localeconv();
1022#endif	/* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */
1023
1024	/*
1025	 * AIX' man page says the default is 0, but C99 and at least Solaris'
1026	 * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX
1027	 * defaults to 6.
1028	 */
1029	if (precision == -1)
1030		precision = 6;
1031
1032	if (fvalue < 0.0)
1033		sign = '-';
1034	else if (flags & PRINT_F_PLUS)	/* Do a sign. */
1035		sign = '+';
1036	else if (flags & PRINT_F_SPACE)
1037		sign = ' ';
1038
1039	if (ISNAN(fvalue))
1040		infnan = (flags & PRINT_F_UP) ? "NAN" : "nan";
1041	else if (ISINF(fvalue))
1042		infnan = (flags & PRINT_F_UP) ? "INF" : "inf";
1043
1044	if (infnan != NULL) {
1045		if (sign != 0)
1046			iconvert[ipos++] = sign;
1047		while (*infnan != '\0')
1048			iconvert[ipos++] = *infnan++;
1049		fmtstr(str, len, size, iconvert, width, ipos, flags);
1050		return;
1051	}
1052
1053	/* "%e" (or "%E") or "%g" (or "%G") conversion. */
1054	if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) {
1055		if (flags & PRINT_F_TYPE_G) {
1056			/*
1057			 * For "%g" (and "%G") conversions, the precision
1058			 * specifies the number of significant digits, which
1059			 * includes the digits in the integer part.  The
1060			 * conversion will or will not be using "e-style" (like
1061			 * "%e" or "%E" conversions) depending on the precision
1062			 * and on the exponent.  However, the exponent can be
1063			 * affected by rounding the converted value, so we'll
1064			 * leave this decision for later.  Until then, we'll
1065			 * assume that we're going to do an "e-style" conversion
1066			 * (in order to get the exponent calculated).  For
1067			 * "e-style", the precision must be decremented by one.
1068			 */
1069			precision--;
1070			/*
1071			 * For "%g" (and "%G") conversions, trailing zeros are
1072			 * removed from the fractional portion of the result
1073			 * unless the "#" flag was specified.
1074			 */
1075			if (!(flags & PRINT_F_NUM))
1076				omitzeros = 1;
1077		}
1078		exponent = getexponent(fvalue);
1079		estyle = 1;
1080	}
1081
1082again:
1083	/*
1084	 * Sorry, we only support 9, 19, or 38 digits (that is, the number of
1085	 * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value
1086	 * minus one) past the decimal point due to our conversion method.
1087	 */
1088	switch (sizeof(UINTMAX_T)) {
1089	case 16:
1090		if (precision > 38)
1091			precision = 38;
1092		break;
1093	case 8:
1094		if (precision > 19)
1095			precision = 19;
1096		break;
1097	default:
1098		if (precision > 9)
1099			precision = 9;
1100		break;
1101	}
1102
1103	ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue;
1104	if (estyle)	/* We want exactly one integer digit. */
1105		ufvalue /= mypow10(exponent);
1106
1107	if ((intpart = cast(ufvalue)) == UINTMAX_MAX) {
1108		*overflow = 1;
1109		return;
1110	}
1111
1112	/*
1113	 * Factor of ten with the number of digits needed for the fractional
1114	 * part.  For example, if the precision is 3, the mask will be 1000.
1115	 */
1116	mask = (UINTMAX_T)mypow10(precision);
1117	/*
1118	 * We "cheat" by converting the fractional part to integer by
1119	 * multiplying by a factor of ten.
1120	 */
1121	if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) {
1122		/*
1123		 * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000
1124		 * (because precision = 3).  Now, myround(1000 * 0.99962) will
1125		 * return 1000.  So, the integer part must be incremented by one
1126		 * and the fractional part must be set to zero.
1127		 */
1128		intpart++;
1129		fracpart = 0;
1130		if (estyle && intpart == 10) {
1131			/*
1132			 * The value was rounded up to ten, but we only want one
1133			 * integer digit if using "e-style".  So, the integer
1134			 * part must be set to one and the exponent must be
1135			 * incremented by one.
1136			 */
1137			intpart = 1;
1138			exponent++;
1139		}
1140	}
1141
1142	/*
1143	 * Now that we know the real exponent, we can check whether or not to
1144	 * use "e-style" for "%g" (and "%G") conversions.  If we don't need
1145	 * "e-style", the precision must be adjusted and the integer and
1146	 * fractional parts must be recalculated from the original value.
1147	 *
1148	 * C99 says: "Let P equal the precision if nonzero, 6 if the precision
1149	 * is omitted, or 1 if the precision is zero.  Then, if a conversion
1150	 * with style `E' would have an exponent of X:
1151	 *
1152	 * - if P > X >= -4, the conversion is with style `f' (or `F') and
1153	 *   precision P - (X + 1).
1154	 *
1155	 * - otherwise, the conversion is with style `e' (or `E') and precision
1156	 *   P - 1." (7.19.6.1, 8)
1157	 *
1158	 * Note that we had decremented the precision by one.
1159	 */
1160	if (flags & PRINT_F_TYPE_G && estyle &&
1161	    precision + 1 > exponent && exponent >= -4) {
1162		precision -= exponent;
1163		estyle = 0;
1164		goto again;
1165	}
1166
1167	if (estyle) {
1168		if (exponent < 0) {
1169			exponent = -exponent;
1170			esign = '-';
1171		} else
1172			esign = '+';
1173
1174		/*
1175		 * Convert the exponent.  The sizeof(econvert) is 4.  So, the
1176		 * econvert buffer can hold e.g. "e+99" and "e-99".  We don't
1177		 * support an exponent which contains more than two digits.
1178		 * Therefore, the following stores are safe.
1179		 */
1180		epos = convert(exponent, econvert, 2, 10, 0);
1181		/*
1182		 * C99 says: "The exponent always contains at least two digits,
1183		 * and only as many more digits as necessary to represent the
1184		 * exponent." (7.19.6.1, 8)
1185		 */
1186		if (epos == 1)
1187			econvert[epos++] = '0';
1188		econvert[epos++] = esign;
1189		econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e';
1190	}
1191
1192	/* Convert the integer part and the fractional part. */
1193	ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0);
1194	if (fracpart != 0)	/* convert() would return 1 if fracpart == 0. */
1195		fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0);
1196
1197	leadfraczeros = precision - fpos;
1198
1199	if (omitzeros) {
1200		if (fpos > 0)	/* Omit trailing fractional part zeros. */
1201			while (omitcount < fpos && fconvert[omitcount] == '0')
1202				omitcount++;
1203		else {	/* The fractional part is zero, omit it completely. */
1204			omitcount = precision;
1205			leadfraczeros = 0;
1206		}
1207		precision -= omitcount;
1208	}
1209
1210	/*
1211	 * Print a decimal point if either the fractional part is non-zero
1212	 * and/or the "#" flag was specified.
1213	 */
1214	if (precision > 0 || flags & PRINT_F_NUM)
1215		emitpoint = 1;
1216	if (separators)	/* Get the number of group separators we'll print. */
1217		separators = getnumsep(ipos);
1218
1219	padlen = width                  /* Minimum field width. */
1220	    - ipos                      /* Number of integer digits. */
1221	    - epos                      /* Number of exponent characters. */
1222	    - precision                 /* Number of fractional digits. */
1223	    - separators                /* Number of group separators. */
1224	    - (emitpoint ? 1 : 0)       /* Will we print a decimal point? */
1225	    - ((sign != 0) ? 1 : 0);    /* Will we print a sign character? */
1226
1227	if (padlen < 0)
1228		padlen = 0;
1229
1230	/*
1231	 * C99 says: "If the `0' and `-' flags both appear, the `0' flag is
1232	 * ignored." (7.19.6.1, 6)
1233	 */
1234	if (flags & PRINT_F_MINUS)	/* Left justifty. */
1235		padlen = -padlen;
1236	else if (flags & PRINT_F_ZERO && padlen > 0) {
1237		if (sign != 0) {	/* Sign. */
1238			OUTCHAR(str, *len, size, sign);
1239			sign = 0;
1240		}
1241		while (padlen > 0) {	/* Leading zeros. */
1242			OUTCHAR(str, *len, size, '0');
1243			padlen--;
1244		}
1245	}
1246	while (padlen > 0) {	/* Leading spaces. */
1247		OUTCHAR(str, *len, size, ' ');
1248		padlen--;
1249	}
1250	if (sign != 0)	/* Sign. */
1251		OUTCHAR(str, *len, size, sign);
1252	while (ipos > 0) {	/* Integer part. */
1253		ipos--;
1254		OUTCHAR(str, *len, size, iconvert[ipos]);
1255		if (separators > 0 && ipos > 0 && ipos % 3 == 0)
1256			printsep(str, len, size);
1257	}
1258	if (emitpoint) {	/* Decimal point. */
1259#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT
1260		if (lc->decimal_point != NULL && *lc->decimal_point != '\0')
1261			OUTCHAR(str, *len, size, *lc->decimal_point);
1262		else	/* We'll always print some decimal point character. */
1263#endif	/* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */
1264			OUTCHAR(str, *len, size, '.');
1265	}
1266	while (leadfraczeros > 0) {	/* Leading fractional part zeros. */
1267		OUTCHAR(str, *len, size, '0');
1268		leadfraczeros--;
1269	}
1270	while (fpos > omitcount) {	/* The remaining fractional part. */
1271		fpos--;
1272		OUTCHAR(str, *len, size, fconvert[fpos]);
1273	}
1274	while (epos > 0) {	/* Exponent. */
1275		epos--;
1276		OUTCHAR(str, *len, size, econvert[epos]);
1277	}
1278	while (padlen < 0) {	/* Trailing spaces. */
1279		OUTCHAR(str, *len, size, ' ');
1280		padlen++;
1281	}
1282}
1283
1284static void
1285printsep(char *str, size_t *len, size_t size)
1286{
1287#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP
1288	struct lconv *lc = localeconv();
1289	int i;
1290
1291	if (lc->thousands_sep != NULL)
1292		for (i = 0; lc->thousands_sep[i] != '\0'; i++)
1293			OUTCHAR(str, *len, size, lc->thousands_sep[i]);
1294	else
1295#endif	/* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */
1296		OUTCHAR(str, *len, size, ',');
1297}
1298
1299static int
1300getnumsep(int digits)
1301{
1302	int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3;
1303#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP
1304	int strln;
1305	struct lconv *lc = localeconv();
1306
1307	/* We support an arbitrary separator length (including zero). */
1308	if (lc->thousands_sep != NULL) {
1309		for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++)
1310			continue;
1311		separators *= strln;
1312	}
1313#endif	/* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */
1314	return separators;
1315}
1316
1317static int
1318getexponent(LDOUBLE value)
1319{
1320	LDOUBLE tmp = (value >= 0.0) ? value : -value;
1321	int exponent = 0;
1322
1323	/*
1324	 * We check for 99 > exponent > -99 in order to work around possible
1325	 * endless loops which could happen (at least) in the second loop (at
1326	 * least) if we're called with an infinite value.  However, we checked
1327	 * for infinity before calling this function using our ISINF() macro, so
1328	 * this might be somewhat paranoid.
1329	 */
1330	while (tmp < 1.0 && tmp > 0.0 && --exponent > -99)
1331		tmp *= 10;
1332	while (tmp >= 10.0 && ++exponent < 99)
1333		tmp /= 10;
1334
1335	return exponent;
1336}
1337
1338static int
1339convert(UINTMAX_T value, char *buf, size_t size, int base, int caps)
1340{
1341	const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef";
1342	size_t pos = 0;
1343
1344	/* We return an unterminated buffer with the digits in reverse order. */
1345	do {
1346		buf[pos++] = digits[value % base];
1347		value /= base;
1348	} while (value != 0 && pos < size);
1349
1350	return (int)pos;
1351}
1352
1353static UINTMAX_T
1354cast(LDOUBLE value)
1355{
1356	UINTMAX_T result;
1357
1358	/*
1359	 * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be
1360	 * represented exactly as an LDOUBLE value (but is less than LDBL_MAX),
1361	 * it may be increased to the nearest higher representable value for the
1362	 * comparison (cf. C99: 6.3.1.4, 2).  It might then equal the LDOUBLE
1363	 * value although converting the latter to UINTMAX_T would overflow.
1364	 */
1365	if (value >= UINTMAX_MAX)
1366		return UINTMAX_MAX;
1367
1368	result = (UINTMAX_T)value;
1369	/*
1370	 * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to
1371	 * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates
1372	 * the standard).  Sigh.
1373	 */
1374	return (result <= value) ? result : result - 1;
1375}
1376
1377static UINTMAX_T
1378myround(LDOUBLE value)
1379{
1380	UINTMAX_T intpart = cast(value);
1381
1382	return ((value -= intpart) < 0.5) ? intpart : intpart + 1;
1383}
1384
1385static LDOUBLE
1386mypow10(int exponent)
1387{
1388	LDOUBLE result = 1;
1389
1390	while (exponent > 0) {
1391		result *= 10;
1392		exponent--;
1393	}
1394	while (exponent < 0) {
1395		result /= 10;
1396		exponent++;
1397	}
1398	return result;
1399}
1400#endif	/* !HAVE_VSNPRINTF */
1401
1402#if !HAVE_VASPRINTF
1403#if NEED_MYMEMCPY
1404void *
1405mymemcpy(void *dst, void *src, size_t len)
1406{
1407	const char *from = src;
1408	char *to = dst;
1409
1410	/* No need for optimization, we use this only to replace va_copy(3). */
1411	while (len-- > 0)
1412		*to++ = *from++;
1413	return dst;
1414}
1415#endif	/* NEED_MYMEMCPY */
1416
1417int
1418util_vasprintf(char **ret, const char *format, va_list ap)
1419{
1420	size_t size;
1421	int len;
1422	va_list aq;
1423
1424	VA_COPY(aq, ap);
1425	len = vsnprintf(NULL, 0, format, aq);
1426	VA_END_COPY(aq);
1427	if (len < 0 || (*ret = malloc(size = len + 1)) == NULL)
1428		return -1;
1429	return vsnprintf(*ret, size, format, ap);
1430}
1431#endif	/* !HAVE_VASPRINTF */
1432
1433#if !HAVE_SNPRINTF
1434#if HAVE_STDARG_H
1435int
1436util_snprintf(char *str, size_t size, const char *format, ...)
1437#else
1438int
1439util_snprintf(va_alist) va_dcl
1440#endif	/* HAVE_STDARG_H */
1441{
1442#if !HAVE_STDARG_H
1443	char *str;
1444	size_t size;
1445	char *format;
1446#endif	/* HAVE_STDARG_H */
1447	va_list ap;
1448	int len;
1449
1450	VA_START(ap, format);
1451	VA_SHIFT(ap, str, char *);
1452	VA_SHIFT(ap, size, size_t);
1453	VA_SHIFT(ap, format, const char *);
1454	len = vsnprintf(str, size, format, ap);
1455	va_end(ap);
1456	return len;
1457}
1458#endif	/* !HAVE_SNPRINTF */
1459
1460#if !HAVE_ASPRINTF
1461#if HAVE_STDARG_H
1462int
1463util_asprintf(char **ret, const char *format, ...)
1464#else
1465int
1466util_asprintf(va_alist) va_dcl
1467#endif	/* HAVE_STDARG_H */
1468{
1469#if !HAVE_STDARG_H
1470	char **ret;
1471	char *format;
1472#endif	/* HAVE_STDARG_H */
1473	va_list ap;
1474	int len;
1475
1476	VA_START(ap, format);
1477	VA_SHIFT(ap, ret, char **);
1478	VA_SHIFT(ap, format, const char *);
1479	len = vasprintf(ret, format, ap);
1480	va_end(ap);
1481	return len;
1482}
1483#endif	/* !HAVE_ASPRINTF */
1484#else	/* Dummy declaration to avoid empty translation unit warnings. */
1485int main(void);
1486#endif	/* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */
1487
1488
1489/* vim: set joinspaces textwidth=80: */
1490