root/maint/gnulib/lib/vasnprintf.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. local_strnlen
  2. local_wcslen
  3. local_wcsnlen
  4. wctomb_fallback
  5. local_wcrtomb
  6. local_wctomb
  7. decimal_point_char
  8. is_infinite_or_zero
  9. is_infinite_or_zerol
  10. multiply
  11. divide
  12. convert_to_decimal
  13. decode_long_double
  14. decode_double
  15. scale10_round_decimal_decoded
  16. scale10_round_decimal_long_double
  17. scale10_round_decimal_double
  18. floorlog10l
  19. floorlog10
  20. is_borderline
  21. MAX_ROOM_NEEDED
  22. VASNPRINTF

   1 /* vsprintf with automatic memory allocation.
   2    Copyright (C) 1999, 2002-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* This file can be parametrized with the following macros:
  18      VASNPRINTF         The name of the function being defined.
  19      FCHAR_T            The element type of the format string.
  20      DCHAR_T            The element type of the destination (result) string.
  21      FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
  22                         in the format string are ASCII. MUST be set if
  23                         FCHAR_T and DCHAR_T are not the same type.
  24      DIRECTIVE          Structure denoting a format directive.
  25                         Depends on FCHAR_T.
  26      DIRECTIVES         Structure denoting the set of format directives of a
  27                         format string.  Depends on FCHAR_T.
  28      PRINTF_PARSE       Function that parses a format string.
  29                         Depends on FCHAR_T.
  30      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
  31      DCHAR_SET          memset like function for DCHAR_T[] arrays.
  32      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
  33      SNPRINTF           The system's snprintf (or similar) function.
  34                         This may be either snprintf or swprintf.
  35      TCHAR_T            The element type of the argument and result string
  36                         of the said SNPRINTF function.  This may be either
  37                         char or wchar_t.  The code exploits that
  38                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
  39                         alignof (TCHAR_T) <= alignof (DCHAR_T).
  40      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
  41      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
  42      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
  43      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
  44      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.
  45      ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
  46      ENABLE_WCHAR_FALLBACK  Set to 1 to avoid EILSEQ during conversion of wide
  47                         characters (wchar_t) and wide character strings
  48                         (wchar_t[]) to multibyte sequences.  The fallback is the
  49                         hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or,
  50                         if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn.
  51  */
  52 
  53 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
  54    This must come before <config.h> because <config.h> may include
  55    <features.h>, and once <features.h> has been included, it's too late.  */
  56 #ifndef _GNU_SOURCE
  57 # define _GNU_SOURCE    1
  58 #endif
  59 
  60 #ifndef VASNPRINTF
  61 # include <config.h>
  62 #endif
  63 
  64 /* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's
  65    use of CHECK macros expands to code that is too complicated for gcc
  66    -fanalyzer.  Suppress the resulting bogus warnings.  */
  67 #if 10 <= __GNUC__
  68 # pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
  69 #endif
  70 
  71 #include <alloca.h>
  72 
  73 /* Specification.  */
  74 #ifndef VASNPRINTF
  75 # if WIDE_CHAR_VERSION
  76 #  include "vasnwprintf.h"
  77 # else
  78 #  include "vasnprintf.h"
  79 # endif
  80 #endif
  81 
  82 #include <locale.h>     /* localeconv() */
  83 #include <stdio.h>      /* snprintf(), sprintf() */
  84 #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
  85 #include <string.h>     /* memcpy(), strlen() */
  86 #include <errno.h>      /* errno */
  87 #include <limits.h>     /* CHAR_BIT */
  88 #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
  89 #if HAVE_NL_LANGINFO
  90 # include <langinfo.h>
  91 #endif
  92 #ifndef VASNPRINTF
  93 # if WIDE_CHAR_VERSION
  94 #  include "wprintf-parse.h"
  95 # else
  96 #  include "printf-parse.h"
  97 # endif
  98 #endif
  99 
 100 /* Checked size_t computations.  */
 101 #include "xsize.h"
 102 
 103 #include "attribute.h"
 104 #include "verify.h"
 105 
 106 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
 107 # include <math.h>
 108 # include "float+.h"
 109 #endif
 110 
 111 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
 112 # include <math.h>
 113 # include "isnand-nolibm.h"
 114 #endif
 115 
 116 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
 117 # include <math.h>
 118 # include "isnanl-nolibm.h"
 119 # include "fpucw.h"
 120 #endif
 121 
 122 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
 123 # include <math.h>
 124 # include "isnand-nolibm.h"
 125 # include "printf-frexp.h"
 126 #endif
 127 
 128 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
 129 # include <math.h>
 130 # include "isnanl-nolibm.h"
 131 # include "printf-frexpl.h"
 132 # include "fpucw.h"
 133 #endif
 134 
 135 /* Default parameters.  */
 136 #ifndef VASNPRINTF
 137 # if WIDE_CHAR_VERSION
 138 #  define VASNPRINTF vasnwprintf
 139 #  define FCHAR_T wchar_t
 140 #  define DCHAR_T wchar_t
 141 #  define TCHAR_T wchar_t
 142 #  define DCHAR_IS_TCHAR 1
 143 #  define DIRECTIVE wchar_t_directive
 144 #  define DIRECTIVES wchar_t_directives
 145 #  define PRINTF_PARSE wprintf_parse
 146 #  define DCHAR_CPY wmemcpy
 147 #  define DCHAR_SET wmemset
 148 # else
 149 #  define VASNPRINTF vasnprintf
 150 #  define FCHAR_T char
 151 #  define DCHAR_T char
 152 #  define TCHAR_T char
 153 #  define DCHAR_IS_TCHAR 1
 154 #  define DIRECTIVE char_directive
 155 #  define DIRECTIVES char_directives
 156 #  define PRINTF_PARSE printf_parse
 157 #  define DCHAR_CPY memcpy
 158 #  define DCHAR_SET memset
 159 # endif
 160 #endif
 161 #if WIDE_CHAR_VERSION
 162   /* TCHAR_T is wchar_t.  */
 163 # define USE_SNPRINTF 1
 164 # if HAVE_DECL__SNWPRINTF
 165    /* On Windows, the function swprintf() has a different signature than
 166       on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
 167       instead.  The mingw function snwprintf() has fewer bugs than the
 168       MSVCRT function _snwprintf(), so prefer that.  */
 169 #  if defined __MINGW32__
 170 #   define SNPRINTF snwprintf
 171 #  else
 172 #   define SNPRINTF _snwprintf
 173 #   define USE_MSVC__SNPRINTF 1
 174 #  endif
 175 # else
 176    /* Unix.  */
 177 #  define SNPRINTF swprintf
 178 # endif
 179 #else
 180   /* TCHAR_T is char.  */
 181   /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
 182      But don't use it on BeOS, since BeOS snprintf produces no output if the
 183      size argument is >= 0x3000000.
 184      Also don't use it on Linux libc5, since there snprintf with size = 1
 185      writes any output without bounds, like sprintf.  */
 186 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
 187 #  define USE_SNPRINTF 1
 188 # else
 189 #  define USE_SNPRINTF 0
 190 # endif
 191 # if HAVE_DECL__SNPRINTF
 192    /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
 193       function _snprintf(), so prefer that.  */
 194 #  if defined __MINGW32__
 195 #   define SNPRINTF snprintf
 196     /* Here we need to call the native snprintf, not rpl_snprintf.  */
 197 #   undef snprintf
 198 #  else
 199     /* MSVC versions < 14 did not have snprintf, only _snprintf.  */
 200 #   define SNPRINTF _snprintf
 201 #   define USE_MSVC__SNPRINTF 1
 202 #  endif
 203 # else
 204    /* Unix.  */
 205 #  define SNPRINTF snprintf
 206    /* Here we need to call the native snprintf, not rpl_snprintf.  */
 207 #  undef snprintf
 208 # endif
 209 #endif
 210 /* Here we need to call the native sprintf, not rpl_sprintf.  */
 211 #undef sprintf
 212 
 213 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
 214    warnings in this file.  Use -Dlint to suppress them.  */
 215 #if defined GCC_LINT || defined lint
 216 # define IF_LINT(Code) Code
 217 #else
 218 # define IF_LINT(Code) /* empty */
 219 #endif
 220 
 221 /* Avoid some warnings from "gcc -Wshadow".
 222    This file doesn't use the exp() and remainder() functions.  */
 223 #undef exp
 224 #define exp expo
 225 #undef remainder
 226 #define remainder rem
 227 
 228 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION
 229 # if (HAVE_STRNLEN && !defined _AIX)
 230 #  define local_strnlen strnlen
 231 # else
 232 #  ifndef local_strnlen_defined
 233 #   define local_strnlen_defined 1
 234 static size_t
 235 local_strnlen (const char *string, size_t maxlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 236 {
 237   const char *end = memchr (string, '\0', maxlen);
 238   return end ? (size_t) (end - string) : maxlen;
 239 }
 240 #  endif
 241 # endif
 242 #endif
 243 
 244 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
 245 # if HAVE_WCSLEN
 246 #  define local_wcslen wcslen
 247 # else
 248    /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
 249       a dependency towards this library, here is a local substitute.
 250       Define this substitute only once, even if this file is included
 251       twice in the same compilation unit.  */
 252 #  ifndef local_wcslen_defined
 253 #   define local_wcslen_defined 1
 254 static size_t
 255 local_wcslen (const wchar_t *s)
     /* [previous][next][first][last][top][bottom][index][help] */
 256 {
 257   const wchar_t *ptr;
 258 
 259   for (ptr = s; *ptr != (wchar_t) 0; ptr++)
 260     ;
 261   return ptr - s;
 262 }
 263 #  endif
 264 # endif
 265 #endif
 266 
 267 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
 268 # if HAVE_WCSNLEN
 269 #  define local_wcsnlen wcsnlen
 270 # else
 271 #  ifndef local_wcsnlen_defined
 272 #   define local_wcsnlen_defined 1
 273 static size_t
 274 local_wcsnlen (const wchar_t *s, size_t maxlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276   const wchar_t *ptr;
 277 
 278   for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
 279     ;
 280   return ptr - s;
 281 }
 282 #  endif
 283 # endif
 284 #endif
 285 
 286 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || (ENABLE_WCHAR_FALLBACK && HAVE_WINT_T)) && !WIDE_CHAR_VERSION
 287 # if ENABLE_WCHAR_FALLBACK
 288 static size_t
 289 wctomb_fallback (char *s, wchar_t wc)
     /* [previous][next][first][last][top][bottom][index][help] */
 290 {
 291   static char hex[16] = "0123456789ABCDEF";
 292 
 293   s[0] = '\\';
 294   if (sizeof (wchar_t) > 2 && wc > 0xffff)
 295     {
 296 #  if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
 297       s[1] = 'U';
 298 #  else
 299       s[1] = 'W';
 300 #  endif
 301       s[2] = hex[(wc & 0xf0000000U) >> 28];
 302       s[3] = hex[(wc & 0xf000000U) >> 24];
 303       s[4] = hex[(wc & 0xf00000U) >> 20];
 304       s[5] = hex[(wc & 0xf0000U) >> 16];
 305       s[6] = hex[(wc & 0xf000U) >> 12];
 306       s[7] = hex[(wc & 0xf00U) >> 8];
 307       s[8] = hex[(wc & 0xf0U) >> 4];
 308       s[9] = hex[wc & 0xfU];
 309       return 10;
 310     }
 311   else
 312     {
 313 #  if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
 314       s[1] = 'u';
 315 #  else
 316       s[1] = 'w';
 317 #  endif
 318       s[2] = hex[(wc & 0xf000U) >> 12];
 319       s[3] = hex[(wc & 0xf00U) >> 8];
 320       s[4] = hex[(wc & 0xf0U) >> 4];
 321       s[5] = hex[wc & 0xfU];
 322       return 6;
 323     }
 324 }
 325 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
 326 static size_t
 327 local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
     /* [previous][next][first][last][top][bottom][index][help] */
 328 {
 329   size_t count = wcrtomb (s, wc, ps);
 330   if (count == (size_t)(-1))
 331     count = wctomb_fallback (s, wc);
 332   return count;
 333 }
 334 #  else
 335 static int
 336 local_wctomb (char *s, wchar_t wc)
     /* [previous][next][first][last][top][bottom][index][help] */
 337 {
 338   int count = wctomb (s, wc);
 339   if (count < 0)
 340     count = wctomb_fallback (s, wc);
 341   return count;
 342 }
 343 #   define local_wcrtomb(S, WC, PS)  local_wctomb ((S), (WC))
 344 #  endif
 345 # else
 346 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
 347 #   define local_wcrtomb(S, WC, PS)  wcrtomb ((S), (WC), (PS))
 348 #  else
 349 #   define local_wcrtomb(S, WC, PS)  wctomb ((S), (WC))
 350 #  endif
 351 # endif
 352 #endif
 353 
 354 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
 355 /* Determine the decimal-point character according to the current locale.  */
 356 # ifndef decimal_point_char_defined
 357 #  define decimal_point_char_defined 1
 358 static char
 359 decimal_point_char (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 360 {
 361   const char *point;
 362   /* Determine it in a multithread-safe way.  We know nl_langinfo is
 363      multithread-safe on glibc systems and Mac OS X systems, but is not required
 364      to be multithread-safe by POSIX.  sprintf(), however, is multithread-safe.
 365      localeconv() is rarely multithread-safe.  */
 366 #  if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
 367   point = nl_langinfo (RADIXCHAR);
 368 #  elif 1
 369   char pointbuf[5];
 370   sprintf (pointbuf, "%#.0f", 1.0);
 371   point = &pointbuf[1];
 372 #  else
 373   point = localeconv () -> decimal_point;
 374 #  endif
 375   /* The decimal point is always a single byte: either '.' or ','.  */
 376   return (point[0] != '\0' ? point[0] : '.');
 377 }
 378 # endif
 379 #endif
 380 
 381 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
 382 
 383 /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
 384 static int
 385 is_infinite_or_zero (double x)
     /* [previous][next][first][last][top][bottom][index][help] */
 386 {
 387   return isnand (x) || x + x == x;
 388 }
 389 
 390 #endif
 391 
 392 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
 393 
 394 /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
 395 static int
 396 is_infinite_or_zerol (long double x)
     /* [previous][next][first][last][top][bottom][index][help] */
 397 {
 398   return isnanl (x) || x + x == x;
 399 }
 400 
 401 #endif
 402 
 403 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
 404 
 405 /* Converting 'long double' to decimal without rare rounding bugs requires
 406    real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
 407    (and slower) algorithms.  */
 408 
 409 typedef unsigned int mp_limb_t;
 410 # define GMP_LIMB_BITS 32
 411 verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
 412 
 413 typedef unsigned long long mp_twolimb_t;
 414 # define GMP_TWOLIMB_BITS 64
 415 verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
 416 
 417 /* Representation of a bignum >= 0.  */
 418 typedef struct
 419 {
 420   size_t nlimbs;
 421   mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  */
 422 } mpn_t;
 423 
 424 /* Compute the product of two bignums >= 0.
 425    Return the allocated memory in case of success, NULL in case of memory
 426    allocation failure.  */
 427 static void *
 428 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
     /* [previous][next][first][last][top][bottom][index][help] */
 429 {
 430   const mp_limb_t *p1;
 431   const mp_limb_t *p2;
 432   size_t len1;
 433   size_t len2;
 434 
 435   if (src1.nlimbs <= src2.nlimbs)
 436     {
 437       len1 = src1.nlimbs;
 438       p1 = src1.limbs;
 439       len2 = src2.nlimbs;
 440       p2 = src2.limbs;
 441     }
 442   else
 443     {
 444       len1 = src2.nlimbs;
 445       p1 = src2.limbs;
 446       len2 = src1.nlimbs;
 447       p2 = src1.limbs;
 448     }
 449   /* Now 0 <= len1 <= len2.  */
 450   if (len1 == 0)
 451     {
 452       /* src1 or src2 is zero.  */
 453       dest->nlimbs = 0;
 454       dest->limbs = (mp_limb_t *) malloc (1);
 455     }
 456   else
 457     {
 458       /* Here 1 <= len1 <= len2.  */
 459       size_t dlen;
 460       mp_limb_t *dp;
 461       size_t k, i, j;
 462 
 463       dlen = len1 + len2;
 464       dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
 465       if (dp == NULL)
 466         return NULL;
 467       for (k = len2; k > 0; )
 468         dp[--k] = 0;
 469       for (i = 0; i < len1; i++)
 470         {
 471           mp_limb_t digit1 = p1[i];
 472           mp_twolimb_t carry = 0;
 473           for (j = 0; j < len2; j++)
 474             {
 475               mp_limb_t digit2 = p2[j];
 476               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
 477               carry += dp[i + j];
 478               dp[i + j] = (mp_limb_t) carry;
 479               carry = carry >> GMP_LIMB_BITS;
 480             }
 481           dp[i + len2] = (mp_limb_t) carry;
 482         }
 483       /* Normalise.  */
 484       while (dlen > 0 && dp[dlen - 1] == 0)
 485         dlen--;
 486       dest->nlimbs = dlen;
 487       dest->limbs = dp;
 488     }
 489   return dest->limbs;
 490 }
 491 
 492 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
 493    a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
 494    the remainder.
 495    Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
 496    q is incremented.
 497    Return the allocated memory in case of success, NULL in case of memory
 498    allocation failure.  */
 499 static void *
 500 divide (mpn_t a, mpn_t b, mpn_t *q)
     /* [previous][next][first][last][top][bottom][index][help] */
 501 {
 502   /* Algorithm:
 503      First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
 504      with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
 505      If m<n, then q:=0 and r:=a.
 506      If m>=n=1, perform a single-precision division:
 507        r:=0, j:=m,
 508        while j>0 do
 509          {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
 510                = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
 511          j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
 512        Normalise [q[m-1],...,q[0]], yields q.
 513      If m>=n>1, perform a multiple-precision division:
 514        We have a/b < beta^(m-n+1).
 515        s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
 516        Shift a and b left by s bits, copying them. r:=a.
 517        r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
 518        For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
 519          Compute q* :
 520            q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
 521            In case of overflow (q* >= beta) set q* := beta-1.
 522            Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
 523            and c3 := b[n-2] * q*.
 524            {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
 525             occurred.  Furthermore 0 <= c3 < beta^2.
 526             If there was overflow and
 527             r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
 528             the next test can be skipped.}
 529            While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
 530              Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
 531            If q* > 0:
 532              Put r := r - b * q* * beta^j. In detail:
 533                [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
 534                hence: u:=0, for i:=0 to n-1 do
 535                               u := u + q* * b[i],
 536                               r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
 537                               u:=u div beta (+ 1, if carry in subtraction)
 538                       r[n+j]:=r[n+j]-u.
 539                {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
 540                                < q* + 1 <= beta,
 541                 the carry u does not overflow.}
 542              If a negative carry occurs, put q* := q* - 1
 543                and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
 544          Set q[j] := q*.
 545        Normalise [q[m-n],..,q[0]]; this yields the quotient q.
 546        Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
 547        rest r.
 548        The room for q[j] can be allocated at the memory location of r[n+j].
 549      Finally, round-to-even:
 550        Shift r left by 1 bit.
 551        If r > b or if r = b and q[0] is odd, q := q+1.
 552    */
 553   const mp_limb_t *a_ptr = a.limbs;
 554   size_t a_len = a.nlimbs;
 555   const mp_limb_t *b_ptr = b.limbs;
 556   size_t b_len = b.nlimbs;
 557   mp_limb_t *roomptr;
 558   mp_limb_t *tmp_roomptr = NULL;
 559   mp_limb_t *q_ptr;
 560   size_t q_len;
 561   mp_limb_t *r_ptr;
 562   size_t r_len;
 563 
 564   /* Allocate room for a_len+2 digits.
 565      (Need a_len+1 digits for the real division and 1 more digit for the
 566      final rounding of q.)  */
 567   roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
 568   if (roomptr == NULL)
 569     return NULL;
 570 
 571   /* Normalise a.  */
 572   while (a_len > 0 && a_ptr[a_len - 1] == 0)
 573     a_len--;
 574 
 575   /* Normalise b.  */
 576   for (;;)
 577     {
 578       if (b_len == 0)
 579         /* Division by zero.  */
 580         abort ();
 581       if (b_ptr[b_len - 1] == 0)
 582         b_len--;
 583       else
 584         break;
 585     }
 586 
 587   /* Here m = a_len >= 0 and n = b_len > 0.  */
 588 
 589   if (a_len < b_len)
 590     {
 591       /* m<n: trivial case.  q=0, r := copy of a.  */
 592       r_ptr = roomptr;
 593       r_len = a_len;
 594       memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
 595       q_ptr = roomptr + a_len;
 596       q_len = 0;
 597     }
 598   else if (b_len == 1)
 599     {
 600       /* n=1: single precision division.
 601          beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
 602       r_ptr = roomptr;
 603       q_ptr = roomptr + 1;
 604       {
 605         mp_limb_t den = b_ptr[0];
 606         mp_limb_t remainder = 0;
 607         const mp_limb_t *sourceptr = a_ptr + a_len;
 608         mp_limb_t *destptr = q_ptr + a_len;
 609         size_t count;
 610         for (count = a_len; count > 0; count--)
 611           {
 612             mp_twolimb_t num =
 613               ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
 614             *--destptr = num / den;
 615             remainder = num % den;
 616           }
 617         /* Normalise and store r.  */
 618         if (remainder > 0)
 619           {
 620             r_ptr[0] = remainder;
 621             r_len = 1;
 622           }
 623         else
 624           r_len = 0;
 625         /* Normalise q.  */
 626         q_len = a_len;
 627         if (q_ptr[q_len - 1] == 0)
 628           q_len--;
 629       }
 630     }
 631   else
 632     {
 633       /* n>1: multiple precision division.
 634          beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
 635          beta^(m-n-1) <= a/b < beta^(m-n+1).  */
 636       /* Determine s.  */
 637       size_t s;
 638       {
 639         mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
 640         /* Determine s = GMP_LIMB_BITS - integer_length (msd).
 641            Code copied from gnulib's integer_length.c.  */
 642 # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
 643      || (__clang_major__ >= 4)
 644         s = __builtin_clz (msd);
 645 # else
 646 #  if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
 647         if (GMP_LIMB_BITS <= DBL_MANT_BIT)
 648           {
 649             /* Use 'double' operations.
 650                Assumes an IEEE 754 'double' implementation.  */
 651 #   define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
 652 #   define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
 653 #   define NWORDS \
 654      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
 655             union { double value; unsigned int word[NWORDS]; } m;
 656 
 657             /* Use a single integer to floating-point conversion.  */
 658             m.value = msd;
 659 
 660             s = GMP_LIMB_BITS
 661                 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
 662                    - DBL_EXP_BIAS);
 663           }
 664         else
 665 #   undef NWORDS
 666 #  endif
 667           {
 668             s = 31;
 669             if (msd >= 0x10000)
 670               {
 671                 msd = msd >> 16;
 672                 s -= 16;
 673               }
 674             if (msd >= 0x100)
 675               {
 676                 msd = msd >> 8;
 677                 s -= 8;
 678               }
 679             if (msd >= 0x10)
 680               {
 681                 msd = msd >> 4;
 682                 s -= 4;
 683               }
 684             if (msd >= 0x4)
 685               {
 686                 msd = msd >> 2;
 687                 s -= 2;
 688               }
 689             if (msd >= 0x2)
 690               {
 691                 msd = msd >> 1;
 692                 s -= 1;
 693               }
 694           }
 695 # endif
 696       }
 697       /* 0 <= s < GMP_LIMB_BITS.
 698          Copy b, shifting it left by s bits.  */
 699       if (s > 0)
 700         {
 701           tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
 702           if (tmp_roomptr == NULL)
 703             {
 704               free (roomptr);
 705               return NULL;
 706             }
 707           {
 708             const mp_limb_t *sourceptr = b_ptr;
 709             mp_limb_t *destptr = tmp_roomptr;
 710             mp_twolimb_t accu = 0;
 711             size_t count;
 712             for (count = b_len; count > 0; count--)
 713               {
 714                 accu += (mp_twolimb_t) *sourceptr++ << s;
 715                 *destptr++ = (mp_limb_t) accu;
 716                 accu = accu >> GMP_LIMB_BITS;
 717               }
 718             /* accu must be zero, since that was how s was determined.  */
 719             if (accu != 0)
 720               abort ();
 721           }
 722           b_ptr = tmp_roomptr;
 723         }
 724       /* Copy a, shifting it left by s bits, yields r.
 725          Memory layout:
 726          At the beginning: r = roomptr[0..a_len],
 727          at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
 728       r_ptr = roomptr;
 729       if (s == 0)
 730         {
 731           memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
 732           r_ptr[a_len] = 0;
 733         }
 734       else
 735         {
 736           const mp_limb_t *sourceptr = a_ptr;
 737           mp_limb_t *destptr = r_ptr;
 738           mp_twolimb_t accu = 0;
 739           size_t count;
 740           for (count = a_len; count > 0; count--)
 741             {
 742               accu += (mp_twolimb_t) *sourceptr++ << s;
 743               *destptr++ = (mp_limb_t) accu;
 744               accu = accu >> GMP_LIMB_BITS;
 745             }
 746           *destptr++ = (mp_limb_t) accu;
 747         }
 748       q_ptr = roomptr + b_len;
 749       q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
 750       {
 751         size_t j = a_len - b_len; /* m-n */
 752         mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
 753         mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
 754         mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
 755           ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
 756         /* Division loop, traversed m-n+1 times.
 757            j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
 758         for (;;)
 759           {
 760             mp_limb_t q_star;
 761             mp_limb_t c1;
 762             if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
 763               {
 764                 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
 765                 mp_twolimb_t num =
 766                   ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
 767                   | r_ptr[j + b_len - 1];
 768                 q_star = num / b_msd;
 769                 c1 = num % b_msd;
 770               }
 771             else
 772               {
 773                 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
 774                 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
 775                 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
 776                    <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
 777                    <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
 778                         {<= beta !}.
 779                    If yes, jump directly to the subtraction loop.
 780                    (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
 781                     <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
 782                 if (r_ptr[j + b_len] > b_msd
 783                     || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
 784                   /* r[j+n] >= b[n-1]+1 or
 785                      r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
 786                      carry.  */
 787                   goto subtract;
 788               }
 789             /* q_star = q*,
 790                c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
 791             {
 792               mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
 793                 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
 794               mp_twolimb_t c3 = /* b[n-2] * q* */
 795                 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
 796               /* While c2 < c3, increase c2 and decrease c3.
 797                  Consider c3-c2.  While it is > 0, decrease it by
 798                  b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
 799                  this can happen only twice.  */
 800               if (c3 > c2)
 801                 {
 802                   q_star = q_star - 1; /* q* := q* - 1 */
 803                   if (c3 - c2 > b_msdd)
 804                     q_star = q_star - 1; /* q* := q* - 1 */
 805                 }
 806             }
 807             if (q_star > 0)
 808               subtract:
 809               {
 810                 /* Subtract r := r - b * q* * beta^j.  */
 811                 mp_limb_t cr;
 812                 {
 813                   const mp_limb_t *sourceptr = b_ptr;
 814                   mp_limb_t *destptr = r_ptr + j;
 815                   mp_twolimb_t carry = 0;
 816                   size_t count;
 817                   for (count = b_len; count > 0; count--)
 818                     {
 819                       /* Here 0 <= carry <= q*.  */
 820                       carry =
 821                         carry
 822                         + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
 823                         + (mp_limb_t) ~(*destptr);
 824                       /* Here 0 <= carry <= beta*q* + beta-1.  */
 825                       *destptr++ = ~(mp_limb_t) carry;
 826                       carry = carry >> GMP_LIMB_BITS; /* <= q* */
 827                     }
 828                   cr = (mp_limb_t) carry;
 829                 }
 830                 /* Subtract cr from r_ptr[j + b_len], then forget about
 831                    r_ptr[j + b_len].  */
 832                 if (cr > r_ptr[j + b_len])
 833                   {
 834                     /* Subtraction gave a carry.  */
 835                     q_star = q_star - 1; /* q* := q* - 1 */
 836                     /* Add b back.  */
 837                     {
 838                       const mp_limb_t *sourceptr = b_ptr;
 839                       mp_limb_t *destptr = r_ptr + j;
 840                       mp_limb_t carry = 0;
 841                       size_t count;
 842                       for (count = b_len; count > 0; count--)
 843                         {
 844                           mp_limb_t source1 = *sourceptr++;
 845                           mp_limb_t source2 = *destptr;
 846                           *destptr++ = source1 + source2 + carry;
 847                           carry =
 848                             (carry
 849                              ? source1 >= (mp_limb_t) ~source2
 850                              : source1 > (mp_limb_t) ~source2);
 851                         }
 852                     }
 853                     /* Forget about the carry and about r[j+n].  */
 854                   }
 855               }
 856             /* q* is determined.  Store it as q[j].  */
 857             q_ptr[j] = q_star;
 858             if (j == 0)
 859               break;
 860             j--;
 861           }
 862       }
 863       r_len = b_len;
 864       /* Normalise q.  */
 865       if (q_ptr[q_len - 1] == 0)
 866         q_len--;
 867 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
 868           b is shifted left by s bits.  */
 869       /* Shift r right by s bits.  */
 870       if (s > 0)
 871         {
 872           mp_limb_t ptr = r_ptr + r_len;
 873           mp_twolimb_t accu = 0;
 874           size_t count;
 875           for (count = r_len; count > 0; count--)
 876             {
 877               accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
 878               accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
 879               *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
 880             }
 881         }
 882 # endif
 883       /* Normalise r.  */
 884       while (r_len > 0 && r_ptr[r_len - 1] == 0)
 885         r_len--;
 886     }
 887   /* Compare r << 1 with b.  */
 888   if (r_len > b_len)
 889     goto increment_q;
 890   {
 891     size_t i;
 892     for (i = b_len;;)
 893       {
 894         mp_limb_t r_i =
 895           (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
 896           | (i < r_len ? r_ptr[i] << 1 : 0);
 897         mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
 898         if (r_i > b_i)
 899           goto increment_q;
 900         if (r_i < b_i)
 901           goto keep_q;
 902         if (i == 0)
 903           break;
 904         i--;
 905       }
 906   }
 907   if (q_len > 0 && ((q_ptr[0] & 1) != 0))
 908     /* q is odd.  */
 909     increment_q:
 910     {
 911       size_t i;
 912       for (i = 0; i < q_len; i++)
 913         if (++(q_ptr[i]) != 0)
 914           goto keep_q;
 915       q_ptr[q_len++] = 1;
 916     }
 917   keep_q:
 918   if (tmp_roomptr != NULL)
 919     free (tmp_roomptr);
 920   q->limbs = q_ptr;
 921   q->nlimbs = q_len;
 922   return roomptr;
 923 }
 924 
 925 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
 926    representation.
 927    Destroys the contents of a.
 928    Return the allocated memory - containing the decimal digits in low-to-high
 929    order, terminated with a NUL character - in case of success, NULL in case
 930    of memory allocation failure.  */
 931 static char *
 932 convert_to_decimal (mpn_t a, size_t extra_zeroes)
     /* [previous][next][first][last][top][bottom][index][help] */
 933 {
 934   mp_limb_t *a_ptr = a.limbs;
 935   size_t a_len = a.nlimbs;
 936   /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
 937   size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
 938   /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the
 939      digits of a, followed by 1 byte for the terminating NUL.  */
 940   char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1));
 941   if (c_ptr != NULL)
 942     {
 943       char *d_ptr = c_ptr;
 944       for (; extra_zeroes > 0; extra_zeroes--)
 945         *d_ptr++ = '0';
 946       while (a_len > 0)
 947         {
 948           /* Divide a by 10^9, in-place.  */
 949           mp_limb_t remainder = 0;
 950           mp_limb_t *ptr = a_ptr + a_len;
 951           size_t count;
 952           for (count = a_len; count > 0; count--)
 953             {
 954               mp_twolimb_t num =
 955                 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
 956               *ptr = num / 1000000000;
 957               remainder = num % 1000000000;
 958             }
 959           /* Store the remainder as 9 decimal digits.  */
 960           for (count = 9; count > 0; count--)
 961             {
 962               *d_ptr++ = '0' + (remainder % 10);
 963               remainder = remainder / 10;
 964             }
 965           /* Normalize a.  */
 966           if (a_ptr[a_len - 1] == 0)
 967             a_len--;
 968         }
 969       /* Remove leading zeroes.  */
 970       while (d_ptr > c_ptr && d_ptr[-1] == '0')
 971         d_ptr--;
 972       /* But keep at least one zero.  */
 973       if (d_ptr == c_ptr)
 974         *d_ptr++ = '0';
 975       /* Terminate the string.  */
 976       *d_ptr = '\0';
 977     }
 978   return c_ptr;
 979 }
 980 
 981 # if NEED_PRINTF_LONG_DOUBLE
 982 
 983 /* Assuming x is finite and >= 0:
 984    write x as x = 2^e * m, where m is a bignum.
 985    Return the allocated memory in case of success, NULL in case of memory
 986    allocation failure.  */
 987 static void *
 988 decode_long_double (long double x, int *ep, mpn_t *mp)
     /* [previous][next][first][last][top][bottom][index][help] */
 989 {
 990   mpn_t m;
 991   int exp;
 992   long double y;
 993   size_t i;
 994 
 995   /* Allocate memory for result.  */
 996   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
 997   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
 998   if (m.limbs == NULL)
 999     return NULL;
1000   /* Split into exponential part and mantissa.  */
1001   y = frexpl (x, &exp);
1002   if (!(y >= 0.0L && y < 1.0L))
1003     abort ();
1004   /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
1005      latter is an integer.  */
1006   /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
1007      I'm not sure whether it's safe to cast a 'long double' value between
1008      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1009      'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1010      doesn't matter).  */
1011 #  if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
1012 #   if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1013     {
1014       mp_limb_t hi, lo;
1015       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1016       hi = (int) y;
1017       y -= hi;
1018       if (!(y >= 0.0L && y < 1.0L))
1019         abort ();
1020       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1021       lo = (int) y;
1022       y -= lo;
1023       if (!(y >= 0.0L && y < 1.0L))
1024         abort ();
1025       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1026     }
1027 #   else
1028     {
1029       mp_limb_t d;
1030       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
1031       d = (int) y;
1032       y -= d;
1033       if (!(y >= 0.0L && y < 1.0L))
1034         abort ();
1035       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
1036     }
1037 #   endif
1038 #  endif
1039   for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1040     {
1041       mp_limb_t hi, lo;
1042       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1043       hi = (int) y;
1044       y -= hi;
1045       if (!(y >= 0.0L && y < 1.0L))
1046         abort ();
1047       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1048       lo = (int) y;
1049       y -= lo;
1050       if (!(y >= 0.0L && y < 1.0L))
1051         abort ();
1052       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1053     }
1054 #  if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
1055            precision.  */
1056   if (!(y == 0.0L))
1057     abort ();
1058 #  endif
1059   /* Normalise.  */
1060   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1061     m.nlimbs--;
1062   *mp = m;
1063   *ep = exp - LDBL_MANT_BIT;
1064   return m.limbs;
1065 }
1066 
1067 # endif
1068 
1069 # if NEED_PRINTF_DOUBLE
1070 
1071 /* Assuming x is finite and >= 0:
1072    write x as x = 2^e * m, where m is a bignum.
1073    Return the allocated memory in case of success, NULL in case of memory
1074    allocation failure.  */
1075 static void *
1076 decode_double (double x, int *ep, mpn_t *mp)
     /* [previous][next][first][last][top][bottom][index][help] */
