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