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