1077 {
1078   mpn_t m;
1079   int exp;
1080   double y;
1081   size_t i;
1082 
1083   /* Allocate memory for result.  */
1084   m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
1085   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
1086   if (m.limbs == NULL)
1087     return NULL;
1088   /* Split into exponential part and mantissa.  */
1089   y = frexp (x, &exp);
1090   if (!(y >= 0.0 && y < 1.0))
1091     abort ();
1092   /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
1093      latter is an integer.  */
1094   /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
1095      I'm not sure whether it's safe to cast a 'double' value between
1096      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1097      'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1098      doesn't matter).  */
1099 #  if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
1100 #   if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1101     {
1102       mp_limb_t hi, lo;
1103       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1104       hi = (int) y;
1105       y -= hi;
1106       if (!(y >= 0.0 && y < 1.0))
1107         abort ();
1108       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1109       lo = (int) y;
1110       y -= lo;
1111       if (!(y >= 0.0 && y < 1.0))
1112         abort ();
1113       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1114     }
1115 #   else
1116     {
1117       mp_limb_t d;
1118       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1119       d = (int) y;
1120       y -= d;
1121       if (!(y >= 0.0 && y < 1.0))
1122         abort ();
1123       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1124     }
1125 #   endif
1126 #  endif
1127   for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1128     {
1129       mp_limb_t hi, lo;
1130       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1131       hi = (int) y;
1132       y -= hi;
1133       if (!(y >= 0.0 && y < 1.0))
1134         abort ();
1135       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1136       lo = (int) y;
1137       y -= lo;
1138       if (!(y >= 0.0 && y < 1.0))
1139         abort ();
1140       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1141     }
1142   if (!(y == 0.0))
1143     abort ();
1144   /* Normalise.  */
1145   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1146     m.nlimbs--;
1147   *mp = m;
1148   *ep = exp - DBL_MANT_BIT;
1149   return m.limbs;
1150 }
1151 
1152 # endif
1153 
1154 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1155    Returns the decimal representation of round (x * 10^n).
1156    Return the allocated memory - containing the decimal digits in low-to-high
1157    order, terminated with a NUL character - in case of success, NULL in case
1158    of memory allocation failure.  */
1159 static char *
1160 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
     /* [previous][next][first][last][top][bottom][index][help] */
1161 {
1162   int s;
1163   size_t extra_zeroes;
1164   unsigned int abs_n;
1165   unsigned int abs_s;
1166   mp_limb_t *pow5_ptr;
1167   size_t pow5_len;
1168   unsigned int s_limbs;
1169   unsigned int s_bits;
1170   mpn_t pow5;
1171   mpn_t z;
1172   void *z_memory;
1173   char *digits;
1174 
1175   if (memory == NULL)
1176     return NULL;
1177   /* x = 2^e * m, hence
1178      y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1179        = round (2^s * 5^n * m).  */
1180   s = e + n;
1181   extra_zeroes = 0;
1182   /* Factor out a common power of 10 if possible.  */
1183   if (s > 0 && n > 0)
1184     {
1185       extra_zeroes = (s < n ? s : n);
1186       s -= extra_zeroes;
1187       n -= extra_zeroes;
1188     }
1189   /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1190      Before converting to decimal, we need to compute
1191      z = round (2^s * 5^n * m).  */
1192   /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1193      sign.  2.322 is slightly larger than log(5)/log(2).  */
1194   abs_n = (n >= 0 ? n : -n);
1195   abs_s = (s >= 0 ? s : -s);
1196   pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1197                                     + abs_s / GMP_LIMB_BITS + 1)
1198                                    * sizeof (mp_limb_t));
1199   if (pow5_ptr == NULL)
1200     {
1201       free (memory);
1202       return NULL;
1203     }
1204   /* Initialize with 1.  */
1205   pow5_ptr[0] = 1;
1206   pow5_len = 1;
1207   /* Multiply with 5^|n|.  */
1208   if (abs_n > 0)
1209     {
1210       static mp_limb_t const small_pow5[13 + 1] =
1211         {
1212           1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1213           48828125, 244140625, 1220703125
1214         };
1215       unsigned int n13;
1216       for (n13 = 0; n13 <= abs_n; n13 += 13)
1217         {
1218           mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1219           size_t j;
1220           mp_twolimb_t carry = 0;
1221           for (j = 0; j < pow5_len; j++)
1222             {
1223               mp_limb_t digit2 = pow5_ptr[j];
1224               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1225               pow5_ptr[j] = (mp_limb_t) carry;
1226               carry = carry >> GMP_LIMB_BITS;
1227             }
1228           if (carry > 0)
1229             pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1230         }
1231     }
1232   s_limbs = abs_s / GMP_LIMB_BITS;
1233   s_bits = abs_s % GMP_LIMB_BITS;
1234   if (n >= 0 ? s >= 0 : s <= 0)
1235     {
1236       /* Multiply with 2^|s|.  */
1237       if (s_bits > 0)
1238         {
1239           mp_limb_t *ptr = pow5_ptr;
1240           mp_twolimb_t accu = 0;
1241           size_t count;
1242           for (count = pow5_len; count > 0; count--)
1243             {
1244               accu += (mp_twolimb_t) *ptr << s_bits;
1245               *ptr++ = (mp_limb_t) accu;
1246               accu = accu >> GMP_LIMB_BITS;
1247             }
1248           if (accu > 0)
1249             {
1250               *ptr = (mp_limb_t) accu;
1251               pow5_len++;
1252             }
1253         }
1254       if (s_limbs > 0)
1255         {
1256           size_t count;
1257           for (count = pow5_len; count > 0;)
1258             {
1259               count--;
1260               pow5_ptr[s_limbs + count] = pow5_ptr[count];
1261             }
1262           for (count = s_limbs; count > 0;)
1263             {
1264               count--;
1265               pow5_ptr[count] = 0;
1266             }
1267           pow5_len += s_limbs;
1268         }
1269       pow5.limbs = pow5_ptr;
1270       pow5.nlimbs = pow5_len;
1271       if (n >= 0)
1272         {
1273           /* Multiply m with pow5.  No division needed.  */
1274           z_memory = multiply (m, pow5, &z);
1275         }
1276       else
1277         {
1278           /* Divide m by pow5 and round.  */
1279           z_memory = divide (m, pow5, &z);
1280         }
1281     }
1282   else
1283     {
1284       pow5.limbs = pow5_ptr;
1285       pow5.nlimbs = pow5_len;
1286       if (n >= 0)
1287         {
1288           /* n >= 0, s < 0.
1289              Multiply m with pow5, then divide by 2^|s|.  */
1290           mpn_t numerator;
1291           mpn_t denominator;
1292           void *tmp_memory;
1293           tmp_memory = multiply (m, pow5, &numerator);
1294           if (tmp_memory == NULL)
1295             {
1296               free (pow5_ptr);
1297               free (memory);
1298               return NULL;
1299             }
1300           /* Construct 2^|s|.  */
1301           {
1302             mp_limb_t *ptr = pow5_ptr + pow5_len;
1303             size_t i;
1304             for (i = 0; i < s_limbs; i++)
1305               ptr[i] = 0;
1306             ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1307             denominator.limbs = ptr;
1308             denominator.nlimbs = s_limbs + 1;
1309           }
1310           z_memory = divide (numerator, denominator, &z);
1311           free (tmp_memory);
1312         }
1313       else
1314         {
1315           /* n < 0, s > 0.
1316              Multiply m with 2^s, then divide by pow5.  */
1317           mpn_t numerator;
1318           mp_limb_t *num_ptr;
1319           num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1320                                           * sizeof (mp_limb_t));
1321           if (num_ptr == NULL)
1322             {
1323               free (pow5_ptr);
1324               free (memory);
1325               return NULL;
1326             }
1327           {
1328             mp_limb_t *destptr = num_ptr;
1329             {
1330               size_t i;
1331               for (i = 0; i < s_limbs; i++)
1332                 *destptr++ = 0;
1333             }
1334             if (s_bits > 0)
1335               {
1336                 const mp_limb_t *sourceptr = m.limbs;
1337                 mp_twolimb_t accu = 0;
1338                 size_t count;
1339                 for (count = m.nlimbs; count > 0; count--)
1340                   {
1341                     accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1342                     *destptr++ = (mp_limb_t) accu;
1343                     accu = accu >> GMP_LIMB_BITS;
1344                   }
1345                 if (accu > 0)
1346                   *destptr++ = (mp_limb_t) accu;
1347               }
1348             else
1349               {
1350                 const mp_limb_t *sourceptr = m.limbs;
1351                 size_t count;
1352                 for (count = m.nlimbs; count > 0; count--)
1353                   *destptr++ = *sourceptr++;
1354               }
1355             numerator.limbs = num_ptr;
1356             numerator.nlimbs = destptr - num_ptr;
1357           }
1358           z_memory = divide (numerator, pow5, &z);
1359           free (num_ptr);
1360         }
1361     }
1362   free (pow5_ptr);
1363   free (memory);
1364 
1365   /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
1366 
1367   if (z_memory == NULL)
1368     return NULL;
1369   digits = convert_to_decimal (z, extra_zeroes);
1370   free (z_memory);
1371   return digits;
1372 }
1373 
1374 # if NEED_PRINTF_LONG_DOUBLE
1375 
1376 /* Assuming x is finite and >= 0, and n is an integer:
1377    Returns the decimal representation of round (x * 10^n).
1378    Return the allocated memory - containing the decimal digits in low-to-high
1379    order, terminated with a NUL character - in case of success, NULL in case
1380    of memory allocation failure.  */
1381 static char *
1382 scale10_round_decimal_long_double (long double x, int n)
     /* [previous][next][first][last][top][bottom][index][help] */
1383 {
1384   int e IF_LINT(= 0);
1385   mpn_t m;
1386   void *memory = decode_long_double (x, &e, &m);
1387   return scale10_round_decimal_decoded (e, m, memory, n);
1388 }
1389 
1390 # endif
1391 
1392 # if NEED_PRINTF_DOUBLE
1393 
1394 /* Assuming x is finite and >= 0, and n is an integer:
1395    Returns the decimal representation of round (x * 10^n).
1396    Return the allocated memory - containing the decimal digits in low-to-high
1397    order, terminated with a NUL character - in case of success, NULL in case
1398    of memory allocation failure.  */
1399 static char *
1400 scale10_round_decimal_double (double x, int n)
     /* [previous][next][first][last][top][bottom][index][help] */
