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