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