1401 {
1402   int e IF_LINT(= 0);
1403   mpn_t m;
1404   void *memory = decode_double (x, &e, &m);
1405   return scale10_round_decimal_decoded (e, m, memory, n);
1406 }
1407 
1408 # endif
1409 
1410 # if NEED_PRINTF_LONG_DOUBLE
1411 
1412 /* Assuming x is finite and > 0:
1413    Return an approximation for n with 10^n <= x < 10^(n+1).
1414    The approximation is usually the right n, but may be off by 1 sometimes.  */
1415 static int
1416 floorlog10l (long double x)
     /* [previous][next][first][last][top][bottom][index][help] */
1417 {
1418   int exp;
1419   long double y;
1420   double z;
1421   double l;
1422 
1423   /* Split into exponential part and mantissa.  */
1424   y = frexpl (x, &exp);
1425   if (!(y >= 0.0L && y < 1.0L))
1426     abort ();
1427   if (y == 0.0L)
1428     return INT_MIN;
1429   if (y < 0.5L)
1430     {
1431       while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1432         {
1433           y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1434           exp -= GMP_LIMB_BITS;
1435         }
1436       if (y < (1.0L / (1 << 16)))
1437         {
1438           y *= 1.0L * (1 << 16);
1439           exp -= 16;
1440         }
1441       if (y < (1.0L / (1 << 8)))
1442         {
1443           y *= 1.0L * (1 << 8);
1444           exp -= 8;
1445         }
1446       if (y < (1.0L / (1 << 4)))
1447         {
1448           y *= 1.0L * (1 << 4);
1449           exp -= 4;
1450         }
1451       if (y < (1.0L / (1 << 2)))
1452         {
1453           y *= 1.0L * (1 << 2);
1454           exp -= 2;
1455         }
1456       if (y < (1.0L / (1 << 1)))
1457         {
1458           y *= 1.0L * (1 << 1);
1459           exp -= 1;
1460         }
1461     }
1462   if (!(y >= 0.5L && y < 1.0L))
1463     abort ();
1464   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
1465   l = exp;
1466   z = y;
1467   if (z < 0.70710678118654752444)
1468     {
1469       z *= 1.4142135623730950488;
1470       l -= 0.5;
1471     }
1472   if (z < 0.8408964152537145431)
1473     {
1474       z *= 1.1892071150027210667;
1475       l -= 0.25;
1476     }
1477   if (z < 0.91700404320467123175)
1478     {
1479       z *= 1.0905077326652576592;
1480       l -= 0.125;
1481     }
1482   if (z < 0.9576032806985736469)
1483     {
1484       z *= 1.0442737824274138403;
1485       l -= 0.0625;
1486     }
1487   /* Now 0.95 <= z <= 1.01.  */
1488   z = 1 - z;
1489   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1490      Four terms are enough to get an approximation with error < 10^-7.  */
1491   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1492   /* Finally multiply with log(2)/log(10), yields an approximation for
1493      log10(x).  */
1494   l *= 0.30102999566398119523;
1495   /* Round down to the next integer.  */
1496   return (int) l + (l < 0 ? -1 : 0);
1497 }
1498 
1499 # endif
1500 
1501 # if NEED_PRINTF_DOUBLE
1502 
1503 /* Assuming x is finite and > 0:
1504    Return an approximation for n with 10^n <= x < 10^(n+1).
1505    The approximation is usually the right n, but may be off by 1 sometimes.  */
1506 static int
1507 floorlog10 (double x)
     /* [previous][next][first][last][top][bottom][index][help] */
1508 {
1509   int exp;
1510   double y;
1511   double z;
1512   double l;
1513 
1514   /* Split into exponential part and mantissa.  */
1515   y = frexp (x, &exp);
1516   if (!(y >= 0.0 && y < 1.0))
1517     abort ();
1518   if (y == 0.0)
1519     return INT_MIN;
1520   if (y < 0.5)
1521     {
1522       while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1523         {
1524           y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1525           exp -= GMP_LIMB_BITS;
1526         }
1527       if (y < (1.0 / (1 << 16)))
1528         {
1529           y *= 1.0 * (1 << 16);
1530           exp -= 16;
1531         }
1532       if (y < (1.0 / (1 << 8)))
1533         {
1534           y *= 1.0 * (1 << 8);
1535           exp -= 8;
1536         }
1537       if (y < (1.0 / (1 << 4)))
1538         {
1539           y *= 1.0 * (1 << 4);
1540           exp -= 4;
1541         }
1542       if (y < (1.0 / (1 << 2)))
1543         {
1544           y *= 1.0 * (1 << 2);
1545           exp -= 2;
1546         }
1547       if (y < (1.0 / (1 << 1)))
1548         {
1549           y *= 1.0 * (1 << 1);
1550           exp -= 1;
1551         }
1552     }
1553   if (!(y >= 0.5 && y < 1.0))
1554     abort ();
1555   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
1556   l = exp;
1557   z = y;
1558   if (z < 0.70710678118654752444)
1559     {
1560       z *= 1.4142135623730950488;
1561       l -= 0.5;
1562     }
1563   if (z < 0.8408964152537145431)
1564     {
1565       z *= 1.1892071150027210667;
1566       l -= 0.25;
1567     }
1568   if (z < 0.91700404320467123175)
1569     {
1570       z *= 1.0905077326652576592;
1571       l -= 0.125;
1572     }
1573   if (z < 0.9576032806985736469)
1574     {
1575       z *= 1.0442737824274138403;
1576       l -= 0.0625;
1577     }
1578   /* Now 0.95 <= z <= 1.01.  */
1579   z = 1 - z;
1580   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1581      Four terms are enough to get an approximation with error < 10^-7.  */
1582   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1583   /* Finally multiply with log(2)/log(10), yields an approximation for
1584      log10(x).  */
1585   l *= 0.30102999566398119523;
1586   /* Round down to the next integer.  */
1587   return (int) l + (l < 0 ? -1 : 0);
1588 }
1589 
1590 # endif
1591 
1592 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1593    a single '1' digit.  */
1594 static int
1595 is_borderline (const char *digits, size_t precision)
     /* [previous][next][first][last][top][bottom][index][help] */
1596 {
1597   for (; precision > 0; precision--, digits++)
1598     if (*digits != '0')
1599       return 0;
1600   if (*digits != '1')
1601     return 0;
1602   digits++;
1603   return *digits == '\0';
1604 }
1605 
1606 #endif
1607 
1608 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
1609 
1610 /* Use a different function name, to make it possible that the 'wchar_t'
1611    parametrization and the 'char' parametrization get compiled in the same
1612    translation unit.  */
1613 # if WIDE_CHAR_VERSION
1614 #  define MAX_ROOM_NEEDED wmax_room_needed
1615 # else
1616 #  define MAX_ROOM_NEEDED max_room_needed
1617 # endif
1618 
1619 /* Returns the number of TCHAR_T units needed as temporary space for the result
1620    of sprintf or SNPRINTF of a single conversion directive.  */
1621 static size_t
1622 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
     /* [previous][next][first][last][top][bottom][index][help] */
1623                  arg_type type, int flags, size_t width, int has_precision,
1624                  size_t precision, int pad_ourselves)
1625 {
1626   size_t tmp_length;
1627 
1628   switch (conversion)
1629     {
1630     case 'd': case 'i': case 'u':
1631       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1632         tmp_length =
1633           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1634                           * 0.30103 /* binary -> decimal */
1635                          )
1636           + 1; /* turn floor into ceil */
1637       else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1638         tmp_length =
1639           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1640                           * 0.30103 /* binary -> decimal */
1641                          )
1642           + 1; /* turn floor into ceil */
1643       else
1644         tmp_length =
1645           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1646                           * 0.30103 /* binary -> decimal */
1647                          )
1648           + 1; /* turn floor into ceil */
1649       if (tmp_length < precision)
1650         tmp_length = precision;
1651       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
1652       tmp_length = xsum (tmp_length, tmp_length);
1653       /* Add 1, to account for a leading sign.  */
1654       tmp_length = xsum (tmp_length, 1);
1655       break;
1656 
1657     case 'o':
1658       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1659         tmp_length =
1660           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1661                           * 0.333334 /* binary -> octal */
1662                          )
1663           + 1; /* turn floor into ceil */
1664       else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1665         tmp_length =
1666           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1667                           * 0.333334 /* binary -> octal */
1668                          )
1669           + 1; /* turn floor into ceil */
1670       else
1671         tmp_length =
1672           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1673                           * 0.333334 /* binary -> octal */
1674                          )
1675           + 1; /* turn floor into ceil */
1676       if (tmp_length < precision)
1677         tmp_length = precision;
1678       /* Add 1, to account for a leading sign.  */
1679       tmp_length = xsum (tmp_length, 1);
1680       break;
1681 
1682     case 'x': case 'X':
1683       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1684         tmp_length =
1685           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1686                           * 0.25 /* binary -> hexadecimal */
1687                          )
1688           + 1; /* turn floor into ceil */
1689       else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1690         tmp_length =
1691           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1692                           * 0.25 /* binary -> hexadecimal */
1693                          )
1694           + 1; /* turn floor into ceil */
1695       else
1696         tmp_length =
1697           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1698                           * 0.25 /* binary -> hexadecimal */
1699                          )
1700           + 1; /* turn floor into ceil */
1701       if (tmp_length < precision)
1702         tmp_length = precision;
1703       /* Add 2, to account for a leading sign or alternate form.  */
1704       tmp_length = xsum (tmp_length, 2);
1705       break;
1706 
1707     case 'f': case 'F':
1708       if (type == TYPE_LONGDOUBLE)
1709         tmp_length =
1710           (unsigned int) (LDBL_MAX_EXP
1711                           * 0.30103 /* binary -> decimal */
1712                           * 2 /* estimate for FLAG_GROUP */
1713                          )
1714           + 1 /* turn floor into ceil */
1715           + 10; /* sign, decimal point etc. */
1716       else
1717         tmp_length =
1718           (unsigned int) (DBL_MAX_EXP
1719                           * 0.30103 /* binary -> decimal */
1720                           * 2 /* estimate for FLAG_GROUP */
1721                          )
1722           + 1 /* turn floor into ceil */
1723           + 10; /* sign, decimal point etc. */
1724       tmp_length = xsum (tmp_length, precision);
1725       break;
1726 
1727     case 'e': case 'E': case 'g': case 'G':
1728       tmp_length =
1729         12; /* sign, decimal point, exponent etc. */
1730       tmp_length = xsum (tmp_length, precision);
1731       break;
1732 
1733     case 'a': case 'A':
1734       if (type == TYPE_LONGDOUBLE)
1735         tmp_length =
1736           (unsigned int) (LDBL_DIG
1737                           * 0.831 /* decimal -> hexadecimal */
1738                          )
1739           + 1; /* turn floor into ceil */
1740       else
1741         tmp_length =
1742           (unsigned int) (DBL_DIG
1743                           * 0.831 /* decimal -> hexadecimal */
1744                          )
1745           + 1; /* turn floor into ceil */
1746       if (tmp_length < precision)
1747         tmp_length = precision;
1748       /* Account for sign, decimal point etc. */
1749       tmp_length = xsum (tmp_length, 12);
1750       break;
1751 
1752     case 'c':
1753 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
1754       if (type == TYPE_WIDE_CHAR)
1755         {
1756           tmp_length = MB_CUR_MAX;
1757 #  if ENABLE_WCHAR_FALLBACK
1758           if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6))
1759             tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6);
1760 #  endif
1761         }
1762       else
1763 # endif
1764         tmp_length = 1;
1765       break;
1766 
1767     case 's':
1768 # if HAVE_WCHAR_T
1769       if (type == TYPE_WIDE_STRING)
1770         {
1771 #  if WIDE_CHAR_VERSION
1772           /* ISO C says about %ls in fwprintf:
1773                "If the precision is not specified or is greater than the size
1774                 of the array, the array shall contain a null wide character."
1775              So if there is a precision, we must not use wcslen.  */
1776           const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
1777 
1778           if (has_precision)
1779             tmp_length = local_wcsnlen (arg, precision);
1780           else
1781             tmp_length = local_wcslen (arg);
1782 #  else
1783           /* ISO C says about %ls in fprintf:
1784                "If a precision is specified, no more than that many bytes are
1785                 written (including shift sequences, if any), and the array
1786                 shall contain a null wide character if, to equal the multibyte
1787                 character sequence length given by the precision, the function
1788                 would need to access a wide character one past the end of the
1789                 array."
1790              So if there is a precision, we must not use wcslen.  */
1791           /* This case has already been handled separately in VASNPRINTF.  */
1792           abort ();
1793 #  endif
1794         }
1795       else
1796 # endif
1797         {
1798 # if WIDE_CHAR_VERSION
1799           /* ISO C says about %s in fwprintf:
1800                "If the precision is not specified or is greater than the size
1801                 of the converted array, the converted array shall contain a
1802                 null wide character."
1803              So if there is a precision, we must not use strlen.  */
1804           /* This case has already been handled separately in VASNPRINTF.  */
1805           abort ();
1806 # else
1807           /* ISO C says about %s in fprintf:
1808                "If the precision is not specified or greater than the size of
1809                 the array, the array shall contain a null character."
1810              So if there is a precision, we must not use strlen.  */
1811           const char *arg = ap->arg[arg_index].a.a_string;
1812 
1813           if (has_precision)
1814             tmp_length = local_strnlen (arg, precision);
1815           else
1816             tmp_length = strlen (arg);
1817 # endif
1818         }
1819       break;
1820 
1821     case 'p':
1822       tmp_length =
1823         (unsigned int) (sizeof (void *) * CHAR_BIT
1824                         * 0.25 /* binary -> hexadecimal */
1825                        )
1826           + 1 /* turn floor into ceil */
1827           + 2; /* account for leading 0x */
1828       break;
1829 
1830     default:
1831       abort ();
1832     }
1833 
1834   if (!pad_ourselves)
1835     {
1836 # if ENABLE_UNISTDIO
1837       /* Padding considers the number of characters, therefore the number of
1838          elements after padding may be
1839            > max (tmp_length, width)
1840          but is certainly
1841            <= tmp_length + width.  */
1842       tmp_length = xsum (tmp_length, width);
1843 # else
1844       /* Padding considers the number of elements, says POSIX.  */
1845       if (tmp_length < width)
1846         tmp_length = width;
1847 # endif
1848     }
1849 
1850   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1851 
1852   return tmp_length;
1853 }
1854 
1855 #endif
1856 
1857 DCHAR_T *
1858 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
     /* [previous][next][first][last][top][bottom][index][help] */
