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