Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (c) 1995 Patrick Powell.
      3  *
      4  * This code is based on code written by Patrick Powell <papowell (at) 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 (at) 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 (at) 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 (at) 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 (at) samba.org>, Russ Allbery
     33  * 	<rra (at) stanford.edu>, Hrvoje Niksic <hniksic (at) xemacs.org>, Damien Miller
     34  * 	<djm (at) 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 (at) 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 (at) 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 (at) 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 (at) 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 (at) 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
    241 static 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)                                          \
    441 do {                                                                         \
    442 	if (len + 1 < size)                                                  \
    443 		str[len] = ch;                                               \
    444 	(len)++;                                                             \
    445 } while (/* CONSTCOND */ 0)
    446 
    447 static void fmtstr(char *, size_t *, size_t, const char *, int, int, int);
    448 static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int);
    449 static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *);
    450 static void printsep(char *, size_t *, size_t);
    451 static int getnumsep(int);
    452 static int getexponent(LDOUBLE);
    453 static int convert(UINTMAX_T, char *, size_t, int, int);
    454 static UINTMAX_T cast(LDOUBLE);
    455 static UINTMAX_T myround(LDOUBLE);
    456 static LDOUBLE mypow10(int);
    457 
    458 int
    459 util_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 		}
    848 out:
    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 
    860 static void
    861 fmtstr(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 
    894 static void
    895 fmtint(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 
    995 static void
    996 fmtflt(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 
   1082 again:
   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 
   1284 static void
   1285 printsep(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 
   1299 static int
   1300 getnumsep(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 
   1317 static int
   1318 getexponent(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 
   1338 static int
   1339 convert(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 
   1353 static UINTMAX_T
   1354 cast(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 
   1377 static UINTMAX_T
   1378 myround(LDOUBLE value)
   1379 {
   1380 	UINTMAX_T intpart = cast(value);
   1381 
   1382 	return ((value -= intpart) < 0.5) ? intpart : intpart + 1;
   1383 }
   1384 
   1385 static LDOUBLE
   1386 mypow10(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
   1404 void *
   1405 mymemcpy(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 
   1417 int
   1418 util_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
   1435 int
   1436 util_snprintf(char *str, size_t size, const char *format, ...)
   1437 #else
   1438 int
   1439 util_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
   1462 int
   1463 util_asprintf(char **ret, const char *format, ...)
   1464 #else
   1465 int
   1466 util_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. */
   1485 int main(void);
   1486 #endif	/* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */
   1487 
   1488 
   1489 /* vim: set joinspaces textwidth=80: */
   1490