1859             const FCHAR_T *format, va_list args)
1860 {
1861   DIRECTIVES d;
1862   arguments a;
1863 
1864   if (PRINTF_PARSE (format, &d, &a) < 0)
1865     /* errno is already set.  */
1866     return NULL;
1867 
1868   /* Frees the memory allocated by this function.  Preserves errno.  */
1869 #define CLEANUP() \
1870   if (d.dir != d.direct_alloc_dir)                                      \
1871     free (d.dir);                                                       \
1872   if (a.arg != a.direct_alloc_arg)                                      \
1873     free (a.arg);
1874 
1875   if (PRINTF_FETCHARGS (args, &a) < 0)
1876     {
1877       CLEANUP ();
1878       errno = EINVAL;
1879       return NULL;
1880     }
1881 
1882   {
1883     size_t buf_neededlength;
1884     TCHAR_T *buf;
1885     TCHAR_T *buf_malloced;
1886     const FCHAR_T *cp;
1887     size_t i;
1888     DIRECTIVE *dp;
1889     /* Output string accumulator.  */
1890     DCHAR_T *result;
1891     size_t allocated;
1892     size_t length;
1893 
1894     /* Allocate a small buffer that will hold a directive passed to
1895        sprintf or snprintf.  */
1896     buf_neededlength =
1897       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1898 #if HAVE_ALLOCA
1899     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1900       {
1901         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1902         buf_malloced = NULL;
1903       }
1904     else
1905 #endif
1906       {
1907         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1908         if (size_overflow_p (buf_memsize))
1909           goto out_of_memory_1;
1910         buf = (TCHAR_T *) malloc (buf_memsize);
1911         if (buf == NULL)
1912           goto out_of_memory_1;
1913         buf_malloced = buf;
1914       }
1915 
1916     if (resultbuf != NULL)
1917       {
1918         result = resultbuf;
1919         allocated = *lengthp;
1920       }
1921     else
1922       {
1923         result = NULL;
1924         allocated = 0;
1925       }
1926     length = 0;
1927     /* Invariants:
1928        result is either == resultbuf or == NULL or malloc-allocated.
1929        If length > 0, then result != NULL.  */
1930 
1931     /* Ensures that allocated >= needed.  Aborts through a jump to
1932        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
1933 #define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \
1934     if ((needed) > allocated)                                                \
1935       {                                                                      \
1936         size_t memory_size;                                                  \
1937         DCHAR_T *memory;                                                     \
1938                                                                              \
1939         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
1940         if ((needed) > allocated)                                            \
1941           allocated = (needed);                                              \
1942         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
1943         if (size_overflow_p (memory_size))                                   \
1944           oom_statement                                                      \
1945         if (result == resultbuf || result == NULL)                           \
1946           memory = (DCHAR_T *) malloc (memory_size);                         \
1947         else                                                                 \
1948           memory = (DCHAR_T *) realloc (result, memory_size);                \
1949         if (memory == NULL)                                                  \
1950           oom_statement                                                      \
1951         if (result == resultbuf && length > 0)                               \
1952           DCHAR_CPY (memory, result, length);                                \
1953         result = memory;                                                     \
1954       }
1955 #define ENSURE_ALLOCATION(needed) \
1956   ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; )
1957 
1958     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1959       {
1960         if (cp != dp->dir_start)
1961           {
1962             size_t n = dp->dir_start - cp;
1963             size_t augmented_length = xsum (length, n);
1964 
1965             ENSURE_ALLOCATION (augmented_length);
1966             /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
1967                need that the format string contains only ASCII characters
1968                if FCHAR_T and DCHAR_T are not the same type.  */
1969             if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1970               {
1971                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1972                 length = augmented_length;
1973               }
1974             else
1975               {
1976                 do
1977                   result[length++] = *cp++;
1978                 while (--n > 0);
1979               }
1980           }
1981         if (i == d.count)
1982           break;
1983 
1984         /* Execute a single directive.  */
1985         if (dp->conversion == '%')
1986           {
1987             size_t augmented_length;
1988 
1989             if (!(dp->arg_index == ARG_NONE))
1990               abort ();
1991             augmented_length = xsum (length, 1);
1992             ENSURE_ALLOCATION (augmented_length);
1993             result[length] = '%';
1994             length = augmented_length;
1995           }
1996         else
1997           {
1998             if (!(dp->arg_index != ARG_NONE))
1999               abort ();
2000 
2001             if (dp->conversion == 'n')
2002               {
2003                 switch (a.arg[dp->arg_index].type)
2004                   {
2005                   case TYPE_COUNT_SCHAR_POINTER:
2006                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
2007                     break;
2008                   case TYPE_COUNT_SHORT_POINTER:
2009                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
2010                     break;
2011                   case TYPE_COUNT_INT_POINTER:
2012                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
2013                     break;
2014                   case TYPE_COUNT_LONGINT_POINTER:
2015                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
2016                     break;
2017                   case TYPE_COUNT_LONGLONGINT_POINTER:
2018                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
2019                     break;
2020                   default:
2021                     abort ();
2022                   }
2023               }
2024 #if ENABLE_UNISTDIO
2025             /* The unistdio extensions.  */
2026             else if (dp->conversion == 'U')
2027               {
2028                 arg_type type = a.arg[dp->arg_index].type;
2029                 int flags = dp->flags;
2030                 int has_width;
2031                 size_t width;
2032                 int has_precision;
2033                 size_t precision;
2034 
2035                 has_width = 0;
2036                 width = 0;
2037                 if (dp->width_start != dp->width_end)
2038                   {
2039                     if (dp->width_arg_index != ARG_NONE)
2040                       {
2041                         int arg;
2042 
2043                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2044                           abort ();
2045                         arg = a.arg[dp->width_arg_index].a.a_int;
2046                         width = arg;
2047                         if (arg < 0)
2048                           {
2049                             /* "A negative field width is taken as a '-' flag
2050                                 followed by a positive field width."  */
2051                             flags |= FLAG_LEFT;
2052                             width = -width;
2053                           }
2054                       }
2055                     else
2056                       {
2057                         const FCHAR_T *digitp = dp->width_start;
2058 
2059                         do
2060                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2061                         while (digitp != dp->width_end);
2062                       }
2063                     has_width = 1;
2064                   }
2065 
2066                 has_precision = 0;
2067                 precision = 0;
2068                 if (dp->precision_start != dp->precision_end)
2069                   {
2070                     if (dp->precision_arg_index != ARG_NONE)
2071                       {
2072                         int arg;
2073 
2074                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2075                           abort ();
2076                         arg = a.arg[dp->precision_arg_index].a.a_int;
2077                         /* "A negative precision is taken as if the precision
2078                             were omitted."  */
2079                         if (arg >= 0)
2080                           {
2081                             precision = arg;
2082                             has_precision = 1;
2083                           }
2084                       }
2085                     else
2086                       {
2087                         const FCHAR_T *digitp = dp->precision_start + 1;
2088 
2089                         precision = 0;
2090                         while (digitp != dp->precision_end)
2091                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2092                         has_precision = 1;
2093                       }
2094                   }
2095 
2096                 switch (type)
2097                   {
2098                   case TYPE_U8_STRING:
2099                     {
2100                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2101                       const uint8_t *arg_end;
2102                       size_t characters;
2103 
2104                       if (has_precision)
2105                         {
2106                           /* Use only PRECISION characters, from the left.  */
2107                           arg_end = arg;
2108                           characters = 0;
2109                           for (; precision > 0; precision--)
2110                             {
2111                               int count = u8_strmblen (arg_end);
2112                               if (count == 0)
2113                                 break;
2114                               if (count < 0)
2115                                 {
2116                                   if (!(result == resultbuf || result == NULL))
2117                                     free (result);
2118                                   if (buf_malloced != NULL)
2119                                     free (buf_malloced);
2120                                   CLEANUP ();
2121                                   errno = EILSEQ;
2122                                   return NULL;
2123                                 }
2124                               arg_end += count;
2125                               characters++;
2126                             }
2127                         }
2128                       else if (has_width)
2129                         {
2130                           /* Use the entire string, and count the number of
2131                              characters.  */
2132                           arg_end = arg;
2133                           characters = 0;
2134                           for (;;)
2135                             {
2136                               int count = u8_strmblen (arg_end);
2137                               if (count == 0)
2138                                 break;
2139                               if (count < 0)
2140                                 {
2141                                   if (!(result == resultbuf || result == NULL))
2142                                     free (result);
2143                                   if (buf_malloced != NULL)
2144                                     free (buf_malloced);
2145                                   CLEANUP ();
2146                                   errno = EILSEQ;
2147                                   return NULL;
2148                                 }
2149                               arg_end += count;
2150                               characters++;
2151                             }
2152                         }
2153                       else
2154                         {
2155                           /* Use the entire string.  */
2156                           arg_end = arg + u8_strlen (arg);
2157                           /* The number of characters doesn't matter.  */
2158                           characters = 0;
2159                         }
2160 
2161                       if (characters < width && !(dp->flags & FLAG_LEFT))
2162                         {
2163                           size_t n = width - characters;
2164                           ENSURE_ALLOCATION (xsum (length, n));
2165                           DCHAR_SET (result + length, ' ', n);
2166                           length += n;
2167                         }
2168 
2169 # if DCHAR_IS_UINT8_T
2170                       {
2171                         size_t n = arg_end - arg;
2172                         ENSURE_ALLOCATION (xsum (length, n));
2173                         DCHAR_CPY (result + length, arg, n);
2174                         length += n;
2175                       }
2176 # else
2177                       { /* Convert.  */
2178                         DCHAR_T *converted = result + length;
2179                         size_t converted_len = allocated - length;
2180 #  if DCHAR_IS_TCHAR
2181                         /* Convert from UTF-8 to locale encoding.  */
2182                         converted =
2183                           u8_conv_to_encoding (locale_charset (),
2184                                                iconveh_question_mark,
2185                                                arg, arg_end - arg, NULL,
2186                                                converted, &converted_len);
2187 #  else
2188                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
2189                         converted =
2190                           U8_TO_DCHAR (arg, arg_end - arg,
2191                                        converted, &converted_len);
2192 #  endif
2193                         if (converted == NULL)
2194                           {
2195                             if (!(result == resultbuf || result == NULL))
2196                               free (result);
2197                             if (buf_malloced != NULL)
2198                               free (buf_malloced);
2199                             CLEANUP ();
2200                             return NULL;
2201                           }
2202                         if (converted != result + length)
2203                           {
2204                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2205                                                     { free (converted); goto out_of_memory; });
2206                             DCHAR_CPY (result + length, converted, converted_len);
2207                             free (converted);
2208                           }
2209                         length += converted_len;
2210                       }
2211 # endif
2212 
2213                       if (characters < width && (dp->flags & FLAG_LEFT))
2214                         {
2215                           size_t n = width - characters;
2216                           ENSURE_ALLOCATION (xsum (length, n));
2217                           DCHAR_SET (result + length, ' ', n);
2218                           length += n;
2219                         }
2220                     }
2221                     break;
2222 
2223                   case TYPE_U16_STRING:
2224                     {
2225                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2226                       const uint16_t *arg_end;
2227                       size_t characters;
2228 
2229                       if (has_precision)
2230                         {
2231                           /* Use only PRECISION characters, from the left.  */
2232                           arg_end = arg;
2233                           characters = 0;
2234                           for (; precision > 0; precision--)
2235                             {
2236                               int count = u16_strmblen (arg_end);
2237                               if (count == 0)
2238                                 break;
2239                               if (count < 0)
2240                                 {
2241                                   if (!(result == resultbuf || result == NULL))
2242                                     free (result);
2243                                   if (buf_malloced != NULL)
2244                                     free (buf_malloced);
2245                                   CLEANUP ();
2246                                   errno = EILSEQ;
2247                                   return NULL;
2248                                 }
2249                               arg_end += count;
2250                               characters++;
2251                             }
2252                         }
2253                       else if (has_width)
2254                         {
2255                           /* Use the entire string, and count the number of
2256                              characters.  */
2257                           arg_end = arg;
2258                           characters = 0;
2259                           for (;;)
2260                             {
2261                               int count = u16_strmblen (arg_end);
2262                               if (count == 0)
2263                                 break;
2264                               if (count < 0)
2265                                 {
2266                                   if (!(result == resultbuf || result == NULL))
2267                                     free (result);
2268                                   if (buf_malloced != NULL)
2269                                     free (buf_malloced);
2270                                   CLEANUP ();
2271                                   errno = EILSEQ;
2272                                   return NULL;
2273                                 }
2274                               arg_end += count;
2275                               characters++;
2276                             }
2277                         }
2278                       else
2279                         {
2280                           /* Use the entire string.  */
2281                           arg_end = arg + u16_strlen (arg);
2282                           /* The number of characters doesn't matter.  */
2283                           characters = 0;
2284                         }
2285 
2286                       if (characters < width && !(dp->flags & FLAG_LEFT))
2287                         {
2288                           size_t n = width - characters;
2289                           ENSURE_ALLOCATION (xsum (length, n));
2290                           DCHAR_SET (result + length, ' ', n);
2291                           length += n;
2292                         }
2293 
2294 # if DCHAR_IS_UINT16_T
2295                       {
2296                         size_t n = arg_end - arg;
2297                         ENSURE_ALLOCATION (xsum (length, n));
2298                         DCHAR_CPY (result + length, arg, n);
2299                         length += n;
2300                       }
2301 # else
2302                       { /* Convert.  */
2303                         DCHAR_T *converted = result + length;
2304                         size_t converted_len = allocated - length;
2305 #  if DCHAR_IS_TCHAR
2306                         /* Convert from UTF-16 to locale encoding.  */
2307                         converted =
2308                           u16_conv_to_encoding (locale_charset (),
2309                                                 iconveh_question_mark,
2310                                                 arg, arg_end - arg, NULL,
2311                                                 converted, &converted_len);
2312 #  else
2313                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
2314                         converted =
2315                           U16_TO_DCHAR (arg, arg_end - arg,
2316                                         converted, &converted_len);
2317 #  endif
2318                         if (converted == NULL)
2319                           {
2320                             if (!(result == resultbuf || result == NULL))
2321                               free (result);
2322                             if (buf_malloced != NULL)
2323                               free (buf_malloced);
2324                             CLEANUP ();
2325                             return NULL;
2326                           }
2327                         if (converted != result + length)
2328                           {
2329                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2330                                                     { free (converted); goto out_of_memory; });
2331                             DCHAR_CPY (result + length, converted, converted_len);
2332                             free (converted);
2333                           }
2334                         length += converted_len;
2335                       }
2336 # endif
2337 
2338                       if (characters < width && (dp->flags & FLAG_LEFT))
2339                         {
2340                           size_t n = width - characters;
2341                           ENSURE_ALLOCATION (xsum (length, n));
2342                           DCHAR_SET (result + length, ' ', n);
2343                           length += n;
2344                         }
2345                     }
2346                     break;
2347 
2348                   case TYPE_U32_STRING:
2349                     {
2350                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2351                       const uint32_t *arg_end;
2352                       size_t characters;
2353 
2354                       if (has_precision)
2355                         {
2356                           /* Use only PRECISION characters, from the left.  */
2357                           arg_end = arg;
2358                           characters = 0;
2359                           for (; precision > 0; precision--)
2360                             {
2361                               int count = u32_strmblen (arg_end);
2362                               if (count == 0)
2363                                 break;
2364                               if (count < 0)
2365                                 {
2366                                   if (!(result == resultbuf || result == NULL))
2367                                     free (result);
2368                                   if (buf_malloced != NULL)
2369                                     free (buf_malloced);
2370                                   CLEANUP ();
2371                                   errno = EILSEQ;
2372                                   return NULL;
2373                                 }
2374                               arg_end += count;
2375                               characters++;
2376                             }
2377                         }
2378                       else if (has_width)
2379                         {
2380                           /* Use the entire string, and count the number of
2381                              characters.  */
2382                           arg_end = arg;
2383                           characters = 0;
2384                           for (;;)
2385                             {
2386                               int count = u32_strmblen (arg_end);
2387                               if (count == 0)
2388                                 break;
2389                               if (count < 0)
2390                                 {
2391                                   if (!(result == resultbuf || result == NULL))
2392                                     free (result);
2393                                   if (buf_malloced != NULL)
2394                                     free (buf_malloced);
2395                                   CLEANUP ();
2396                                   errno = EILSEQ;
2397                                   return NULL;
2398                                 }
2399                               arg_end += count;
2400                               characters++;
2401                             }
2402                         }
2403                       else
2404                         {
2405                           /* Use the entire string.  */
2406                           arg_end = arg + u32_strlen (arg);
2407                           /* The number of characters doesn't matter.  */
2408                           characters = 0;
2409                         }
2410 
2411                       if (characters < width && !(dp->flags & FLAG_LEFT))
2412                         {
2413                           size_t n = width - characters;
2414                           ENSURE_ALLOCATION (xsum (length, n));
2415                           DCHAR_SET (result + length, ' ', n);
2416                           length += n;
2417                         }
2418 
2419 # if DCHAR_IS_UINT32_T
2420                       {
2421                         size_t n = arg_end - arg;
2422                         ENSURE_ALLOCATION (xsum (length, n));
2423                         DCHAR_CPY (result + length, arg, n);
2424                         length += n;
2425                       }
2426 # else
2427                       { /* Convert.  */
2428                         DCHAR_T *converted = result + length;
2429                         size_t converted_len = allocated - length;
2430 #  if DCHAR_IS_TCHAR
2431                         /* Convert from UTF-32 to locale encoding.  */
2432                         converted =
2433                           u32_conv_to_encoding (locale_charset (),
2434                                                 iconveh_question_mark,
2435                                                 arg, arg_end - arg, NULL,
2436                                                 converted, &converted_len);
2437 #  else
2438                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
2439                         converted =
2440                           U32_TO_DCHAR (arg, arg_end - arg,
2441                                         converted, &converted_len);
2442 #  endif
2443                         if (converted == NULL)
2444                           {
2445                             if (!(result == resultbuf || result == NULL))
2446                               free (result);
2447                             if (buf_malloced != NULL)
2448                               free (buf_malloced);
2449                             CLEANUP ();
2450                             return NULL;
2451                           }
2452                         if (converted != result + length)
2453                           {
2454                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2455                                                     { free (converted); goto out_of_memory; });
2456                             DCHAR_CPY (result + length, converted, converted_len);
2457                             free (converted);
2458                           }
2459                         length += converted_len;
2460                       }
2461 # endif
2462 
2463                       if (characters < width && (dp->flags & FLAG_LEFT))
2464                         {
2465                           size_t n = width - characters;
2466                           ENSURE_ALLOCATION (xsum (length, n));
2467                           DCHAR_SET (result + length, ' ', n);
2468                           length += n;
2469                         }
2470                     }
2471                     break;
2472 
2473                   default:
2474                     abort ();
2475                   }
2476               }
2477 #endif
2478 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T
2479             else if (dp->conversion == 's'
2480 # if WIDE_CHAR_VERSION
2481                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2482 # else
2483                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2484 # endif
2485                     )
2486               {
2487                 /* The normal handling of the 's' directive below requires
2488                    allocating a temporary buffer.  The determination of its
2489                    length (tmp_length), in the case when a precision is
2490                    specified, below requires a conversion between a char[]
2491                    string and a wchar_t[] wide string.  It could be done, but
2492                    we have no guarantee that the implementation of sprintf will
2493                    use the exactly same algorithm.  Without this guarantee, it
2494                    is possible to have buffer overrun bugs.  In order to avoid
2495                    such bugs, we implement the entire processing of the 's'
2496                    directive ourselves.  */
2497                 int flags = dp->flags;
2498                 int has_width;
2499                 size_t width;
2500                 int has_precision;
2501                 size_t precision;
2502 
2503                 has_width = 0;
2504                 width = 0;
2505                 if (dp->width_start != dp->width_end)
2506                   {
2507                     if (dp->width_arg_index != ARG_NONE)
2508                       {
2509                         int arg;
2510 
2511                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2512                           abort ();
2513                         arg = a.arg[dp->width_arg_index].a.a_int;
2514                         width = arg;
2515                         if (arg < 0)
2516                           {
2517                             /* "A negative field width is taken as a '-' flag
2518                                 followed by a positive field width."  */
2519                             flags |= FLAG_LEFT;
2520                             width = -width;
2521                           }
2522                       }
2523                     else
2524                       {
2525                         const FCHAR_T *digitp = dp->width_start;
2526 
2527                         do
2528                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2529                         while (digitp != dp->width_end);
2530                       }
2531                     has_width = 1;
2532                   }
2533 
2534                 has_precision = 0;
2535                 precision = 6;
2536                 if (dp->precision_start != dp->precision_end)
2537                   {
2538                     if (dp->precision_arg_index != ARG_NONE)
2539                       {
2540                         int arg;
2541 
2542                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2543                           abort ();
2544                         arg = a.arg[dp->precision_arg_index].a.a_int;
2545                         /* "A negative precision is taken as if the precision
2546                             were omitted."  */
2547                         if (arg >= 0)
2548                           {
2549                             precision = arg;
2550                             has_precision = 1;
2551                           }
2552                       }
2553                     else
2554                       {
2555                         const FCHAR_T *digitp = dp->precision_start + 1;
2556 
2557                         precision = 0;
2558                         while (digitp != dp->precision_end)
2559                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2560                         has_precision = 1;
2561                       }
2562                   }
2563 
2564 # if WIDE_CHAR_VERSION
2565                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
2566                 {
2567                   const char *arg = a.arg[dp->arg_index].a.a_string;
2568                   const char *arg_end;
2569                   size_t characters;
2570 
2571                   if (has_precision)
2572                     {
2573                       /* Use only as many bytes as needed to produce PRECISION
2574                          wide characters, from the left.  */
2575 #  if HAVE_MBRTOWC
2576                       mbstate_t state;
2577                       memset (&state, '\0', sizeof (mbstate_t));
2578 #  endif
2579                       arg_end = arg;
2580                       characters = 0;
2581                       for (; precision > 0; precision--)
2582                         {
2583                           int count;
2584 #  if HAVE_MBRTOWC
2585                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2586 #  else
2587                           count = mblen (arg_end, MB_CUR_MAX);
2588 #  endif
2589                           if (count == 0)
2590                             /* Found the terminating NUL.  */
2591                             break;
2592                           if (count < 0)
2593                             {
2594                               /* Invalid or incomplete multibyte character.  */
2595                               if (!(result == resultbuf || result == NULL))
2596                                 free (result);
2597                               if (buf_malloced != NULL)
2598                                 free (buf_malloced);
2599                               CLEANUP ();
2600                               errno = EILSEQ;
2601                               return NULL;
2602                             }
2603                           arg_end += count;
2604                           characters++;
2605                         }
2606                     }
2607                   else if (has_width)
2608                     {
2609                       /* Use the entire string, and count the number of wide
2610                          characters.  */
2611 #  if HAVE_MBRTOWC
2612                       mbstate_t state;
2613                       memset (&state, '\0', sizeof (mbstate_t));
2614 #  endif
2615                       arg_end = arg;
2616                       characters = 0;
2617                       for (;;)
2618                         {
2619                           int count;
2620 #  if HAVE_MBRTOWC
2621                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2622 #  else
2623                           count = mblen (arg_end, MB_CUR_MAX);
2624 #  endif
2625                           if (count == 0)
2626                             /* Found the terminating NUL.  */
2627                             break;
2628                           if (count < 0)
2629                             {
2630                               /* Invalid or incomplete multibyte character.  */
2631                               if (!(result == resultbuf || result == NULL))
2632                                 free (result);
2633                               if (buf_malloced != NULL)
2634                                 free (buf_malloced);
2635                               CLEANUP ();
2636                               errno = EILSEQ;
2637                               return NULL;
2638                             }
2639                           arg_end += count;
2640                           characters++;
2641                         }
2642                     }
2643                   else
2644                     {
2645                       /* Use the entire string.  */
2646                       arg_end = arg + strlen (arg);
2647                       /* The number of characters doesn't matter.  */
2648                       characters = 0;
2649                     }
2650 
2651                   if (characters < width && !(dp->flags & FLAG_LEFT))
2652                     {
2653                       size_t n = width - characters;
2654                       ENSURE_ALLOCATION (xsum (length, n));
2655                       DCHAR_SET (result + length, ' ', n);
2656                       length += n;
2657                     }
2658 
2659                   if (has_precision || has_width)
2660                     {
2661                       /* We know the number of wide characters in advance.  */
2662                       size_t remaining;
2663 #  if HAVE_MBRTOWC
2664                       mbstate_t state;
2665                       memset (&state, '\0', sizeof (mbstate_t));
2666 #  endif
2667                       ENSURE_ALLOCATION (xsum (length, characters));
2668                       for (remaining = characters; remaining > 0; remaining--)
2669                         {
2670                           wchar_t wc;
2671                           int count;
2672 #  if HAVE_MBRTOWC
2673                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2674 #  else
2675                           count = mbtowc (&wc, arg, arg_end - arg);
2676 #  endif
2677                           if (count <= 0)
2678                             /* mbrtowc not consistent with mbrlen, or mbtowc
2679                                not consistent with mblen.  */
2680                             abort ();
2681                           result[length++] = wc;
2682                           arg += count;
2683                         }
2684                       if (!(arg == arg_end))
2685                         abort ();
2686                     }
2687                   else
2688                     {
2689 #  if HAVE_MBRTOWC
2690                       mbstate_t state;
2691                       memset (&state, '\0', sizeof (mbstate_t));
2692 #  endif
2693                       while (arg < arg_end)
2694                         {
2695                           wchar_t wc;
2696                           int count;
2697 #  if HAVE_MBRTOWC
2698                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2699 #  else
2700                           count = mbtowc (&wc, arg, arg_end - arg);
2701 #  endif
2702                           if (count <= 0)
2703                             /* mbrtowc not consistent with mbrlen, or mbtowc
2704                                not consistent with mblen.  */
2705                             abort ();
2706                           ENSURE_ALLOCATION (xsum (length, 1));
2707                           result[length++] = wc;
2708                           arg += count;
2709                         }
2710                     }
2711 
2712                   if (characters < width && (dp->flags & FLAG_LEFT))
2713                     {
2714                       size_t n = width - characters;
2715                       ENSURE_ALLOCATION (xsum (length, n));
2716                       DCHAR_SET (result + length, ' ', n);
2717                       length += n;
2718                     }
2719                 }
2720 # else
2721                 /* %ls in vasnprintf.  See the specification of fprintf.  */
2722                 {
2723                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2724                   const wchar_t *arg_end;
2725                   size_t characters;
2726 #  if !DCHAR_IS_TCHAR
2727                   /* This code assumes that TCHAR_T is 'char'.  */
2728                   verify (sizeof (TCHAR_T) == 1);
2729                   TCHAR_T *tmpsrc;
2730                   DCHAR_T *tmpdst;
2731                   size_t tmpdst_len;
2732 #  endif
2733                   size_t w;
2734 
2735                   if (has_precision)
2736                     {
2737                       /* Use only as many wide characters as needed to produce
2738                          at most PRECISION bytes, from the left.  */
2739 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2740                       mbstate_t state;
2741                       memset (&state, '\0', sizeof (mbstate_t));
2742 #  endif
2743                       arg_end = arg;
2744                       characters = 0;
2745                       while (precision > 0)
2746                         {
2747                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2748                           int count;
2749 
2750                           if (*arg_end == 0)
2751                             /* Found the terminating null wide character.  */
2752                             break;
2753                           count = local_wcrtomb (cbuf, *arg_end, &state);
2754                           if (count < 0)
2755                             {
2756                               /* Cannot convert.  */
2757                               if (!(result == resultbuf || result == NULL))
2758                                 free (result);
2759                               if (buf_malloced != NULL)
2760                                 free (buf_malloced);
2761                               CLEANUP ();
2762                               errno = EILSEQ;
2763                               return NULL;
2764                             }
2765                           if (precision < (unsigned int) count)
2766                             break;
2767                           arg_end++;
2768                           characters += count;
2769                           precision -= count;
2770                         }
2771                     }
2772 #  if DCHAR_IS_TCHAR
2773                   else if (has_width)
2774 #  else
2775                   else
2776 #  endif
2777                     {
2778                       /* Use the entire string, and count the number of
2779                          bytes.  */
2780 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2781                       mbstate_t state;
2782                       memset (&state, '\0', sizeof (mbstate_t));
2783 #  endif
2784                       arg_end = arg;
2785                       characters = 0;
2786                       for (;;)
2787                         {
2788                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2789                           int count;
2790 
2791                           if (*arg_end == 0)
2792                             /* Found the terminating null wide character.  */
2793                             break;
2794                           count = local_wcrtomb (cbuf, *arg_end, &state);
2795                           if (count < 0)
2796                             {
2797                               /* Cannot convert.  */
2798                               if (!(result == resultbuf || result == NULL))
2799                                 free (result);
2800                               if (buf_malloced != NULL)
2801                                 free (buf_malloced);
2802                               CLEANUP ();
2803                               errno = EILSEQ;
2804                               return NULL;
2805                             }
2806                           arg_end++;
2807                           characters += count;
2808                         }
2809                     }
2810 #  if DCHAR_IS_TCHAR
2811                   else
2812                     {
2813                       /* Use the entire string.  */
2814                       arg_end = arg + local_wcslen (arg);
2815                       /* The number of bytes doesn't matter.  */
2816                       characters = 0;
2817                     }
2818 #  endif
2819 
2820 #  if !DCHAR_IS_TCHAR
2821                   /* Convert the string into a piece of temporary memory.  */
2822                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2823                   if (tmpsrc == NULL)
2824                     goto out_of_memory;
2825                   {
2826                     TCHAR_T *tmpptr = tmpsrc;
2827                     size_t remaining;
2828 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2829                     mbstate_t state;
2830                     memset (&state, '\0', sizeof (mbstate_t));
2831 #   endif
2832                     for (remaining = characters; remaining > 0; )
2833                       {
2834                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2835                         int count;
2836 
2837                         if (*arg == 0)
2838                           abort ();
2839                         count = local_wcrtomb (cbuf, *arg, &state);
2840                         if (count <= 0)
2841                           /* Inconsistency.  */
2842                           abort ();
2843                         memcpy (tmpptr, cbuf, count);
2844                         tmpptr += count;
2845                         arg++;
2846                         remaining -= count;
2847                       }
2848                     if (!(arg == arg_end))
2849                       abort ();
2850                   }
2851 
2852                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
2853                   tmpdst =
2854                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
2855                                               iconveh_question_mark,
2856                                               tmpsrc, characters,
2857                                               NULL,
2858                                               NULL, &tmpdst_len);
2859                   if (tmpdst == NULL)
2860                     {
2861                       free (tmpsrc);
2862                       if (!(result == resultbuf || result == NULL))
2863                         free (result);
2864                       if (buf_malloced != NULL)
2865                         free (buf_malloced);
2866                       CLEANUP ();
2867                       return NULL;
2868                     }
2869                   free (tmpsrc);
2870 #  endif
2871 
2872                   if (has_width)
2873                     {
2874 #  if ENABLE_UNISTDIO
2875                       /* Outside POSIX, it's preferable to compare the width
2876                          against the number of _characters_ of the converted
2877                          value.  */
2878                       w = DCHAR_MBSNLEN (result + length, characters);
2879 #  else
2880                       /* The width is compared against the number of _bytes_
2881                          of the converted value, says POSIX.  */
2882                       w = characters;
2883 #  endif
2884                     }
2885                   else
2886                     /* w doesn't matter.  */
2887                     w = 0;
2888 
2889                   if (w < width && !(dp->flags & FLAG_LEFT))
2890                     {
2891                       size_t n = width - w;
2892                       ENSURE_ALLOCATION (xsum (length, n));
2893                       DCHAR_SET (result + length, ' ', n);
2894                       length += n;
2895                     }
2896 
2897 #  if DCHAR_IS_TCHAR
2898                   if (has_precision || has_width)
2899                     {
2900                       /* We know the number of bytes in advance.  */
2901                       size_t remaining;
2902 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2903                       mbstate_t state;
2904                       memset (&state, '\0', sizeof (mbstate_t));
2905 #   endif
2906                       ENSURE_ALLOCATION (xsum (length, characters));
2907                       for (remaining = characters; remaining > 0; )
2908                         {
2909                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2910                           int count;
2911 
2912                           if (*arg == 0)
2913                             abort ();
2914                           count = local_wcrtomb (cbuf, *arg, &state);
2915                           if (count <= 0)
2916                             /* Inconsistency.  */
2917                             abort ();
2918                           memcpy (result + length, cbuf, count);
2919                           length += count;
2920                           arg++;
2921                           remaining -= count;
2922                         }
2923                       if (!(arg == arg_end))
2924                         abort ();
2925                     }
2926                   else
2927                     {
2928 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2929                       mbstate_t state;
2930                       memset (&state, '\0', sizeof (mbstate_t));
2931 #   endif
2932                       while (arg < arg_end)
2933                         {
2934                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2935                           int count;
2936 
2937                           if (*arg == 0)
2938                             abort ();
2939                           count = local_wcrtomb (cbuf, *arg, &state);
2940                           if (count <= 0)
2941                             {
2942                               /* Cannot convert.  */
2943                               if (!(result == resultbuf || result == NULL))
2944                                 free (result);
2945                               if (buf_malloced != NULL)
2946                                 free (buf_malloced);
2947                               CLEANUP ();
2948                               errno = EILSEQ;
2949                               return NULL;
2950                             }
2951                           ENSURE_ALLOCATION (xsum (length, count));
2952                           memcpy (result + length, cbuf, count);
2953                           length += count;
2954                           arg++;
2955                         }
2956                     }
2957 #  else
2958                   ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
2959                                           { free (tmpdst); goto out_of_memory; });
2960                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2961                   free (tmpdst);
2962                   length += tmpdst_len;
2963 #  endif
2964 
2965                   if (w < width && (dp->flags & FLAG_LEFT))
2966                     {
2967                       size_t n = width - w;
2968                       ENSURE_ALLOCATION (xsum (length, n));
2969                       DCHAR_SET (result + length, ' ', n);
2970                       length += n;
2971                     }
2972                 }
2973 # endif
2974               }
2975 #endif
2976 #if ENABLE_WCHAR_FALLBACK && HAVE_WINT_T && !WIDE_CHAR_VERSION
2977             else if (dp->conversion == 'c'
2978                      && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)
2979               {
2980                 /* Implement the 'lc' directive ourselves, in order to provide
2981                    the fallback that avoids EILSEQ.  */
2982                 int flags = dp->flags;
2983                 int has_width;
2984                 size_t width;
2985 
2986                 has_width = 0;
2987                 width = 0;
2988                 if (dp->width_start != dp->width_end)
2989                   {
2990                     if (dp->width_arg_index != ARG_NONE)
2991                       {
2992                         int arg;
2993 
2994                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2995                           abort ();
2996                         arg = a.arg[dp->width_arg_index].a.a_int;
2997                         width = arg;
2998                         if (arg < 0)
2999                           {
3000                             /* "A negative field width is taken as a '-' flag
3001                                 followed by a positive field width."  */
3002                             flags |= FLAG_LEFT;
3003                             width = -width;
3004                           }
3005                       }
3006                     else
3007                       {
3008                         const FCHAR_T *digitp = dp->width_start;
3009 
3010                         do
3011                           width = xsum (xtimes (width, 10), *digitp++ - '0');
3012                         while (digitp != dp->width_end);
3013                       }
3014                     has_width = 1;
3015                   }
3016 
3017                 /* %lc in vasnprintf.  See the specification of fprintf.  */
3018                 {
3019                   wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
3020                   size_t characters;
3021 # if !DCHAR_IS_TCHAR
3022                   /* This code assumes that TCHAR_T is 'char'.  */
3023                   verify (sizeof (TCHAR_T) == 1);
3024                   TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64.  */
3025                   DCHAR_T *tmpdst;
3026                   size_t tmpdst_len;
3027 # endif
3028                   size_t w;
3029 
3030 # if DCHAR_IS_TCHAR
3031                   if (has_width)
3032 # endif
3033                     {
3034                       /* Count the number of bytes.  */
3035                       characters = 0;
3036                       if (arg != 0)
3037                         {
3038                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3039                           int count;
3040 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3041                           mbstate_t state;
3042                           memset (&state, '\0', sizeof (mbstate_t));
3043 # endif
3044 
3045                           count = local_wcrtomb (cbuf, arg, &state);
3046                           if (count < 0)
3047                             /* Inconsistency.  */
3048                             abort ();
3049                           characters = count;
3050                         }
3051                     }
3052 # if DCHAR_IS_TCHAR
3053                   else
3054                     {
3055                       /* The number of bytes doesn't matter.  */
3056                       characters = 0;
3057                     }
3058 # endif
3059 
3060 # if !DCHAR_IS_TCHAR
3061                   /* Convert the string into a piece of temporary memory.  */
3062                   if (characters > 0) /* implies arg != 0 */
3063                     {
3064                       char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3065                       int count;
3066 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3067                       mbstate_t state;
3068                       memset (&state, '\0', sizeof (mbstate_t));
3069 #  endif
3070 
3071                       count = local_wcrtomb (cbuf, arg, &state);
3072                       if (count <= 0)
3073                         /* Inconsistency.  */
3074                         abort ();
3075                       memcpy (tmpsrc, cbuf, count);
3076                     }
3077 
3078                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
3079                   tmpdst =
3080                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
3081                                               iconveh_question_mark,
3082                                               tmpsrc, characters,
3083                                               NULL,
3084                                               NULL, &tmpdst_len);
3085                   if (tmpdst == NULL)
3086                     {
3087                       if (!(result == resultbuf || result == NULL))
3088                         free (result);
3089                       if (buf_malloced != NULL)
3090                         free (buf_malloced);
3091                       CLEANUP ();
3092                       return NULL;
3093                     }
3094 # endif
3095 
3096                   if (has_width)
3097                     {
3098 # if ENABLE_UNISTDIO
3099                       /* Outside POSIX, it's preferable to compare the width
3100                          against the number of _characters_ of the converted
3101                          value.  */
3102                       w = DCHAR_MBSNLEN (result + length, characters);
3103 # else
3104                       /* The width is compared against the number of _bytes_
3105                          of the converted value, says POSIX.  */
3106                       w = characters;
3107 # endif
3108                     }
3109                   else
3110                     /* w doesn't matter.  */
3111                     w = 0;
3112 
3113                   if (w < width && !(dp->flags & FLAG_LEFT))
3114                     {
3115                       size_t n = width - w;
3116                       ENSURE_ALLOCATION (xsum (length, n));
3117                       DCHAR_SET (result + length, ' ', n);
3118                       length += n;
3119                     }
3120 
3121 # if DCHAR_IS_TCHAR
3122                   if (has_width)
3123                     {
3124                       /* We know the number of bytes in advance.  */
3125                       ENSURE_ALLOCATION (xsum (length, characters));
3126                       if (characters > 0) /* implies arg != 0 */
3127                         {
3128                           int count;
3129 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3130                           mbstate_t state;
3131                           memset (&state, '\0', sizeof (mbstate_t));
3132 #  endif
3133 
3134                           count = local_wcrtomb (result + length, arg, &state);
3135                           if (count <= 0)
3136                             /* Inconsistency.  */
3137                             abort ();
3138                           length += count;
3139                         }
3140                     }
3141                   else
3142                     {
3143                       if (arg != 0)
3144                         {
3145                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3146                           int count;
3147 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3148                           mbstate_t state;
3149                           memset (&state, '\0', sizeof (mbstate_t));
3150 #  endif
3151 
3152                           count = local_wcrtomb (cbuf, arg, &state);
3153                           if (count <= 0)
3154                             /* Inconsistency.  */
3155                             abort ();
3156                           ENSURE_ALLOCATION (xsum (length, count));
3157                           memcpy (result + length, cbuf, count);
3158                           length += count;
3159                         }
3160                     }
3161 # else
3162                   ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
3163                                           { free (tmpdst); goto out_of_memory; });
3164                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3165                   free (tmpdst);
3166                   length += tmpdst_len;
3167 # endif
3168 
3169                   if (w < width && (dp->flags & FLAG_LEFT))
3170                     {
3171                       size_t n = width - w;
3172                       ENSURE_ALLOCATION (xsum (length, n));
3173                       DCHAR_SET (result + length, ' ', n);
3174                       length += n;
3175                     }
3176                 }
3177               }
3178 #endif
3179 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
3180             else if ((dp->conversion == 'a' || dp->conversion == 'A')
3181 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
3182                      && (0
3183 #  if NEED_PRINTF_DOUBLE
3184                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
3185 #  endif
3186 #  if NEED_PRINTF_LONG_DOUBLE
3187                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3188 #  endif
3189                         )
3190 # endif
3191                     )
3192               {
3193                 arg_type type = a.arg[dp->arg_index].type;
3194                 int flags = dp->flags;
3195                 size_t width;
3196                 int has_precision;
3197                 size_t precision;
3198                 size_t tmp_length;
3199                 size_t count;
3200                 DCHAR_T tmpbuf[700];
3201                 DCHAR_T *tmp;
3202                 DCHAR_T *pad_ptr;
3203                 DCHAR_T *p;
3204 
3205                 width = 0;
3206                 if (dp->width_start != dp->width_end)
3207                   {
3208                     if (dp->width_arg_index != ARG_NONE)
3209                       {
3210                         int arg;
3211 
3212                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3213                           abort ();
3214                         arg = a.arg[dp->width_arg_index].a.a_int;
3215                         width = arg;
3216                         if (arg < 0)
3217                           {
3218                             /* "A negative field width is taken as a '-' flag
3219                                 followed by a positive field width."  */
3220                             flags |= FLAG_LEFT;
3221                             width = -width;
3222                           }
3223                       }
3224                     else
3225                       {
3226                         const FCHAR_T *digitp = dp->width_start;
3227 
3228                         do
3229                           width = xsum (xtimes (width, 10), *digitp++ - '0');
3230                         while (digitp != dp->width_end);
3231                       }
3232                   }
3233 
3234                 has_precision = 0;
3235                 precision = 0;
3236                 if (dp->precision_start != dp->precision_end)
3237                   {
3238                     if (dp->precision_arg_index != ARG_NONE)
3239                       {
3240                         int arg;
3241 
3242                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3243                           abort ();
3244                         arg = a.arg[dp->precision_arg_index].a.a_int;
3245                         /* "A negative precision is taken as if the precision
3246                             were omitted."  */
3247                         if (arg >= 0)
3248                           {
3249                             precision = arg;
3250                             has_precision = 1;
3251                           }
3252                       }
3253                     else
3254                       {
3255                         const FCHAR_T *digitp = dp->precision_start + 1;
3256 
3257                         precision = 0;
3258                         while (digitp != dp->precision_end)
3259                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3260                         has_precision = 1;
3261                       }
3262                   }
3263 
3264                 /* Allocate a temporary buffer of sufficient size.  */
3265                 if (type == TYPE_LONGDOUBLE)
3266                   tmp_length =
3267                     (unsigned int) ((LDBL_DIG + 1)
3268                                     * 0.831 /* decimal -> hexadecimal */
3269                                    )
3270                     + 1; /* turn floor into ceil */
3271                 else
3272                   tmp_length =
3273                     (unsigned int) ((DBL_DIG + 1)
3274                                     * 0.831 /* decimal -> hexadecimal */
3275                                    )
3276                     + 1; /* turn floor into ceil */
3277                 if (tmp_length < precision)
3278                   tmp_length = precision;
3279                 /* Account for sign, decimal point etc. */
3280                 tmp_length = xsum (tmp_length, 12);
3281 
3282                 if (tmp_length < width)
3283                   tmp_length = width;
3284 
3285                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3286 
3287                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3288                   tmp = tmpbuf;
3289                 else
3290                   {
3291                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3292 
3293                     if (size_overflow_p (tmp_memsize))
3294                       /* Overflow, would lead to out of memory.  */
3295                       goto out_of_memory;
3296                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3297                     if (tmp == NULL)
3298                       /* Out of memory.  */
3299                       goto out_of_memory;
3300                   }
3301 
3302                 pad_ptr = NULL;
3303                 p = tmp;
3304                 if (type == TYPE_LONGDOUBLE)
3305                   {
3306 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3307                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3308 
3309                     if (isnanl (arg))
3310                       {
3311                         if (dp->conversion == 'A')
3312                           {
3313                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3314                           }
3315                         else
3316                           {
3317                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3318                           }
3319                       }
3320                     else
3321                       {
3322                         int sign = 0;
3323                         DECL_LONG_DOUBLE_ROUNDING
3324 
3325                         BEGIN_LONG_DOUBLE_ROUNDING ();
3326 
3327                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3328                           {
3329                             sign = -1;
3330                             arg = -arg;
3331                           }
3332 
3333                         if (sign < 0)
3334                           *p++ = '-';
3335                         else if (flags & FLAG_SHOWSIGN)
3336                           *p++ = '+';
3337                         else if (flags & FLAG_SPACE)
3338                           *p++ = ' ';
3339 
3340                         if (arg > 0.0L && arg + arg == arg)
3341                           {
3342                             if (dp->conversion == 'A')
3343                               {
3344                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3345                               }
3346                             else
3347                               {
3348                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3349                               }
3350                           }
3351                         else
3352                           {
3353                             int exponent;
3354                             long double mantissa;
3355 
3356                             if (arg > 0.0L)
3357                               mantissa = printf_frexpl (arg, &exponent);
3358                             else
3359                               {
3360                                 exponent = 0;
3361                                 mantissa = 0.0L;
3362                               }
3363 
3364                             if (has_precision
3365                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3366                               {
3367                                 /* Round the mantissa.  */
3368                                 long double tail = mantissa;
3369                                 size_t q;
3370 
3371                                 for (q = precision; ; q--)
3372                                   {
3373                                     int digit = (int) tail;
3374                                     tail -= digit;
3375                                     if (q == 0)
3376                                       {
3377                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3378                                           tail = 1 - tail;
3379                                         else
3380                                           tail = - tail;
3381                                         break;
3382                                       }
3383                                     tail *= 16.0L;
3384                                   }
3385                                 if (tail != 0.0L)
3386                                   for (q = precision; q > 0; q--)
3387                                     tail *= 0.0625L;
3388                                 mantissa += tail;
3389                               }
3390 
3391                             *p++ = '0';
3392                             *p++ = dp->conversion - 'A' + 'X';
3393                             pad_ptr = p;
3394                             {
3395                               int digit;
3396 
3397                               digit = (int) mantissa;
3398                               mantissa -= digit;
3399                               *p++ = '0' + digit;
3400                               if ((flags & FLAG_ALT)
3401                                   || mantissa > 0.0L || precision > 0)
3402                                 {
3403                                   *p++ = decimal_point_char ();
3404                                   /* This loop terminates because we assume
3405                                      that FLT_RADIX is a power of 2.  */
3406                                   while (mantissa > 0.0L)
3407                                     {
3408                                       mantissa *= 16.0L;
3409                                       digit = (int) mantissa;
3410                                       mantissa -= digit;
3411                                       *p++ = digit
3412                                              + (digit < 10
3413                                                 ? '0'
3414                                                 : dp->conversion - 10);
3415                                       if (precision > 0)
3416                                         precision--;
3417                                     }
3418                                   while (precision > 0)
3419                                     {
3420                                       *p++ = '0';
3421                                       precision--;
3422                                     }
3423                                 }
3424                               }
3425                               *p++ = dp->conversion - 'A' + 'P';
3426 #  if WIDE_CHAR_VERSION
3427                               {
3428                                 static const wchar_t decimal_format[] =
3429                                   { '%', '+', 'd', '\0' };
3430                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3431                               }
3432                               while (*p != '\0')
3433                                 p++;
3434 #  else
3435                               if (sizeof (DCHAR_T) == 1)
3436                                 {
3437                                   sprintf ((char *) p, "%+d", exponent);
3438                                   while (*p != '\0')
3439                                     p++;
3440                                 }
3441                               else
3442                                 {
3443                                   char expbuf[6 + 1];
3444                                   const char *ep;
3445                                   sprintf (expbuf, "%+d", exponent);
3446                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3447                                     p++;
3448                                 }
3449 #  endif
3450                           }
3451 
3452                         END_LONG_DOUBLE_ROUNDING ();
3453                       }
3454 # else
3455                     abort ();
3456 # endif
3457                   }
3458                 else
3459                   {
3460 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3461                     double arg = a.arg[dp->arg_index].a.a_double;
3462 
3463                     if (isnand (arg))
3464                       {
3465                         if (dp->conversion == 'A')
3466                           {
3467                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3468                           }
3469                         else
3470                           {
3471                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3472                           }
3473                       }
3474                     else
3475                       {
3476                         int sign = 0;
3477 
3478                         if (signbit (arg)) /* arg < 0.0 or negative zero */
3479                           {
3480                             sign = -1;
3481                             arg = -arg;
3482                           }
3483 
3484                         if (sign < 0)
3485                           *p++ = '-';
3486                         else if (flags & FLAG_SHOWSIGN)
3487                           *p++ = '+';
3488                         else if (flags & FLAG_SPACE)
3489                           *p++ = ' ';
3490 
3491                         if (arg > 0.0 && arg + arg == arg)
3492                           {
3493                             if (dp->conversion == 'A')
3494                               {
3495                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3496                               }
3497                             else
3498                               {
3499                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3500                               }
3501                           }
3502                         else
3503                           {
3504                             int exponent;
3505                             double mantissa;
3506 
3507                             if (arg > 0.0)
3508                               mantissa = printf_frexp (arg, &exponent);
3509                             else
3510                               {
3511                                 exponent = 0;
3512                                 mantissa = 0.0;
3513                               }
3514 
3515                             if (has_precision
3516                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3517                               {
3518                                 /* Round the mantissa.  */
3519                                 double tail = mantissa;
3520                                 size_t q;
3521 
3522                                 for (q = precision; ; q--)
3523                                   {
3524                                     int digit = (int) tail;
3525                                     tail -= digit;
3526                                     if (q == 0)
3527                                       {
3528                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3529                                           tail = 1 - tail;
3530                                         else
3531                                           tail = - tail;
3532                                         break;
3533                                       }
3534                                     tail *= 16.0;
3535                                   }
3536                                 if (tail != 0.0)
3537                                   for (q = precision; q > 0; q--)
3538                                     tail *= 0.0625;
3539                                 mantissa += tail;
3540                               }
3541 
3542                             *p++ = '0';
3543                             *p++ = dp->conversion - 'A' + 'X';
3544                             pad_ptr = p;
3545                             {
3546                               int digit;
3547 
3548                               digit = (int) mantissa;
3549                               mantissa -= digit;
3550                               *p++ = '0' + digit;
3551                               if ((flags & FLAG_ALT)
3552                                   || mantissa > 0.0 || precision > 0)
3553                                 {
3554                                   *p++ = decimal_point_char ();
3555                                   /* This loop terminates because we assume
3556                                      that FLT_RADIX is a power of 2.  */
3557                                   while (mantissa > 0.0)
3558                                     {
3559                                       mantissa *= 16.0;
3560                                       digit = (int) mantissa;
3561                                       mantissa -= digit;
3562                                       *p++ = digit
3563                                              + (digit < 10
3564                                                 ? '0'
3565                                                 : dp->conversion - 10);
3566                                       if (precision > 0)
3567                                         precision--;
3568                                     }
3569                                   while (precision > 0)
3570                                     {
3571                                       *p++ = '0';
3572                                       precision--;
3573                                     }
3574                                 }
3575                               }
3576                               *p++ = dp->conversion - 'A' + 'P';
3577 #  if WIDE_CHAR_VERSION
3578                               {
3579                                 static const wchar_t decimal_format[] =
3580                                   { '%', '+', 'd', '\0' };
3581                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3582                               }
3583                               while (*p != '\0')
3584                                 p++;
3585 #  else
3586                               if (sizeof (DCHAR_T) == 1)
3587                                 {
3588                                   sprintf ((char *) p, "%+d", exponent);
3589                                   while (*p != '\0')
3590                                     p++;
3591                                 }
3592                               else
3593                                 {
3594                                   char expbuf[6 + 1];
3595                                   const char *ep;
3596                                   sprintf (expbuf, "%+d", exponent);
3597                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3598                                     p++;
3599                                 }
3600 #  endif
3601                           }
3602                       }
3603 # else
3604                     abort ();
3605 # endif
3606                   }
3607 
3608                 /* The generated string now extends from tmp to p, with the
3609                    zero padding insertion point being at pad_ptr.  */
3610                 count = p - tmp;
3611 
3612                 if (count < width)
3613                   {
3614                     size_t pad = width - count;
3615                     DCHAR_T *end = p + pad;
3616 
3617                     if (flags & FLAG_LEFT)
3618                       {
3619                         /* Pad with spaces on the right.  */
3620                         for (; pad > 0; pad--)
3621                           *p++ = ' ';
3622                       }
3623                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3624                       {
3625                         /* Pad with zeroes.  */
3626                         DCHAR_T *q = end;
3627 
3628                         while (p > pad_ptr)
3629                           *--q = *--p;
3630                         for (; pad > 0; pad--)
3631                           *p++ = '0';
3632                       }
3633                     else
3634                       {
3635                         /* Pad with spaces on the left.  */
3636                         DCHAR_T *q = end;
3637 
3638                         while (p > tmp)
3639                           *--q = *--p;
3640                         for (; pad > 0; pad--)
3641                           *p++ = ' ';
3642                       }
3643 
3644                     p = end;
3645                   }
3646 
3647                 count = p - tmp;
3648 
3649                 if (count >= tmp_length)
3650                   /* tmp_length was incorrectly calculated - fix the
3651                      code above!  */
3652                   abort ();
3653 
3654                 /* Make room for the result.  */
3655                 if (count >= allocated - length)
3656                   {
3657                     size_t n = xsum (length, count);
3658 
3659                     ENSURE_ALLOCATION (n);
3660                   }
3661 
3662                 /* Append the result.  */
3663                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3664                 if (tmp != tmpbuf)
3665                   free (tmp);
3666                 length += count;
3667               }
3668 #endif
3669 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3670             else if ((dp->conversion == 'f' || dp->conversion == 'F'
3671                       || dp->conversion == 'e' || dp->conversion == 'E'
3672                       || dp->conversion == 'g' || dp->conversion == 'G'
3673                       || dp->conversion == 'a' || dp->conversion == 'A')
3674                      && (0
3675 # if NEED_PRINTF_DOUBLE
3676                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
3677 # elif NEED_PRINTF_INFINITE_DOUBLE
3678                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3679                              /* The systems (mingw) which produce wrong output
3680                                 for Inf, -Inf, and NaN also do so for -0.0.
3681                                 Therefore we treat this case here as well.  */
3682                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3683 # endif
3684 # if NEED_PRINTF_LONG_DOUBLE
3685                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3686 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3687                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3688                              /* Some systems produce wrong output for Inf,
3689                                 -Inf, and NaN.  Some systems in this category
3690                                 (IRIX 5.3) also do so for -0.0.  Therefore we
3691                                 treat this case here as well.  */
3692                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3693 # endif
3694                         ))
3695               {
3696 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3697                 arg_type type = a.arg[dp->arg_index].type;
3698 # endif
3699                 int flags = dp->flags;
3700                 size_t width;
3701                 size_t count;
3702                 int has_precision;
3703                 size_t precision;
3704                 size_t tmp_length;
3705                 DCHAR_T tmpbuf[700];
3706                 DCHAR_T *tmp;
3707                 DCHAR_T *pad_ptr;
3708                 DCHAR_T *p;
3709 
3710                 width = 0;
3711                 if (dp->width_start != dp->width_end)
3712                   {
3713                     if (dp->width_arg_index != ARG_NONE)
3714                       {
3715                         int arg;
3716 
3717                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3718                           abort ();
3719                         arg = a.arg[dp->width_arg_index].a.a_int;
3720                         width = arg;
3721                         if (arg < 0)
3722                           {
3723                             /* "A negative field width is taken as a '-' flag
3724                                 followed by a positive field width."  */
3725                             flags |= FLAG_LEFT;
3726                             width = -width;
3727                           }
3728                       }
3729                     else
3730                       {
3731                         const FCHAR_T *digitp = dp->width_start;
3732 
3733                         do
3734                           width = xsum (xtimes (width, 10), *digitp++ - '0');
3735                         while (digitp != dp->width_end);
3736                       }
3737                   }
3738 
3739                 has_precision = 0;
3740                 precision = 0;
3741                 if (dp->precision_start != dp->precision_end)
3742                   {
3743                     if (dp->precision_arg_index != ARG_NONE)
3744                       {
3745                         int arg;
3746 
3747                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3748                           abort ();
3749                         arg = a.arg[dp->precision_arg_index].a.a_int;
3750                         /* "A negative precision is taken as if the precision
3751                             were omitted."  */
3752                         if (arg >= 0)
3753                           {
3754                             precision = arg;
3755                             has_precision = 1;
3756                           }
3757                       }
3758                     else
3759                       {
3760                         const FCHAR_T *digitp = dp->precision_start + 1;
3761 
3762                         precision = 0;
3763                         while (digitp != dp->precision_end)
3764                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3765                         has_precision = 1;
3766                       }
3767                   }
3768 
3769                 /* POSIX specifies the default precision to be 6 for %f, %F,
3770                    %e, %E, but not for %g, %G.  Implementations appear to use
3771                    the same default precision also for %g, %G.  But for %a, %A,
3772                    the default precision is 0.  */
3773                 if (!has_precision)
3774                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3775                     precision = 6;
3776 
3777                 /* Allocate a temporary buffer of sufficient size.  */
3778 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3779                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3780 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3781                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3782 # elif NEED_PRINTF_LONG_DOUBLE
3783                 tmp_length = LDBL_DIG + 1;
3784 # elif NEED_PRINTF_DOUBLE
3785                 tmp_length = DBL_DIG + 1;
3786 # else
3787                 tmp_length = 0;
3788 # endif
3789                 if (tmp_length < precision)
3790                   tmp_length = precision;
3791 # if NEED_PRINTF_LONG_DOUBLE
3792 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3793                 if (type == TYPE_LONGDOUBLE)
3794 #  endif
3795                   if (dp->conversion == 'f' || dp->conversion == 'F')
3796                     {
3797                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
3798                       if (!(isnanl (arg) || arg + arg == arg))
3799                         {
3800                           /* arg is finite and nonzero.  */
3801                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
3802                           if (exponent >= 0 && tmp_length < exponent + precision)
3803                             tmp_length = exponent + precision;
3804                         }
3805                     }
3806 # endif
3807 # if NEED_PRINTF_DOUBLE
3808 #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3809                 if (type == TYPE_DOUBLE)
3810 #  endif
3811                   if (dp->conversion == 'f' || dp->conversion == 'F')
3812                     {
3813                       double arg = a.arg[dp->arg_index].a.a_double;
3814                       if (!(isnand (arg) || arg + arg == arg))
3815                         {
3816                           /* arg is finite and nonzero.  */
3817                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
3818                           if (exponent >= 0 && tmp_length < exponent + precision)
3819                             tmp_length = exponent + precision;
3820                         }
3821                     }
3822 # endif
3823                 /* Account for sign, decimal point etc. */
3824                 tmp_length = xsum (tmp_length, 12);
3825 
3826                 if (tmp_length < width)
3827                   tmp_length = width;
3828 
3829                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3830 
3831                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3832                   tmp = tmpbuf;
3833                 else
3834                   {
3835                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3836 
3837                     if (size_overflow_p (tmp_memsize))
3838                       /* Overflow, would lead to out of memory.  */
3839                       goto out_of_memory;
3840                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3841                     if (tmp == NULL)
3842                       /* Out of memory.  */
3843                       goto out_of_memory;
3844                   }
3845 
3846                 pad_ptr = NULL;
3847                 p = tmp;
3848 
3849 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3850 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3851                 if (type == TYPE_LONGDOUBLE)
3852 #  endif
3853                   {
3854                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3855 
3856                     if (isnanl (arg))
3857                       {
3858                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3859                           {
3860                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3861                           }
3862                         else
3863                           {
3864                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3865                           }
3866                       }
3867                     else
3868                       {
3869                         int sign = 0;
3870                         DECL_LONG_DOUBLE_ROUNDING
3871 
3872                         BEGIN_LONG_DOUBLE_ROUNDING ();
3873 
3874                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3875                           {
3876                             sign = -1;
3877                             arg = -arg;
3878                           }
3879 
3880                         if (sign < 0)
3881                           *p++ = '-';
3882                         else if (flags & FLAG_SHOWSIGN)
3883                           *p++ = '+';
3884                         else if (flags & FLAG_SPACE)
3885                           *p++ = ' ';
3886 
3887                         if (arg > 0.0L && arg + arg == arg)
3888                           {
3889                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3890                               {
3891                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3892                               }
3893                             else
3894                               {
3895                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3896                               }
3897                           }
3898                         else
3899                           {
3900 #  if NEED_PRINTF_LONG_DOUBLE
3901                             pad_ptr = p;
3902 
3903                             if (dp->conversion == 'f' || dp->conversion == 'F')
3904                               {
3905                                 char *digits;
3906                                 size_t ndigits;
3907 
3908                                 digits =
3909                                   scale10_round_decimal_long_double (arg, precision);
3910                                 if (digits == NULL)
3911                                   {
3912                                     END_LONG_DOUBLE_ROUNDING ();
3913                                     goto out_of_memory;
3914                                   }
3915                                 ndigits = strlen (digits);
3916 
3917                                 if (ndigits > precision)
3918                                   do
3919                                     {
3920                                       --ndigits;
3921                                       *p++ = digits[ndigits];
3922                                     }
3923                                   while (ndigits > precision);
3924                                 else
3925                                   *p++ = '0';
3926                                 /* Here ndigits <= precision.  */
3927                                 if ((flags & FLAG_ALT) || precision > 0)
3928                                   {
3929                                     *p++ = decimal_point_char ();
3930                                     for (; precision > ndigits; precision--)
3931                                       *p++ = '0';
3932                                     while (ndigits > 0)
3933                                       {
3934                                         --ndigits;
3935                                         *p++ = digits[ndigits];
3936                                       }
3937                                   }
3938 
3939                                 free (digits);
3940                               }
3941                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3942                               {
3943                                 int exponent;
3944 
3945                                 if (arg == 0.0L)
3946                                   {
3947                                     exponent = 0;
3948                                     *p++ = '0';
3949                                     if ((flags & FLAG_ALT) || precision > 0)
3950                                       {
3951                                         *p++ = decimal_point_char ();
3952                                         for (; precision > 0; precision--)
3953                                           *p++ = '0';
3954                                       }
3955                                   }
3956                                 else
3957                                   {
3958                                     /* arg > 0.0L.  */
3959                                     int adjusted;
3960                                     char *digits;
3961                                     size_t ndigits;
3962 
3963                                     exponent = floorlog10l (arg);
3964                                     adjusted = 0;
3965                                     for (;;)
3966                                       {
3967                                         digits =
3968                                           scale10_round_decimal_long_double (arg,
3969                                                                              (int)precision - exponent);
3970                                         if (digits == NULL)
3971                                           {
3972                                             END_LONG_DOUBLE_ROUNDING ();
3973                                             goto out_of_memory;
3974                                           }
3975                                         ndigits = strlen (digits);
3976 
3977                                         if (ndigits == precision + 1)
3978                                           break;
3979                                         if (ndigits < precision
3980                                             || ndigits > precision + 2)
3981                                           /* The exponent was not guessed
3982                                              precisely enough.  */
3983                                           abort ();
3984                                         if (adjusted)
3985                                           /* None of two values of exponent is
3986                                              the right one.  Prevent an endless
3987                                              loop.  */
3988                                           abort ();
3989                                         free (digits);
3990                                         if (ndigits == precision)
3991                                           exponent -= 1;
3992                                         else
3993                                           exponent += 1;
3994                                         adjusted = 1;
3995                                       }
3996                                     /* Here ndigits = precision+1.  */
3997                                     if (is_borderline (digits, precision))
3998                                       {
3999                                         /* Maybe the exponent guess was too high
4000                                            and a smaller exponent can be reached
4001                                            by turning a 10...0 into 9...9x.  */
4002                                         char *digits2 =
4003                                           scale10_round_decimal_long_double (arg,
4004                                                                              (int)precision - exponent + 1);
4005                                         if (digits2 == NULL)
4006                                           {
4007                                             free (digits);
4008                                             END_LONG_DOUBLE_ROUNDING ();
4009                                             goto out_of_memory;
4010                                           }
4011                                         if (strlen (digits2) == precision + 1)
4012                                           {
4013                                             free (digits);
4014                                             digits = digits2;
4015                                             exponent -= 1;
4016                                           }
4017                                         else
4018                                           free (digits2);
4019                                       }
4020                                     /* Here ndigits = precision+1.  */
4021 
4022                                     *p++ = digits[--ndigits];
4023                                     if ((flags & FLAG_ALT) || precision > 0)
4024                                       {
4025                                         *p++ = decimal_point_char ();
4026                                         while (ndigits > 0)
4027                                           {
4028                                             --ndigits;
4029                                             *p++ = digits[ndigits];
4030                                           }
4031                                       }
4032 
4033                                     free (digits);
4034                                   }
4035 
4036                                 *p++ = dp->conversion; /* 'e' or 'E' */
4037 #   if WIDE_CHAR_VERSION
4038                                 {
4039                                   static const wchar_t decimal_format[] =
4040                                     { '%', '+', '.', '2', 'd', '\0' };
4041                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
4042                                 }
4043                                 while (*p != '\0')
4044                                   p++;
4045 #   else
4046                                 if (sizeof (DCHAR_T) == 1)
4047                                   {
4048                                     sprintf ((char *) p, "%+.2d", exponent);
4049                                     while (*p != '\0')
4050                                       p++;
4051                                   }
4052                                 else
4053                                   {
4054                                     char expbuf[6 + 1];
4055                                     const char *ep;
4056                                     sprintf (expbuf, "%+.2d", exponent);
4057                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4058                                       p++;
4059                                   }
4060 #   endif
4061                               }
4062                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4063                               {
4064                                 if (precision == 0)
4065                                   precision = 1;
4066                                 /* precision >= 1.  */
4067 
4068                                 if (arg == 0.0L)
4069                                   /* The exponent is 0, >= -4, < precision.
4070                                      Use fixed-point notation.  */
4071                                   {
4072                                     size_t ndigits = precision;
4073                                     /* Number of trailing zeroes that have to be
4074                                        dropped.  */
4075                                     size_t nzeroes =
4076                                       (flags & FLAG_ALT ? 0 : precision - 1);
4077 
4078                                     --ndigits;
4079                                     *p++ = '0';
4080                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
4081                                       {
4082                                         *p++ = decimal_point_char ();
4083                                         while (ndigits > nzeroes)
4084                                           {
4085                                             --ndigits;
4086                                             *p++ = '0';
4087                                           }
4088                                       }
4089                                   }
4090                                 else
4091                                   {
4092                                     /* arg > 0.0L.  */
4093                                     int exponent;
4094                                     int adjusted;
4095                                     char *digits;
4096                                     size_t ndigits;
4097                                     size_t nzeroes;
4098 
4099                                     exponent = floorlog10l (arg);
4100                                     adjusted = 0;
4101                                     for (;;)
4102                                       {
4103                                         digits =
4104                                           scale10_round_decimal_long_double (arg,
4105                                                                              (int)(precision - 1) - exponent);
4106                                         if (digits == NULL)
4107                                           {
4108                                             END_LONG_DOUBLE_ROUNDING ();
4109                                             goto out_of_memory;
4110                                           }
4111                                         ndigits = strlen (digits);
4112 
4113                                         if (ndigits == precision)
4114                                           break;
4115                                         if (ndigits < precision - 1
4116                                             || ndigits > precision + 1)
4117                                           /* The exponent was not guessed
4118                                              precisely enough.  */
4119                                           abort ();
4120                                         if (adjusted)
4121                                           /* None of two values of exponent is
4122                                              the right one.  Prevent an endless
4123                                              loop.  */
4124                                           abort ();
4125                                         free (digits);
4126                                         if (ndigits < precision)
4127                                           exponent -= 1;
4128                                         else
4129                                           exponent += 1;
4130                                         adjusted = 1;
4131                                       }
4132                                     /* Here ndigits = precision.  */
4133                                     if (is_borderline (digits, precision - 1))
4134                                       {
4135                                         /* Maybe the exponent guess was too high
4136                                            and a smaller exponent can be reached
4137                                            by turning a 10...0 into 9...9x.  */
4138                                         char *digits2 =
4139                                           scale10_round_decimal_long_double (arg,
4140                                                                              (int)(precision - 1) - exponent + 1);
4141                                         if (digits2 == NULL)
4142                                           {
4143                                             free (digits);
4144                                             END_LONG_DOUBLE_ROUNDING ();
4145                                             goto out_of_memory;
4146                                           }
4147                                         if (strlen (digits2) == precision)
4148                                           {
4149                                             free (digits);
4150                                             digits = digits2;
4151                                             exponent -= 1;
4152                                           }
4153                                         else
4154                                           free (digits2);
4155                                       }
4156                                     /* Here ndigits = precision.  */
4157 
4158                                     /* Determine the number of trailing zeroes
4159                                        that have to be dropped.  */
4160                                     nzeroes = 0;
4161                                     if ((flags & FLAG_ALT) == 0)
4162                                       while (nzeroes < ndigits
4163                                              && digits[nzeroes] == '0')
4164                                         nzeroes++;
4165 
4166                                     /* The exponent is now determined.  */
4167                                     if (exponent >= -4
4168                                         && exponent < (long)precision)
4169                                       {
4170                                         /* Fixed-point notation:
4171                                            max(exponent,0)+1 digits, then the
4172                                            decimal point, then the remaining
4173                                            digits without trailing zeroes.  */
4174                                         if (exponent >= 0)
4175                                           {
4176                                             size_t ecount = exponent + 1;
4177                                             /* Note: count <= precision = ndigits.  */
4178                                             for (; ecount > 0; ecount--)
4179                                               *p++ = digits[--ndigits];
4180                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
4181                                               {
4182                                                 *p++ = decimal_point_char ();
4183                                                 while (ndigits > nzeroes)
4184                                                   {
4185                                                     --ndigits;
4186                                                     *p++ = digits[ndigits];
4187                                                   }
4188                                               }
4189                                           }
4190                                         else
4191                                           {
4192                                             size_t ecount = -exponent - 1;
4193                                             *p++ = '0';
4194                                             *p++ = decimal_point_char ();
4195                                             for (; ecount > 0; ecount--)
4196                                               *p++ = '0';
4197                                             while (ndigits > nzeroes)
4198                                               {
4199                                                 --ndigits;
4200                                                 *p++ = digits[ndigits];
4201                                               }
4202                                           }
4203                                       }
4204                                     else
4205                                       {
4206                                         /* Exponential notation.  */
4207                                         *p++ = digits[--ndigits];
4208                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
4209                                           {
4210                                             *p++ = decimal_point_char ();
4211                                             while (ndigits > nzeroes)
4212                                               {
4213                                                 --ndigits;
4214                                                 *p++ = digits[ndigits];
4215                                               }
4216                                           }
4217                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4218 #   if WIDE_CHAR_VERSION
4219                                         {
4220                                           static const wchar_t decimal_format[] =
4221                                             { '%', '+', '.', '2', 'd', '\0' };
4222                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
4223                                         }
4224                                         while (*p != '\0')
4225                                           p++;
4226 #   else
4227                                         if (sizeof (DCHAR_T) == 1)
4228                                           {
4229                                             sprintf ((char *) p, "%+.2d", exponent);
4230                                             while (*p != '\0')
4231                                               p++;
4232                                           }
4233                                         else
4234                                           {
4235                                             char expbuf[6 + 1];
4236                                             const char *ep;
4237                                             sprintf (expbuf, "%+.2d", exponent);
4238                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4239                                               p++;
4240                                           }
4241 #   endif
4242                                       }
4243 
4244                                     free (digits);
4245                                   }
4246                               }
4247                             else
4248                               abort ();
4249 #  else
4250                             /* arg is finite.  */
4251                             if (!(arg == 0.0L))
4252                               abort ();
4253 
4254                             pad_ptr = p;
4255 
4256                             if (dp->conversion == 'f' || dp->conversion == 'F')
4257                               {
4258                                 *p++ = '0';
4259                                 if ((flags & FLAG_ALT) || precision > 0)
4260                                   {
4261                                     *p++ = decimal_point_char ();
4262                                     for (; precision > 0; precision--)
4263                                       *p++ = '0';
4264                                   }
4265                               }
4266                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4267                               {
4268                                 *p++ = '0';
4269                                 if ((flags & FLAG_ALT) || precision > 0)
4270                                   {
4271                                     *p++ = decimal_point_char ();
4272                                     for (; precision > 0; precision--)
4273                                       *p++ = '0';
4274                                   }
4275                                 *p++ = dp->conversion; /* 'e' or 'E' */
4276                                 *p++ = '+';
4277                                 *p++ = '0';
4278                                 *p++ = '0';
4279                               }
4280                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4281                               {
4282                                 *p++ = '0';
4283                                 if (flags & FLAG_ALT)
4284                                   {
4285                                     size_t ndigits =
4286                                       (precision > 0 ? precision - 1 : 0);
4287                                     *p++ = decimal_point_char ();
4288                                     for (; ndigits > 0; --ndigits)
4289                                       *p++ = '0';
4290                                   }
4291                               }
4292                             else if (dp->conversion == 'a' || dp->conversion == 'A')
4293                               {
4294                                 *p++ = '0';
4295                                 *p++ = dp->conversion - 'A' + 'X';
4296                                 pad_ptr = p;
4297                                 *p++ = '0';
4298                                 if ((flags & FLAG_ALT) || precision > 0)
4299                                   {
4300                                     *p++ = decimal_point_char ();
4301                                     for (; precision > 0; precision--)
4302                                       *p++ = '0';
4303                                   }
4304                                 *p++ = dp->conversion - 'A' + 'P';
4305                                 *p++ = '+';
4306                                 *p++ = '0';
4307                               }
4308                             else
4309                               abort ();
4310 #  endif
4311                           }
4312 
4313                         END_LONG_DOUBLE_ROUNDING ();
4314                       }
4315                   }
4316 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4317                 else
4318 #  endif
4319 # endif
4320 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4321                   {
4322                     double arg = a.arg[dp->arg_index].a.a_double;
4323 
4324                     if (isnand (arg))
4325                       {
4326                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4327                           {
4328                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4329                           }
4330                         else
4331                           {
4332                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4333                           }
4334                       }
4335                     else
4336                       {
4337                         int sign = 0;
4338 
4339                         if (signbit (arg)) /* arg < 0.0 or negative zero */
4340                           {
4341                             sign = -1;
4342                             arg = -arg;
4343                           }
4344 
4345                         if (sign < 0)
4346                           *p++ = '-';
4347                         else if (flags & FLAG_SHOWSIGN)
4348                           *p++ = '+';
4349                         else if (flags & FLAG_SPACE)
4350                           *p++ = ' ';
4351 
4352                         if (arg > 0.0 && arg + arg == arg)
4353                           {
4354                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4355                               {
4356                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4357                               }
4358                             else
4359                               {
4360                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4361                               }
4362                           }
4363                         else
4364                           {
4365 #  if NEED_PRINTF_DOUBLE
4366                             pad_ptr = p;
4367 
4368                             if (dp->conversion == 'f' || dp->conversion == 'F')
4369                               {
4370                                 char *digits;
4371                                 size_t ndigits;
4372 
4373                                 digits =
4374                                   scale10_round_decimal_double (arg, precision);
4375                                 if (digits == NULL)
4376                                   goto out_of_memory;
4377                                 ndigits = strlen (digits);
4378 
4379                                 if (ndigits > precision)
4380                                   do
4381                                     {
4382                                       --ndigits;
4383                                       *p++ = digits[ndigits];
4384                                     }
4385                                   while (ndigits > precision);
4386                                 else
4387                                   *p++ = '0';
4388                                 /* Here ndigits <= precision.  */
4389                                 if ((flags & FLAG_ALT) || precision > 0)
4390                                   {
4391                                     *p++ = decimal_point_char ();
4392                                     for (; precision > ndigits; precision--)
4393                                       *p++ = '0';
4394                                     while (ndigits > 0)
4395                                       {
4396                                         --ndigits;
4397                                         *p++ = digits[ndigits];
4398                                       }
4399                                   }
4400 
4401                                 free (digits);
4402                               }
4403                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4404                               {
4405                                 int exponent;
4406 
4407                                 if (arg == 0.0)
4408                                   {
4409                                     exponent = 0;
4410                                     *p++ = '0';
4411                                     if ((flags & FLAG_ALT) || precision > 0)
4412                                       {
4413                                         *p++ = decimal_point_char ();
4414                                         for (; precision > 0; precision--)
4415                                           *p++ = '0';
4416                                       }
4417                                   }
4418                                 else
4419                                   {
4420                                     /* arg > 0.0.  */
4421                                     int adjusted;
4422                                     char *digits;
4423                                     size_t ndigits;
4424 
4425                                     exponent = floorlog10 (arg);
4426                                     adjusted = 0;
4427                                     for (;;)
4428                                       {
4429                                         digits =
4430                                           scale10_round_decimal_double (arg,
4431                                                                         (int)precision - exponent);
4432                                         if (digits == NULL)
4433                                           goto out_of_memory;
4434                                         ndigits = strlen (digits);
4435 
4436                                         if (ndigits == precision + 1)
4437                                           break;
4438                                         if (ndigits < precision
4439                                             || ndigits > precision + 2)
4440                                           /* The exponent was not guessed
4441                                              precisely enough.  */
4442                                           abort ();
4443                                         if (adjusted)
4444                                           /* None of two values of exponent is
4445                                              the right one.  Prevent an endless
4446                                              loop.  */
4447                                           abort ();
4448                                         free (digits);
4449                                         if (ndigits == precision)
4450                                           exponent -= 1;
4451                                         else
4452                                           exponent += 1;
4453                                         adjusted = 1;
4454                                       }
4455                                     /* Here ndigits = precision+1.  */
4456                                     if (is_borderline (digits, precision))
4457                                       {
4458                                         /* Maybe the exponent guess was too high
4459                                            and a smaller exponent can be reached
4460                                            by turning a 10...0 into 9...9x.  */
4461                                         char *digits2 =
4462                                           scale10_round_decimal_double (arg,
4463                                                                         (int)precision - exponent + 1);
4464                                         if (digits2 == NULL)
4465                                           {
4466                                             free (digits);
4467                                             goto out_of_memory;
4468                                           }
4469                                         if (strlen (digits2) == precision + 1)
4470                                           {
4471                                             free (digits);
4472                                             digits = digits2;
4473                                             exponent -= 1;
4474                                           }
4475                                         else
4476                                           free (digits2);
4477                                       }
4478                                     /* Here ndigits = precision+1.  */
4479 
4480                                     *p++ = digits[--ndigits];
4481                                     if ((flags & FLAG_ALT) || precision > 0)
4482                                       {
4483                                         *p++ = decimal_point_char ();
4484                                         while (ndigits > 0)
4485                                           {
4486                                             --ndigits;
4487                                             *p++ = digits[ndigits];
4488                                           }
4489                                       }
4490 
4491                                     free (digits);
4492                                   }
4493 
4494                                 *p++ = dp->conversion; /* 'e' or 'E' */
4495 #   if WIDE_CHAR_VERSION
4496                                 {
4497                                   static const wchar_t decimal_format[] =
4498                                     /* Produce the same number of exponent digits
4499                                        as the native printf implementation.  */
4500 #    if defined _WIN32 && ! defined __CYGWIN__
4501                                     { '%', '+', '.', '3', 'd', '\0' };
4502 #    else
4503                                     { '%', '+', '.', '2', 'd', '\0' };
4504 #    endif
4505                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
4506                                 }
4507                                 while (*p != '\0')
4508                                   p++;
4509 #   else
4510                                 {
4511                                   static const char decimal_format[] =
4512                                     /* Produce the same number of exponent digits
4513                                        as the native printf implementation.  */
4514 #    if defined _WIN32 && ! defined __CYGWIN__
4515                                     "%+.3d";
4516 #    else
4517                                     "%+.2d";
4518 #    endif
4519                                   if (sizeof (DCHAR_T) == 1)
4520                                     {
4521                                       sprintf ((char *) p, decimal_format, exponent);
4522                                       while (*p != '\0')
4523                                         p++;
4524                                     }
4525                                   else
4526                                     {
4527                                       char expbuf[6 + 1];
4528                                       const char *ep;
4529                                       sprintf (expbuf, decimal_format, exponent);
4530                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4531                                         p++;
4532                                     }
4533                                 }
4534 #   endif
4535                               }
4536                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4537                               {
4538                                 if (precision == 0)
4539                                   precision = 1;
4540                                 /* precision >= 1.  */
4541 
4542                                 if (arg == 0.0)
4543                                   /* The exponent is 0, >= -4, < precision.
4544                                      Use fixed-point notation.  */
4545                                   {
4546                                     size_t ndigits = precision;
4547                                     /* Number of trailing zeroes that have to be
4548                                        dropped.  */
4549                                     size_t nzeroes =
4550                                       (flags & FLAG_ALT ? 0 : precision - 1);
4551 
4552                                     --ndigits;
4553                                     *p++ = '0';
4554                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
4555                                       {
4556                                         *p++ = decimal_point_char ();
4557                                         while (ndigits > nzeroes)
4558                                           {
4559                                             --ndigits;
4560                                             *p++ = '0';
4561                                           }
4562                                       }
4563                                   }
4564                                 else
4565                                   {
4566                                     /* arg > 0.0.  */
4567                                     int exponent;
4568                                     int adjusted;
4569                                     char *digits;
4570                                     size_t ndigits;
4571                                     size_t nzeroes;
4572 
4573                                     exponent = floorlog10 (arg);
4574                                     adjusted = 0;
4575                                     for (;;)
4576                                       {
4577                                         digits =
4578                                           scale10_round_decimal_double (arg,
4579                                                                         (int)(precision - 1) - exponent);
4580                                         if (digits == NULL)
4581                                           goto out_of_memory;
4582                                         ndigits = strlen (digits);
4583 
4584                                         if (ndigits == precision)
4585                                           break;
4586                                         if (ndigits < precision - 1
4587                                             || ndigits > precision + 1)
4588                                           /* The exponent was not guessed
4589                                              precisely enough.  */
4590                                           abort ();
4591                                         if (adjusted)
4592                                           /* None of two values of exponent is
4593                                              the right one.  Prevent an endless
4594                                              loop.  */
4595                                           abort ();
4596                                         free (digits);
4597                                         if (ndigits < precision)
4598                                           exponent -= 1;
4599                                         else
4600                                           exponent += 1;
4601                                         adjusted = 1;
4602                                       }
4603                                     /* Here ndigits = precision.  */
4604                                     if (is_borderline (digits, precision - 1))
4605                                       {
4606                                         /* Maybe the exponent guess was too high
4607                                            and a smaller exponent can be reached
4608                                            by turning a 10...0 into 9...9x.  */
4609                                         char *digits2 =
4610                                           scale10_round_decimal_double (arg,
4611                                                                         (int)(precision - 1) - exponent + 1);
4612                                         if (digits2 == NULL)
4613                                           {
4614                                             free (digits);
4615                                             goto out_of_memory;
4616                                           }
4617                                         if (strlen (digits2) == precision)
4618                                           {
4619                                             free (digits);
4620                                             digits = digits2;
4621                                             exponent -= 1;
4622                                           }
4623                                         else
4624                                           free (digits2);
4625                                       }
4626                                     /* Here ndigits = precision.  */
4627 
4628                                     /* Determine the number of trailing zeroes
4629                                        that have to be dropped.  */
4630                                     nzeroes = 0;
4631                                     if ((flags & FLAG_ALT) == 0)
4632                                       while (nzeroes < ndigits
4633                                              && digits[nzeroes] == '0')
4634                                         nzeroes++;
4635 
4636                                     /* The exponent is now determined.  */
4637                                     if (exponent >= -4
4638                                         && exponent < (long)precision)
4639                                       {
4640                                         /* Fixed-point notation:
4641                                            max(exponent,0)+1 digits, then the
4642                                            decimal point, then the remaining
4643                                            digits without trailing zeroes.  */
4644                                         if (exponent >= 0)
4645                                           {
4646                                             size_t ecount = exponent + 1;
4647                                             /* Note: ecount <= precision = ndigits.  */
4648                                             for (; ecount > 0; ecount--)
4649                                               *p++ = digits[--ndigits];
4650                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
4651                                               {
4652                                                 *p++ = decimal_point_char ();
4653                                                 while (ndigits > nzeroes)
4654                                                   {
4655                                                     --ndigits;
4656                                                     *p++ = digits[ndigits];
4657                                                   }
4658                                               }
4659                                           }
4660                                         else
4661                                           {
4662                                             size_t ecount = -exponent - 1;
4663                                             *p++ = '0';
4664                                             *p++ = decimal_point_char ();
4665                                             for (; ecount > 0; ecount--)
4666                                               *p++ = '0';
4667                                             while (ndigits > nzeroes)
4668                                               {
4669                                                 --ndigits;
4670                                                 *p++ = digits[ndigits];
4671                                               }
4672                                           }
4673                                       }
4674                                     else
4675                                       {
4676                                         /* Exponential notation.  */
4677                                         *p++ = digits[--ndigits];
4678                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
4679                                           {
4680                                             *p++ = decimal_point_char ();
4681                                             while (ndigits > nzeroes)
4682                                               {
4683                                                 --ndigits;
4684                                                 *p++ = digits[ndigits];
4685                                               }
4686                                           }
4687                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4688 #   if WIDE_CHAR_VERSION
4689                                         {
4690                                           static const wchar_t decimal_format[] =
4691                                             /* Produce the same number of exponent digits
4692                                                as the native printf implementation.  */
4693 #    if defined _WIN32 && ! defined __CYGWIN__
4694                                             { '%', '+', '.', '3', 'd', '\0' };
4695 #    else
4696                                             { '%', '+', '.', '2', 'd', '\0' };
4697 #    endif
4698                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
4699                                         }
4700                                         while (*p != '\0')
4701                                           p++;
4702 #   else
4703                                         {
4704                                           static const char decimal_format[] =
4705                                             /* Produce the same number of exponent digits
4706                                                as the native printf implementation.  */
4707 #    if defined _WIN32 && ! defined __CYGWIN__
4708                                             "%+.3d";
4709 #    else
4710                                             "%+.2d";
4711 #    endif
4712                                           if (sizeof (DCHAR_T) == 1)
4713                                             {
4714                                               sprintf ((char *) p, decimal_format, exponent);
4715                                               while (*p != '\0')
4716                                                 p++;
4717                                             }
4718                                           else
4719                                             {
4720                                               char expbuf[6 + 1];
4721                                               const char *ep;
4722                                               sprintf (expbuf, decimal_format, exponent);
4723                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4724                                                 p++;
4725                                             }
4726                                         }
4727 #   endif
4728                                       }
4729 
4730                                     free (digits);
4731                                   }
4732                               }
4733                             else
4734                               abort ();
4735 #  else
4736                             /* arg is finite.  */
4737                             if (!(arg == 0.0))
4738                               abort ();
4739 
4740                             pad_ptr = p;
4741 
4742                             if (dp->conversion == 'f' || dp->conversion == 'F')
4743                               {
4744                                 *p++ = '0';
4745                                 if ((flags & FLAG_ALT) || precision > 0)
4746                                   {
4747                                     *p++ = decimal_point_char ();
4748                                     for (; precision > 0; precision--)
4749                                       *p++ = '0';
4750                                   }
4751                               }
4752                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4753                               {
4754                                 *p++ = '0';
4755                                 if ((flags & FLAG_ALT) || precision > 0)
4756                                   {
4757                                     *p++ = decimal_point_char ();
4758                                     for (; precision > 0; precision--)
4759                                       *p++ = '0';
4760                                   }
4761                                 *p++ = dp->conversion; /* 'e' or 'E' */
4762                                 *p++ = '+';
4763                                 /* Produce the same number of exponent digits as
4764                                    the native printf implementation.  */
4765 #   if defined _WIN32 && ! defined __CYGWIN__
4766                                 *p++ = '0';
4767 #   endif
4768                                 *p++ = '0';
4769                                 *p++ = '0';
4770                               }
4771                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4772                               {
4773                                 *p++ = '0';
4774                                 if (flags & FLAG_ALT)
4775                                   {
4776                                     size_t ndigits =
4777                                       (precision > 0 ? precision - 1 : 0);
4778                                     *p++ = decimal_point_char ();
4779                                     for (; ndigits > 0; --ndigits)
4780                                       *p++ = '0';
4781                                   }
4782                               }
4783                             else
4784                               abort ();
4785 #  endif
4786                           }
4787                       }
4788                   }
4789 # endif
4790 
4791                 /* The generated string now extends from tmp to p, with the
4792                    zero padding insertion point being at pad_ptr.  */
4793                 count = p - tmp;
4794 
4795                 if (count < width)
4796                   {
4797                     size_t pad = width - count;
4798                     DCHAR_T *end = p + pad;
4799 
4800                     if (flags & FLAG_LEFT)
4801                       {
4802                         /* Pad with spaces on the right.  */
4803                         for (; pad > 0; pad--)
4804                           *p++ = ' ';
4805                       }
4806                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4807                       {
4808                         /* Pad with zeroes.  */
4809                         DCHAR_T *q = end;
4810 
4811                         while (p > pad_ptr)
4812                           *--q = *--p;
4813                         for (; pad > 0; pad--)
4814                           *p++ = '0';
4815                       }
4816                     else
4817                       {
4818                         /* Pad with spaces on the left.  */
4819                         DCHAR_T *q = end;
4820 
4821                         while (p > tmp)
4822                           *--q = *--p;
4823                         for (; pad > 0; pad--)
4824                           *p++ = ' ';
4825                       }
4826 
4827                     p = end;
4828                   }
4829 
4830                 count = p - tmp;
4831 
4832                 if (count >= tmp_length)
4833                   /* tmp_length was incorrectly calculated - fix the
4834                      code above!  */
4835                   abort ();
4836 
4837                 /* Make room for the result.  */
4838                 if (count >= allocated - length)
4839                   {
4840                     size_t n = xsum (length, count);
4841 
4842                     ENSURE_ALLOCATION (n);
4843                   }
4844 
4845                 /* Append the result.  */
4846                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4847                 if (tmp != tmpbuf)
4848                   free (tmp);
4849                 length += count;
4850               }
4851 #endif
4852             else
4853               {
4854                 arg_type type = a.arg[dp->arg_index].type;
4855                 int flags = dp->flags;
4856 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4857                 int has_width;
4858 #endif
4859 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4860                 size_t width;
4861 #endif
4862 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4863                 int has_precision;
4864                 size_t precision;
4865 #endif
4866 #if NEED_PRINTF_UNBOUNDED_PRECISION
4867                 int prec_ourselves;
4868 #else
4869 #               define prec_ourselves 0
4870 #endif
4871 #if NEED_PRINTF_FLAG_LEFTADJUST
4872 #               define pad_ourselves 1
4873 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4874                 int pad_ourselves;
4875 #else
4876 #               define pad_ourselves 0
4877 #endif
4878                 TCHAR_T *fbp;
4879                 unsigned int prefix_count;
4880                 int prefixes[2] IF_LINT (= { 0 });
4881                 int orig_errno;
4882 #if !USE_SNPRINTF
4883                 size_t tmp_length;
4884                 TCHAR_T tmpbuf[700];
4885                 TCHAR_T *tmp;
4886 #endif
4887 
4888 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4889                 has_width = 0;
4890 #endif
4891 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4892                 width = 0;
4893                 if (dp->width_start != dp->width_end)
4894                   {
4895                     if (dp->width_arg_index != ARG_NONE)
4896                       {
4897                         int arg;
4898 
4899                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4900                           abort ();
4901                         arg = a.arg[dp->width_arg_index].a.a_int;
4902                         width = arg;
4903                         if (arg < 0)
4904                           {
4905                             /* "A negative field width is taken as a '-' flag
4906                                 followed by a positive field width."  */
4907                             flags |= FLAG_LEFT;
4908                             width = -width;
4909                           }
4910                       }
4911                     else
4912                       {
4913                         const FCHAR_T *digitp = dp->width_start;
4914 
4915                         do
4916                           width = xsum (xtimes (width, 10), *digitp++ - '0');
4917                         while (digitp != dp->width_end);
4918                       }
4919 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4920                     has_width = 1;
4921 #endif
4922                   }
4923 #endif
4924 
4925 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4926                 has_precision = 0;
4927                 precision = 6;
4928                 if (dp->precision_start != dp->precision_end)
4929                   {
4930                     if (dp->precision_arg_index != ARG_NONE)
4931                       {
4932                         int arg;
4933 
4934                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4935                           abort ();
4936                         arg = a.arg[dp->precision_arg_index].a.a_int;
4937                         /* "A negative precision is taken as if the precision
4938                             were omitted."  */
4939                         if (arg >= 0)
4940                           {
4941                             precision = arg;
4942                             has_precision = 1;
4943                           }
4944                       }
4945                     else
4946                       {
4947                         const FCHAR_T *digitp = dp->precision_start + 1;
4948 
4949                         precision = 0;
4950                         while (digitp != dp->precision_end)
4951                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4952                         has_precision = 1;
4953                       }
4954                   }
4955 #endif
4956 
4957                 /* Decide whether to handle the precision ourselves.  */
4958 #if NEED_PRINTF_UNBOUNDED_PRECISION
4959                 switch (dp->conversion)
4960                   {
4961                   case 'd': case 'i': case 'u':
4962                   case 'o':
4963                   case 'x': case 'X': case 'p':
4964                     prec_ourselves = has_precision && (precision > 0);
4965                     break;
4966                   default:
4967                     prec_ourselves = 0;
4968                     break;
4969                   }
4970 #endif
4971 
4972                 /* Decide whether to perform the padding ourselves.  */
4973 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4974                 switch (dp->conversion)
4975                   {
4976 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4977                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4978                      to perform the padding after this conversion.  Functions
4979                      with unistdio extensions perform the padding based on
4980                      character count rather than element count.  */
4981                   case 'c': case 's':
4982 # endif
4983 # if NEED_PRINTF_FLAG_ZERO
4984                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4985                   case 'a': case 'A':
4986 # endif
4987                     pad_ourselves = 1;
4988                     break;
4989                   default:
4990                     pad_ourselves = prec_ourselves;
4991                     break;
4992                   }
4993 #endif
4994 
4995 #if !USE_SNPRINTF
4996                 /* Allocate a temporary buffer of sufficient size for calling
4997                    sprintf.  */
4998                 tmp_length =
4999                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
5000                                    flags, width, has_precision, precision,
5001                                    pad_ourselves);
5002 
5003                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
5004                   tmp = tmpbuf;
5005                 else
5006                   {
5007                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
5008 
5009                     if (size_overflow_p (tmp_memsize))
5010                       /* Overflow, would lead to out of memory.  */
5011                       goto out_of_memory;
5012                     tmp = (TCHAR_T *) malloc (tmp_memsize);
5013                     if (tmp == NULL)
5014                       /* Out of memory.  */
5015                       goto out_of_memory;
5016                   }
5017 #endif
5018 
5019                 /* Construct the format string for calling snprintf or
5020                    sprintf.  */
5021                 fbp = buf;
5022                 *fbp++ = '%';
5023 #if NEED_PRINTF_FLAG_GROUPING
5024                 /* The underlying implementation doesn't support the ' flag.
5025                    Produce no grouping characters in this case; this is
5026                    acceptable because the grouping is locale dependent.  */
5027 #else
5028                 if (flags & FLAG_GROUP)
5029                   *fbp++ = '\'';
5030 #endif
5031                 if (flags & FLAG_LEFT)
5032                   *fbp++ = '-';
5033                 if (flags & FLAG_SHOWSIGN)
5034                   *fbp++ = '+';
5035                 if (flags & FLAG_SPACE)
5036                   *fbp++ = ' ';
5037                 if (flags & FLAG_ALT)
5038                   *fbp++ = '#';
5039 #if __GLIBC__ >= 2 && !defined __UCLIBC__
5040                 if (flags & FLAG_LOCALIZED)
5041                   *fbp++ = 'I';
5042 #endif
5043                 if (!pad_ourselves)
5044                   {
5045                     if (flags & FLAG_ZERO)
5046                       *fbp++ = '0';
5047                     if (dp->width_start != dp->width_end)
5048                       {
5049                         size_t n = dp->width_end - dp->width_start;
5050                         /* The width specification is known to consist only
5051                            of standard ASCII characters.  */
5052                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
5053                           {
5054                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
5055                             fbp += n;
5056                           }
5057                         else
5058                           {
5059                             const FCHAR_T *mp = dp->width_start;
5060                             do
5061                               *fbp++ = *mp++;
5062                             while (--n > 0);
5063                           }
5064                       }
5065                   }
5066                 if (!prec_ourselves)
5067                   {
5068                     if (dp->precision_start != dp->precision_end)
5069                       {
5070                         size_t n = dp->precision_end - dp->precision_start;
5071                         /* The precision specification is known to consist only
5072                            of standard ASCII characters.  */
5073                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
5074                           {
5075                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
5076                             fbp += n;
5077                           }
5078                         else
5079                           {
5080                             const FCHAR_T *mp = dp->precision_start;
5081                             do
5082                               *fbp++ = *mp++;
5083                             while (--n > 0);
5084                           }
5085                       }
5086                   }
5087 
5088                 switch (type)
5089                   {
5090                   case TYPE_LONGLONGINT:
5091                   case TYPE_ULONGLONGINT:
5092 #if defined _WIN32 && ! defined __CYGWIN__
5093                     *fbp++ = 'I';
5094                     *fbp++ = '6';
5095                     *fbp++ = '4';
5096                     break;
5097 #else
5098                     *fbp++ = 'l';
5099 #endif
5100                     FALLTHROUGH;
5101                   case TYPE_LONGINT:
5102                   case TYPE_ULONGINT:
5103 #if HAVE_WINT_T
5104                   case TYPE_WIDE_CHAR:
5105 #endif
5106 #if HAVE_WCHAR_T
5107                   case TYPE_WIDE_STRING:
5108 #endif
5109                     *fbp++ = 'l';
5110                     break;
5111                   case TYPE_LONGDOUBLE:
5112                     *fbp++ = 'L';
5113                     break;
5114                   default:
5115                     break;
5116                   }
5117 #if NEED_PRINTF_DIRECTIVE_F
5118                 if (dp->conversion == 'F')
5119                   *fbp = 'f';
5120                 else
5121 #endif
5122                   *fbp = dp->conversion;
5123 #if USE_SNPRINTF
5124 # if ((HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99)            \
5125       || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))       \
5126           && !defined __UCLIBC__)                                           \
5127       || (defined __APPLE__ && defined __MACH__)                            \
5128       || defined __ANDROID__                                                \
5129       || (defined _WIN32 && ! defined __CYGWIN__))
5130                 /* On systems where we know that snprintf's return value
5131                    conforms to ISO C 99 (HAVE_SNPRINTF_RETVAL_C99) and that
5132                    snprintf always produces NUL-terminated strings
5133                    (HAVE_SNPRINTF_TRUNCATION_C99), it is possible to avoid
5134                    using %n.  And it is desirable to do so, because more and
5135                    more platforms no longer support %n, for "security reasons".
5136                    In particular, the following platforms:
5137                      - On glibc2 systems from 2004-10-18 or newer, the use of
5138                        %n in format strings in writable memory may crash the
5139                        program (if compiled with _FORTIFY_SOURCE=2).
5140                      - On Mac OS X 10.13 or newer, the use of %n in format
5141                        strings in writable memory by default crashes the
5142                        program.
5143                      - On Android, starting on 2018-03-07, the use of %n in
5144                        format strings produces a fatal error (see
5145                        <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
5146                    On these platforms, HAVE_SNPRINTF_RETVAL_C99 and
5147                    HAVE_SNPRINTF_TRUNCATION_C99 are 1. We have listed them
5148                    explicitly in the condition above, in case of cross-
5149                    compilation (just to be sure).  */
5150                 /* On native Windows systems (such as mingw), we can avoid using
5151                    %n because:
5152                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
5153                        snprintf does not write more than the specified number
5154                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
5155                        '4', '5', '6' into buf, not '4', '5', '\0'.)
5156                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
5157                        allows us to recognize the case of an insufficient
5158                        buffer size: it returns -1 in this case.
5159                    On native Windows systems (such as mingw) where the OS is
5160                    Windows Vista, the use of %n in format strings by default
5161                    crashes the program. See
5162                      <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
5163                      <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
5164                    So we should avoid %n in this situation.  */
5165                 fbp[1] = '\0';
5166 # else           /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
5167                 fbp[1] = '%';
5168                 fbp[2] = 'n';
5169                 fbp[3] = '\0';
5170 # endif
5171 #else
5172                 fbp[1] = '\0';
5173 #endif
5174 
5175                 /* Construct the arguments for calling snprintf or sprintf.  */
5176                 prefix_count = 0;
5177                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
5178                   {
5179                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
5180                       abort ();
5181                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
5182                   }
5183                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
5184                   {
5185                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
5186                       abort ();
5187                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
5188                   }
5189 
5190 #if USE_SNPRINTF
5191                 /* The SNPRINTF result is appended after result[0..length].
5192                    The latter is an array of DCHAR_T; SNPRINTF appends an
5193                    array of TCHAR_T to it.  This is possible because
5194                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
5195                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
5196 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
5197                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
5198                    where an snprintf() with maxlen==1 acts like sprintf().  */
5199                 ENSURE_ALLOCATION (xsum (length,
5200                                          (2 + TCHARS_PER_DCHAR - 1)
5201                                          / TCHARS_PER_DCHAR));
5202                 /* Prepare checking whether snprintf returns the count
5203                    via %n.  */
5204                 *(TCHAR_T *) (result + length) = '\0';
5205 #endif
5206 
5207                 orig_errno = errno;
5208 
5209                 for (;;)
5210                   {
5211                     int count = -1;
5212 
5213 #if USE_SNPRINTF
5214                     int retcount = 0;
5215                     size_t maxlen = allocated - length;
5216                     /* SNPRINTF can fail if its second argument is
5217                        > INT_MAX.  */
5218                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
5219                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
5220                     maxlen = maxlen * TCHARS_PER_DCHAR;
5221 # define SNPRINTF_BUF(arg) \
5222                     switch (prefix_count)                                   \
5223                       {                                                     \
5224                       case 0:                                               \
5225                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5226                                              maxlen, buf,                   \
5227                                              arg, &count);                  \
5228                         break;                                              \
5229                       case 1:                                               \
5230                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5231                                              maxlen, buf,                   \
5232                                              prefixes[0], arg, &count);     \
5233                         break;                                              \
5234                       case 2:                                               \
5235                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5236                                              maxlen, buf,                   \
5237                                              prefixes[0], prefixes[1], arg, \
5238                                              &count);                       \
5239                         break;                                              \
5240                       default:                                              \
5241                         abort ();                                           \
5242                       }
5243 #else
5244 # define SNPRINTF_BUF(arg) \
5245                     switch (prefix_count)                                   \
5246                       {                                                     \
5247                       case 0:                                               \
5248                         count = sprintf (tmp, buf, arg);                    \
5249                         break;                                              \
5250                       case 1:                                               \
5251                         count = sprintf (tmp, buf, prefixes[0], arg);       \
5252                         break;                                              \
5253                       case 2:                                               \
5254                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
5255                                          arg);                              \
5256                         break;                                              \
5257                       default:                                              \
5258                         abort ();                                           \
5259                       }
5260 #endif
5261 
5262                     errno = 0;
5263                     switch (type)
5264                       {
5265                       case TYPE_SCHAR:
5266                         {
5267                           int arg = a.arg[dp->arg_index].a.a_schar;
5268                           SNPRINTF_BUF (arg);
5269                         }
5270                         break;
5271                       case TYPE_UCHAR:
5272                         {
5273                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
5274                           SNPRINTF_BUF (arg);
5275                         }
5276                         break;
5277                       case TYPE_SHORT:
5278                         {
5279                           int arg = a.arg[dp->arg_index].a.a_short;
5280                           SNPRINTF_BUF (arg);
5281                         }
5282                         break;
5283                       case TYPE_USHORT:
5284                         {
5285                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
5286                           SNPRINTF_BUF (arg);
5287                         }
5288                         break;
5289                       case TYPE_INT:
5290                         {
5291                           int arg = a.arg[dp->arg_index].a.a_int;
5292                           SNPRINTF_BUF (arg);
5293                         }
5294                         break;
5295                       case TYPE_UINT:
5296                         {
5297                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5298                           SNPRINTF_BUF (arg);
5299                         }
5300                         break;
5301                       case TYPE_LONGINT:
5302                         {
5303                           long int arg = a.arg[dp->arg_index].a.a_longint;
5304                           SNPRINTF_BUF (arg);
5305                         }
5306                         break;
5307                       case TYPE_ULONGINT:
5308                         {
5309                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5310                           SNPRINTF_BUF (arg);
5311                         }
5312                         break;
5313                       case TYPE_LONGLONGINT:
5314                         {
5315                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5316                           SNPRINTF_BUF (arg);
5317                         }
5318                         break;
5319                       case TYPE_ULONGLONGINT:
5320                         {
5321                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5322                           SNPRINTF_BUF (arg);
5323                         }
5324                         break;
5325                       case TYPE_DOUBLE:
5326                         {
5327                           double arg = a.arg[dp->arg_index].a.a_double;
5328                           SNPRINTF_BUF (arg);
5329                         }
5330                         break;
5331                       case TYPE_LONGDOUBLE:
5332                         {
5333                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
5334                           SNPRINTF_BUF (arg);
5335                         }
5336                         break;
5337                       case TYPE_CHAR:
5338                         {
5339                           int arg = a.arg[dp->arg_index].a.a_char;
5340                           SNPRINTF_BUF (arg);
5341                         }
5342                         break;
5343 #if HAVE_WINT_T
5344                       case TYPE_WIDE_CHAR:
5345                         {
5346                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5347                           SNPRINTF_BUF (arg);
5348                         }
5349                         break;
5350 #endif
5351                       case TYPE_STRING:
5352                         {
5353                           const char *arg = a.arg[dp->arg_index].a.a_string;
5354                           SNPRINTF_BUF (arg);
5355                         }
5356                         break;
5357 #if HAVE_WCHAR_T
5358                       case TYPE_WIDE_STRING:
5359                         {
5360                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5361                           SNPRINTF_BUF (arg);
5362                         }
5363                         break;
5364 #endif
5365                       case TYPE_POINTER:
5366                         {
5367                           void *arg = a.arg[dp->arg_index].a.a_pointer;
5368                           SNPRINTF_BUF (arg);
5369                         }
5370                         break;
5371                       default:
5372                         abort ();
5373                       }
5374 
5375 #if USE_SNPRINTF
5376                     /* Portability: Not all implementations of snprintf()
5377                        are ISO C 99 compliant.  Determine the number of
5378                        bytes that snprintf() has produced or would have
5379                        produced.  */
5380                     if (count >= 0)
5381                       {
5382                         /* Verify that snprintf() has NUL-terminated its
5383                            result.  */
5384                         if ((unsigned int) count < maxlen
5385                             && ((TCHAR_T *) (result + length)) [count] != '\0')
5386                           abort ();
5387                         /* Portability hack.  */
5388                         if (retcount > count)
5389                           count = retcount;
5390                       }
5391                     else
5392                       {
5393                         /* snprintf() doesn't understand the '%n'
5394                            directive.  */
5395                         if (fbp[1] != '\0')
5396                           {
5397                             /* Don't use the '%n' directive; instead, look
5398                                at the snprintf() return value.  */
5399                             fbp[1] = '\0';
5400                             continue;
5401                           }
5402                         else
5403                           {
5404                             /* Look at the snprintf() return value.  */
5405                             if (retcount < 0)
5406                               {
5407 # if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
5408                                 /* HP-UX 10.20 snprintf() is doubly deficient:
5409                                    It doesn't understand the '%n' directive,
5410                                    *and* it returns -1 (rather than the length
5411                                    that would have been required) when the
5412                                    buffer is too small.
5413                                    But a failure at this point can also come
5414                                    from other reasons than a too small buffer,
5415                                    such as an invalid wide string argument to
5416                                    the %ls directive, or possibly an invalid
5417                                    floating-point argument.  */
5418                                 size_t tmp_length =
5419                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
5420                                                    dp->conversion, type, flags,
5421                                                    width,
5422                                                    has_precision,
5423                                                    precision, pad_ourselves);
5424 
5425                                 if (maxlen < tmp_length)
5426                                   {
5427                                     /* Make more room.  But try to do through
5428                                        this reallocation only once.  */
5429                                     size_t bigger_need =
5430                                       xsum (length,
5431                                             xsum (tmp_length,
5432                                                   TCHARS_PER_DCHAR - 1)
5433                                             / TCHARS_PER_DCHAR);
5434                                     /* And always grow proportionally.
5435                                        (There may be several arguments, each
5436                                        needing a little more room than the
5437                                        previous one.)  */
5438                                     size_t bigger_need2 =
5439                                       xsum (xtimes (allocated, 2), 12);
5440                                     if (bigger_need < bigger_need2)
5441                                       bigger_need = bigger_need2;
5442                                     ENSURE_ALLOCATION (bigger_need);
5443                                     continue;
5444                                   }
5445 # endif
5446                               }
5447                             else
5448                               count = retcount;
5449                           }
5450                       }
5451 #endif
5452 
5453                     /* Attempt to handle failure.  */
5454                     if (count < 0)
5455                       {
5456                         /* SNPRINTF or sprintf failed.  Use the errno that it
5457                            has set, if any.  */
5458                         if (errno == 0)
5459                           {
5460                             if (dp->conversion == 'c' || dp->conversion == 's')
5461                               errno = EILSEQ;
5462                             else
5463                               errno = EINVAL;
5464                           }
5465 
5466                         if (!(result == resultbuf || result == NULL))
5467                           free (result);
5468                         if (buf_malloced != NULL)
5469                           free (buf_malloced);
5470                         CLEANUP ();
5471 
5472                         return NULL;
5473                       }
5474 
5475 #if USE_SNPRINTF
5476                     /* Handle overflow of the allocated buffer.
5477                        If such an overflow occurs, a C99 compliant snprintf()
5478                        returns a count >= maxlen.  However, a non-compliant
5479                        snprintf() function returns only count = maxlen - 1.  To
5480                        cover both cases, test whether count >= maxlen - 1.  */
5481                     if ((unsigned int) count + 1 >= maxlen)
5482                       {
5483                         /* If maxlen already has attained its allowed maximum,
5484                            allocating more memory will not increase maxlen.
5485                            Instead of looping, bail out.  */
5486                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5487                           goto overflow;
5488                         else
5489                           {
5490                             /* Need at least (count + 1) * sizeof (TCHAR_T)
5491                                bytes.  (The +1 is for the trailing NUL.)
5492                                But ask for (count + 2) * sizeof (TCHAR_T)
5493                                bytes, so that in the next round, we likely get
5494                                  maxlen > (unsigned int) count + 1
5495                                and so we don't get here again.
5496                                And allocate proportionally, to avoid looping
5497                                eternally if snprintf() reports a too small
5498                                count.  */
5499                             size_t n =
5500                               xmax (xsum (length,
5501                                           ((unsigned int) count + 2
5502                                            + TCHARS_PER_DCHAR - 1)
5503                                           / TCHARS_PER_DCHAR),
5504                                     xtimes (allocated, 2));
5505 
5506                             ENSURE_ALLOCATION (n);
5507                             continue;
5508                           }
5509                       }
5510 #endif
5511 
5512 #if NEED_PRINTF_UNBOUNDED_PRECISION
5513                     if (prec_ourselves)
5514                       {
5515                         /* Handle the precision.  */
5516                         TCHAR_T *prec_ptr =
5517 # if USE_SNPRINTF
5518                           (TCHAR_T *) (result + length);
5519 # else
5520                           tmp;
5521 # endif
5522                         size_t prefix_count;
5523                         size_t move;
5524 
5525                         prefix_count = 0;
5526                         /* Put the additional zeroes after the sign.  */
5527                         if (count >= 1
5528                             && (*prec_ptr == '-' || *prec_ptr == '+'
5529                                 || *prec_ptr == ' '))
5530                           prefix_count = 1;
5531                         /* Put the additional zeroes after the 0x prefix if
5532                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
5533                         else if (count >= 2
5534                                  && prec_ptr[0] == '0'
5535                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5536                           prefix_count = 2;
5537 
5538                         move = count - prefix_count;
5539                         if (precision > move)
5540                           {
5541                             /* Insert zeroes.  */
5542                             size_t insert = precision - move;
5543                             TCHAR_T *prec_end;
5544 
5545 # if USE_SNPRINTF
5546                             size_t n =
5547                               xsum (length,
5548                                     (count + insert + TCHARS_PER_DCHAR - 1)
5549                                     / TCHARS_PER_DCHAR);
5550                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5551                             ENSURE_ALLOCATION (n);
5552                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5553                             prec_ptr = (TCHAR_T *) (result + length);
5554 # endif
5555 
5556                             prec_end = prec_ptr + count;
5557                             prec_ptr += prefix_count;
5558 
5559                             while (prec_end > prec_ptr)
5560                               {
5561                                 prec_end--;
5562                                 prec_end[insert] = prec_end[0];
5563                               }
5564 
5565                             prec_end += insert;
5566                             do
5567                               *--prec_end = '0';
5568                             while (prec_end > prec_ptr);
5569 
5570                             count += insert;
5571                           }
5572                       }
5573 #endif
5574 
5575 #if !USE_SNPRINTF
5576                     if (count >= tmp_length)
5577                       /* tmp_length was incorrectly calculated - fix the
5578                          code above!  */
5579                       abort ();
5580 #endif
5581 
5582 #if !DCHAR_IS_TCHAR
5583                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
5584                     if (dp->conversion == 'c' || dp->conversion == 's')
5585                       {
5586                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5587                            TYPE_WIDE_STRING.
5588                            The result string is not certainly ASCII.  */
5589                         const TCHAR_T *tmpsrc;
5590                         DCHAR_T *tmpdst;
5591                         size_t tmpdst_len;
5592                         /* This code assumes that TCHAR_T is 'char'.  */
5593                         verify (sizeof (TCHAR_T) == 1);
5594 # if USE_SNPRINTF
5595                         tmpsrc = (TCHAR_T *) (result + length);
5596 # else
5597                         tmpsrc = tmp;
5598 # endif
5599                         tmpdst =
5600                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
5601                                                     iconveh_question_mark,
5602                                                     tmpsrc, count,
5603                                                     NULL,
5604                                                     NULL, &tmpdst_len);
5605                         if (tmpdst == NULL)
5606                           {
5607                             if (!(result == resultbuf || result == NULL))
5608                               free (result);
5609                             if (buf_malloced != NULL)
5610                               free (buf_malloced);
5611                             CLEANUP ();
5612                             return NULL;
5613                           }
5614                         ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
5615                                                 { free (tmpdst); goto out_of_memory; });
5616                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5617                         free (tmpdst);
5618                         count = tmpdst_len;
5619                       }
5620                     else
5621                       {
5622                         /* The result string is ASCII.
5623                            Simple 1:1 conversion.  */
5624 # if USE_SNPRINTF
5625                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5626                            no-op conversion, in-place on the array starting
5627                            at (result + length).  */
5628                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5629 # endif
5630                           {
5631                             const TCHAR_T *tmpsrc;
5632                             DCHAR_T *tmpdst;
5633                             size_t n;
5634 
5635 # if USE_SNPRINTF
5636                             if (result == resultbuf)
5637                               {
5638                                 tmpsrc = (TCHAR_T *) (result + length);
5639                                 /* ENSURE_ALLOCATION will not move tmpsrc
5640                                    (because it's part of resultbuf).  */
5641                                 ENSURE_ALLOCATION (xsum (length, count));
5642                               }
5643                             else
5644                               {
5645                                 /* ENSURE_ALLOCATION will move the array
5646                                    (because it uses realloc().  */
5647                                 ENSURE_ALLOCATION (xsum (length, count));
5648                                 tmpsrc = (TCHAR_T *) (result + length);
5649                               }
5650 # else
5651                             tmpsrc = tmp;
5652                             ENSURE_ALLOCATION (xsum (length, count));
5653 # endif
5654                             tmpdst = result + length;
5655                             /* Copy backwards, because of overlapping.  */
5656                             tmpsrc += count;
5657                             tmpdst += count;
5658                             for (n = count; n > 0; n--)
5659                               *--tmpdst = *--tmpsrc;
5660                           }
5661                       }
5662 #endif
5663 
5664 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5665                     /* Make room for the result.  */
5666                     if (count > allocated - length)
5667                       {
5668                         /* Need at least count elements.  But allocate
5669                            proportionally.  */
5670                         size_t n =
5671                           xmax (xsum (length, count), xtimes (allocated, 2));
5672 
5673                         ENSURE_ALLOCATION (n);
5674                       }
5675 #endif
5676 
5677                     /* Here count <= allocated - length.  */
5678 
5679                     /* Perform padding.  */
5680 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5681                     if (pad_ourselves && has_width)
5682                       {
5683                         size_t w;
5684 # if ENABLE_UNISTDIO
5685                         /* Outside POSIX, it's preferable to compare the width
5686                            against the number of _characters_ of the converted
5687                            value.  */
5688                         w = DCHAR_MBSNLEN (result + length, count);
5689 # else
5690                         /* The width is compared against the number of _bytes_
5691                            of the converted value, says POSIX.  */
5692                         w = count;
5693 # endif
5694                         if (w < width)
5695                           {
5696                             size_t pad = width - w;
5697 
5698                             /* Make room for the result.  */
5699                             if (xsum (count, pad) > allocated - length)
5700                               {
5701                                 /* Need at least count + pad elements.  But
5702                                    allocate proportionally.  */
5703                                 size_t n =
5704                                   xmax (xsum3 (length, count, pad),
5705                                         xtimes (allocated, 2));
5706 
5707 # if USE_SNPRINTF
5708                                 length += count;
5709                                 ENSURE_ALLOCATION (n);
5710                                 length -= count;
5711 # else
5712                                 ENSURE_ALLOCATION (n);
5713 # endif
5714                               }
5715                             /* Here count + pad <= allocated - length.  */
5716 
5717                             {
5718 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5719                               DCHAR_T * const rp = result + length;
5720 # else
5721                               DCHAR_T * const rp = tmp;
5722 # endif
5723                               DCHAR_T *p = rp + count;
5724                               DCHAR_T *end = p + pad;
5725                               DCHAR_T *pad_ptr;
5726 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5727                               if (dp->conversion == 'c'
5728                                   || dp->conversion == 's')
5729                                 /* No zero-padding for string directives.  */
5730                                 pad_ptr = NULL;
5731                               else
5732 # endif
5733                                 {
5734                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
5735                                   /* No zero-padding of "inf" and "nan".  */
5736                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5737                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5738                                     pad_ptr = NULL;
5739                                 }
5740                               /* The generated string now extends from rp to p,
5741                                  with the zero padding insertion point being at
5742                                  pad_ptr.  */
5743 
5744                               count = count + pad; /* = end - rp */
5745 
5746                               if (flags & FLAG_LEFT)
5747                                 {
5748                                   /* Pad with spaces on the right.  */
5749                                   for (; pad > 0; pad--)
5750                                     *p++ = ' ';
5751                                 }
5752                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5753                                 {
5754                                   /* Pad with zeroes.  */
5755                                   DCHAR_T *q = end;
5756 
5757                                   while (p > pad_ptr)
5758                                     *--q = *--p;
5759                                   for (; pad > 0; pad--)
5760                                     *p++ = '0';
5761                                 }
5762                               else
5763                                 {
5764                                   /* Pad with spaces on the left.  */
5765                                   DCHAR_T *q = end;
5766 
5767                                   while (p > rp)
5768                                     *--q = *--p;
5769                                   for (; pad > 0; pad--)
5770                                     *p++ = ' ';
5771                                 }
5772                             }
5773                           }
5774                       }
5775 #endif
5776 
5777                     /* Here still count <= allocated - length.  */
5778 
5779 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5780                     /* The snprintf() result did fit.  */
5781 #else
5782                     /* Append the sprintf() result.  */
5783                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5784 #endif
5785 #if !USE_SNPRINTF
5786                     if (tmp != tmpbuf)
5787                       free (tmp);
5788 #endif
5789 
5790 #if NEED_PRINTF_DIRECTIVE_F
5791                     if (dp->conversion == 'F')
5792                       {
5793                         /* Convert the %f result to upper case for %F.  */
5794                         DCHAR_T *rp = result + length;
5795                         size_t rc;
5796                         for (rc = count; rc > 0; rc--, rp++)
5797                           if (*rp >= 'a' && *rp <= 'z')
5798                             *rp = *rp - 'a' + 'A';
5799                       }
5800 #endif
5801 
5802                     length += count;
5803                     break;
5804                   }
5805                 errno = orig_errno;
5806 #undef pad_ourselves
5807 #undef prec_ourselves
5808               }
5809           }
5810       }
5811 
5812     /* Add the final NUL.  */
5813     ENSURE_ALLOCATION (xsum (length, 1));
5814     result[length] = '\0';
5815 
5816     if (result != resultbuf && length + 1 < allocated)
5817       {
5818         /* Shrink the allocated memory if possible.  */
5819         DCHAR_T *memory;
5820 
5821         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5822         if (memory != NULL)
5823           result = memory;
5824       }
5825 
5826     if (buf_malloced != NULL)
5827       free (buf_malloced);
5828     CLEANUP ();
5829     *lengthp = length;
5830     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
5831        says that snprintf() fails with errno = EOVERFLOW in this case, but
5832        that's only because snprintf() returns an 'int'.  This function does
5833        not have this limitation.  */
5834     return result;
5835 
5836 #if USE_SNPRINTF
5837   overflow:
5838     if (!(result == resultbuf || result == NULL))
5839       free (result);
5840     if (buf_malloced != NULL)
5841       free (buf_malloced);
5842     CLEANUP ();
5843     errno = EOVERFLOW;
5844     return NULL;
5845 #endif
5846 
5847   out_of_memory:
5848     if (!(result == resultbuf || result == NULL))
5849       free (result);
5850     if (buf_malloced != NULL)
5851       free (buf_malloced);
5852   out_of_memory_1:
5853     CLEANUP ();
5854     errno = ENOMEM;
5855     return NULL;
5856   }
5857 }
5858 
5859 #undef MAX_ROOM_NEEDED
5860 #undef TCHARS_PER_DCHAR
5861 #undef SNPRINTF
5862 #undef USE_SNPRINTF
5863 #undef DCHAR_SET
5864 #undef DCHAR_CPY
5865 #undef PRINTF_PARSE
5866 #undef DIRECTIVES
5867 #undef DIRECTIVE
5868 #undef DCHAR_IS_TCHAR
5869 #undef TCHAR_T
5870 #undef DCHAR_T
5871 #undef FCHAR_T
5872 #undef VASNPRINTF

/* [previous][next][first][last][top][bottom][index][help] */