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