Tizen 2.1 base
[sdk/emulator/qemu.git] / gl / mesa / src / gallium / auxiliary / util / u_snprintf.c
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
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: */