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