• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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
util_vsnprintf(char * str,size_t size,const char * format,va_list args)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
fmtstr(char * str,size_t * len,size_t size,const char * value,int width,int precision,int flags)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
fmtint(char * str,size_t * len,size_t size,INTMAX_T value,int base,int width,int precision,int flags)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
fmtflt(char * str,size_t * len,size_t size,LDOUBLE fvalue,int width,int precision,int flags,int * overflow)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
printsep(char * str,size_t * len,size_t size)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
getnumsep(int digits)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
getexponent(LDOUBLE value)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
convert(UINTMAX_T value,char * buf,size_t size,int base,int caps)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
cast(LDOUBLE value)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
myround(LDOUBLE value)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
mypow10(int exponent)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 *
mymemcpy(void * dst,void * src,size_t len)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
util_vasprintf(char ** ret,const char * format,va_list ap)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
util_snprintf(char * str,size_t size,const char * format,...)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
util_asprintf(char ** ret,const char * format,...)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