• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* vsprintf with automatic memory allocation.
2    Copyright (C) 1999, 2002-2012 Free Software Foundation, Inc.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, see <http://www.gnu.org/licenses/>.  */
16 
17 /* This file can be parametrized with the following macros:
18      VASNPRINTF         The name of the function being defined.
19      FCHAR_T            The element type of the format string.
20      DCHAR_T            The element type of the destination (result) string.
21      FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
22                         in the format string are ASCII. MUST be set if
23                         FCHAR_T and DCHAR_T are not the same type.
24      DIRECTIVE          Structure denoting a format directive.
25                         Depends on FCHAR_T.
26      DIRECTIVES         Structure denoting the set of format directives of a
27                         format string.  Depends on FCHAR_T.
28      PRINTF_PARSE       Function that parses a format string.
29                         Depends on FCHAR_T.
30      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
31      DCHAR_SET          memset like function for DCHAR_T[] arrays.
32      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
33      SNPRINTF           The system's snprintf (or similar) function.
34                         This may be either snprintf or swprintf.
35      TCHAR_T            The element type of the argument and result string
36                         of the said SNPRINTF function.  This may be either
37                         char or wchar_t.  The code exploits that
38                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
39                         alignof (TCHAR_T) <= alignof (DCHAR_T).
40      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
41      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
42      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
43      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
44      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.  */
45 
46 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
47    This must come before <config.h> because <config.h> may include
48    <features.h>, and once <features.h> has been included, it's too late.  */
49 #ifndef _GNU_SOURCE
50 # define _GNU_SOURCE    1
51 #endif
52 
53 #ifndef VASNPRINTF
54 # include <config.h>
55 #endif
56 #ifndef IN_LIBINTL
57 # include <alloca.h>
58 #endif
59 
60 /* Specification.  */
61 #ifndef VASNPRINTF
62 # if WIDE_CHAR_VERSION
63 #  include "vasnwprintf.h"
64 # else
65 #  include "vasnprintf.h"
66 # endif
67 #endif
68 
69 #include <locale.h>     /* localeconv() */
70 #include <stdio.h>      /* snprintf(), sprintf() */
71 #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
72 #include <string.h>     /* memcpy(), strlen() */
73 #include <errno.h>      /* errno */
74 #include <limits.h>     /* CHAR_BIT */
75 #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
76 #if HAVE_NL_LANGINFO
77 # include <langinfo.h>
78 #endif
79 #ifndef VASNPRINTF
80 # if WIDE_CHAR_VERSION
81 #  include "wprintf-parse.h"
82 # else
83 #  include "printf-parse.h"
84 # endif
85 #endif
86 
87 /* Checked size_t computations.  */
88 #include "xsize.h"
89 
90 #include "verify.h"
91 
92 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
93 # include <math.h>
94 # include "float+.h"
95 #endif
96 
97 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
98 # include <math.h>
99 # include "isnand-nolibm.h"
100 #endif
101 
102 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
103 # include <math.h>
104 # include "isnanl-nolibm.h"
105 # include "fpucw.h"
106 #endif
107 
108 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
109 # include <math.h>
110 # include "isnand-nolibm.h"
111 # include "printf-frexp.h"
112 #endif
113 
114 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
115 # include <math.h>
116 # include "isnanl-nolibm.h"
117 # include "printf-frexpl.h"
118 # include "fpucw.h"
119 #endif
120 
121 /* Default parameters.  */
122 #ifndef VASNPRINTF
123 # if WIDE_CHAR_VERSION
124 #  define VASNPRINTF vasnwprintf
125 #  define FCHAR_T wchar_t
126 #  define DCHAR_T wchar_t
127 #  define TCHAR_T wchar_t
128 #  define DCHAR_IS_TCHAR 1
129 #  define DIRECTIVE wchar_t_directive
130 #  define DIRECTIVES wchar_t_directives
131 #  define PRINTF_PARSE wprintf_parse
132 #  define DCHAR_CPY wmemcpy
133 #  define DCHAR_SET wmemset
134 # else
135 #  define VASNPRINTF vasnprintf
136 #  define FCHAR_T char
137 #  define DCHAR_T char
138 #  define TCHAR_T char
139 #  define DCHAR_IS_TCHAR 1
140 #  define DIRECTIVE char_directive
141 #  define DIRECTIVES char_directives
142 #  define PRINTF_PARSE printf_parse
143 #  define DCHAR_CPY memcpy
144 #  define DCHAR_SET memset
145 # endif
146 #endif
147 #if WIDE_CHAR_VERSION
148   /* TCHAR_T is wchar_t.  */
149 # define USE_SNPRINTF 1
150 # if HAVE_DECL__SNWPRINTF
151    /* On Windows, the function swprintf() has a different signature than
152       on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
153       instead.  The mingw function snwprintf() has fewer bugs than the
154       MSVCRT function _snwprintf(), so prefer that.  */
155 #  if defined __MINGW32__
156 #   define SNPRINTF snwprintf
157 #  else
158 #   define SNPRINTF _snwprintf
159 #  endif
160 # else
161    /* Unix.  */
162 #  define SNPRINTF swprintf
163 # endif
164 #else
165   /* TCHAR_T is char.  */
166   /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
167      But don't use it on BeOS, since BeOS snprintf produces no output if the
168      size argument is >= 0x3000000.
169      Also don't use it on Linux libc5, since there snprintf with size = 1
170      writes any output without bounds, like sprintf.  */
171 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
172 #  define USE_SNPRINTF 1
173 # else
174 #  define USE_SNPRINTF 0
175 # endif
176 # if HAVE_DECL__SNPRINTF
177    /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
178       function _snprintf(), so prefer that.  */
179 #  if defined __MINGW32__
180 #   define SNPRINTF snprintf
181     /* Here we need to call the native snprintf, not rpl_snprintf.  */
182 #   undef snprintf
183 #  else
184 #   define SNPRINTF _snprintf
185 #  endif
186 # else
187    /* Unix.  */
188 #  define SNPRINTF snprintf
189    /* Here we need to call the native snprintf, not rpl_snprintf.  */
190 #  undef snprintf
191 # endif
192 #endif
193 /* Here we need to call the native sprintf, not rpl_sprintf.  */
194 #undef sprintf
195 
196 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
197    warnings in this file.  Use -Dlint to suppress them.  */
198 #ifdef lint
199 # define IF_LINT(Code) Code
200 #else
201 # define IF_LINT(Code) /* empty */
202 #endif
203 
204 /* Avoid some warnings from "gcc -Wshadow".
205    This file doesn't use the exp() and remainder() functions.  */
206 #undef exp
207 #define exp expo
208 #undef remainder
209 #define remainder rem
210 
211 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
212 # if (HAVE_STRNLEN && !defined _AIX)
213 #  define local_strnlen strnlen
214 # else
215 #  ifndef local_strnlen_defined
216 #   define local_strnlen_defined 1
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                         if (arg < 0)
1961                           {
1962                             /* "A negative field width is taken as a '-' flag
1963                                 followed by a positive field width."  */
1964                             flags |= FLAG_LEFT;
1965                             width = (unsigned int) (-arg);
1966                           }
1967                         else
1968                           width = arg;
1969                       }
1970                     else
1971                       {
1972                         const FCHAR_T *digitp = dp->width_start;
1973 
1974                         do
1975                           width = xsum (xtimes (width, 10), *digitp++ - '0');
1976                         while (digitp != dp->width_end);
1977                       }
1978                     has_width = 1;
1979                   }
1980 
1981                 has_precision = 0;
1982                 precision = 0;
1983                 if (dp->precision_start != dp->precision_end)
1984                   {
1985                     if (dp->precision_arg_index != ARG_NONE)
1986                       {
1987                         int arg;
1988 
1989                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1990                           abort ();
1991                         arg = a.arg[dp->precision_arg_index].a.a_int;
1992                         /* "A negative precision is taken as if the precision
1993                             were omitted."  */
1994                         if (arg >= 0)
1995                           {
1996                             precision = arg;
1997                             has_precision = 1;
1998                           }
1999                       }
2000                     else
2001                       {
2002                         const FCHAR_T *digitp = dp->precision_start + 1;
2003 
2004                         precision = 0;
2005                         while (digitp != dp->precision_end)
2006                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2007                         has_precision = 1;
2008                       }
2009                   }
2010 
2011                 switch (type)
2012                   {
2013                   case TYPE_U8_STRING:
2014                     {
2015                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2016                       const uint8_t *arg_end;
2017                       size_t characters;
2018 
2019                       if (has_precision)
2020                         {
2021                           /* Use only PRECISION characters, from the left.  */
2022                           arg_end = arg;
2023                           characters = 0;
2024                           for (; precision > 0; precision--)
2025                             {
2026                               int count = u8_strmblen (arg_end);
2027                               if (count == 0)
2028                                 break;
2029                               if (count < 0)
2030                                 {
2031                                   if (!(result == resultbuf || result == NULL))
2032                                     free (result);
2033                                   if (buf_malloced != NULL)
2034                                     free (buf_malloced);
2035                                   CLEANUP ();
2036                                   errno = EILSEQ;
2037                                   return NULL;
2038                                 }
2039                               arg_end += count;
2040                               characters++;
2041                             }
2042                         }
2043                       else if (has_width)
2044                         {
2045                           /* Use the entire string, and count the number of
2046                              characters.  */
2047                           arg_end = arg;
2048                           characters = 0;
2049                           for (;;)
2050                             {
2051                               int count = u8_strmblen (arg_end);
2052                               if (count == 0)
2053                                 break;
2054                               if (count < 0)
2055                                 {
2056                                   if (!(result == resultbuf || result == NULL))
2057                                     free (result);
2058                                   if (buf_malloced != NULL)
2059                                     free (buf_malloced);
2060                                   CLEANUP ();
2061                                   errno = EILSEQ;
2062                                   return NULL;
2063                                 }
2064                               arg_end += count;
2065                               characters++;
2066                             }
2067                         }
2068                       else
2069                         {
2070                           /* Use the entire string.  */
2071                           arg_end = arg + u8_strlen (arg);
2072                           /* The number of characters doesn't matter.  */
2073                           characters = 0;
2074                         }
2075 
2076                       if (has_width && width > characters
2077                           && !(dp->flags & FLAG_LEFT))
2078                         {
2079                           size_t n = width - characters;
2080                           ENSURE_ALLOCATION (xsum (length, n));
2081                           DCHAR_SET (result + length, ' ', n);
2082                           length += n;
2083                         }
2084 
2085 # if DCHAR_IS_UINT8_T
2086                       {
2087                         size_t n = arg_end - arg;
2088                         ENSURE_ALLOCATION (xsum (length, n));
2089                         DCHAR_CPY (result + length, arg, n);
2090                         length += n;
2091                       }
2092 # else
2093                       { /* Convert.  */
2094                         DCHAR_T *converted = result + length;
2095                         size_t converted_len = allocated - length;
2096 #  if DCHAR_IS_TCHAR
2097                         /* Convert from UTF-8 to locale encoding.  */
2098                         converted =
2099                           u8_conv_to_encoding (locale_charset (),
2100                                                iconveh_question_mark,
2101                                                arg, arg_end - arg, NULL,
2102                                                converted, &converted_len);
2103 #  else
2104                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
2105                         converted =
2106                           U8_TO_DCHAR (arg, arg_end - arg,
2107                                        converted, &converted_len);
2108 #  endif
2109                         if (converted == NULL)
2110                           {
2111                             int saved_errno = errno;
2112                             if (!(result == resultbuf || result == NULL))
2113                               free (result);
2114                             if (buf_malloced != NULL)
2115                               free (buf_malloced);
2116                             CLEANUP ();
2117                             errno = saved_errno;
2118                             return NULL;
2119                           }
2120                         if (converted != result + length)
2121                           {
2122                             ENSURE_ALLOCATION (xsum (length, converted_len));
2123                             DCHAR_CPY (result + length, converted, converted_len);
2124                             free (converted);
2125                           }
2126                         length += converted_len;
2127                       }
2128 # endif
2129 
2130                       if (has_width && width > characters
2131                           && (dp->flags & FLAG_LEFT))
2132                         {
2133                           size_t n = width - characters;
2134                           ENSURE_ALLOCATION (xsum (length, n));
2135                           DCHAR_SET (result + length, ' ', n);
2136                           length += n;
2137                         }
2138                     }
2139                     break;
2140 
2141                   case TYPE_U16_STRING:
2142                     {
2143                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2144                       const uint16_t *arg_end;
2145                       size_t characters;
2146 
2147                       if (has_precision)
2148                         {
2149                           /* Use only PRECISION characters, from the left.  */
2150                           arg_end = arg;
2151                           characters = 0;
2152                           for (; precision > 0; precision--)
2153                             {
2154                               int count = u16_strmblen (arg_end);
2155                               if (count == 0)
2156                                 break;
2157                               if (count < 0)
2158                                 {
2159                                   if (!(result == resultbuf || result == NULL))
2160                                     free (result);
2161                                   if (buf_malloced != NULL)
2162                                     free (buf_malloced);
2163                                   CLEANUP ();
2164                                   errno = EILSEQ;
2165                                   return NULL;
2166                                 }
2167                               arg_end += count;
2168                               characters++;
2169                             }
2170                         }
2171                       else if (has_width)
2172                         {
2173                           /* Use the entire string, and count the number of
2174                              characters.  */
2175                           arg_end = arg;
2176                           characters = 0;
2177                           for (;;)
2178                             {
2179                               int count = u16_strmblen (arg_end);
2180                               if (count == 0)
2181                                 break;
2182                               if (count < 0)
2183                                 {
2184                                   if (!(result == resultbuf || result == NULL))
2185                                     free (result);
2186                                   if (buf_malloced != NULL)
2187                                     free (buf_malloced);
2188                                   CLEANUP ();
2189                                   errno = EILSEQ;
2190                                   return NULL;
2191                                 }
2192                               arg_end += count;
2193                               characters++;
2194                             }
2195                         }
2196                       else
2197                         {
2198                           /* Use the entire string.  */
2199                           arg_end = arg + u16_strlen (arg);
2200                           /* The number of characters doesn't matter.  */
2201                           characters = 0;
2202                         }
2203 
2204                       if (has_width && width > characters
2205                           && !(dp->flags & FLAG_LEFT))
2206                         {
2207                           size_t n = width - characters;
2208                           ENSURE_ALLOCATION (xsum (length, n));
2209                           DCHAR_SET (result + length, ' ', n);
2210                           length += n;
2211                         }
2212 
2213 # if DCHAR_IS_UINT16_T
2214                       {
2215                         size_t n = arg_end - arg;
2216                         ENSURE_ALLOCATION (xsum (length, n));
2217                         DCHAR_CPY (result + length, arg, n);
2218                         length += n;
2219                       }
2220 # else
2221                       { /* Convert.  */
2222                         DCHAR_T *converted = result + length;
2223                         size_t converted_len = allocated - length;
2224 #  if DCHAR_IS_TCHAR
2225                         /* Convert from UTF-16 to locale encoding.  */
2226                         converted =
2227                           u16_conv_to_encoding (locale_charset (),
2228                                                 iconveh_question_mark,
2229                                                 arg, arg_end - arg, NULL,
2230                                                 converted, &converted_len);
2231 #  else
2232                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
2233                         converted =
2234                           U16_TO_DCHAR (arg, arg_end - arg,
2235                                         converted, &converted_len);
2236 #  endif
2237                         if (converted == NULL)
2238                           {
2239                             int saved_errno = errno;
2240                             if (!(result == resultbuf || result == NULL))
2241                               free (result);
2242                             if (buf_malloced != NULL)
2243                               free (buf_malloced);
2244                             CLEANUP ();
2245                             errno = saved_errno;
2246                             return NULL;
2247                           }
2248                         if (converted != result + length)
2249                           {
2250                             ENSURE_ALLOCATION (xsum (length, converted_len));
2251                             DCHAR_CPY (result + length, converted, converted_len);
2252                             free (converted);
2253                           }
2254                         length += converted_len;
2255                       }
2256 # endif
2257 
2258                       if (has_width && width > characters
2259                           && (dp->flags & FLAG_LEFT))
2260                         {
2261                           size_t n = width - characters;
2262                           ENSURE_ALLOCATION (xsum (length, n));
2263                           DCHAR_SET (result + length, ' ', n);
2264                           length += n;
2265                         }
2266                     }
2267                     break;
2268 
2269                   case TYPE_U32_STRING:
2270                     {
2271                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2272                       const uint32_t *arg_end;
2273                       size_t characters;
2274 
2275                       if (has_precision)
2276                         {
2277                           /* Use only PRECISION characters, from the left.  */
2278                           arg_end = arg;
2279                           characters = 0;
2280                           for (; precision > 0; precision--)
2281                             {
2282                               int count = u32_strmblen (arg_end);
2283                               if (count == 0)
2284                                 break;
2285                               if (count < 0)
2286                                 {
2287                                   if (!(result == resultbuf || result == NULL))
2288                                     free (result);
2289                                   if (buf_malloced != NULL)
2290                                     free (buf_malloced);
2291                                   CLEANUP ();
2292                                   errno = EILSEQ;
2293                                   return NULL;
2294                                 }
2295                               arg_end += count;
2296                               characters++;
2297                             }
2298                         }
2299                       else if (has_width)
2300                         {
2301                           /* Use the entire string, and count the number of
2302                              characters.  */
2303                           arg_end = arg;
2304                           characters = 0;
2305                           for (;;)
2306                             {
2307                               int count = u32_strmblen (arg_end);
2308                               if (count == 0)
2309                                 break;
2310                               if (count < 0)
2311                                 {
2312                                   if (!(result == resultbuf || result == NULL))
2313                                     free (result);
2314                                   if (buf_malloced != NULL)
2315                                     free (buf_malloced);
2316                                   CLEANUP ();
2317                                   errno = EILSEQ;
2318                                   return NULL;
2319                                 }
2320                               arg_end += count;
2321                               characters++;
2322                             }
2323                         }
2324                       else
2325                         {
2326                           /* Use the entire string.  */
2327                           arg_end = arg + u32_strlen (arg);
2328                           /* The number of characters doesn't matter.  */
2329                           characters = 0;
2330                         }
2331 
2332                       if (has_width && width > characters
2333                           && !(dp->flags & FLAG_LEFT))
2334                         {
2335                           size_t n = width - characters;
2336                           ENSURE_ALLOCATION (xsum (length, n));
2337                           DCHAR_SET (result + length, ' ', n);
2338                           length += n;
2339                         }
2340 
2341 # if DCHAR_IS_UINT32_T
2342                       {
2343                         size_t n = arg_end - arg;
2344                         ENSURE_ALLOCATION (xsum (length, n));
2345                         DCHAR_CPY (result + length, arg, n);
2346                         length += n;
2347                       }
2348 # else
2349                       { /* Convert.  */
2350                         DCHAR_T *converted = result + length;
2351                         size_t converted_len = allocated - length;
2352 #  if DCHAR_IS_TCHAR
2353                         /* Convert from UTF-32 to locale encoding.  */
2354                         converted =
2355                           u32_conv_to_encoding (locale_charset (),
2356                                                 iconveh_question_mark,
2357                                                 arg, arg_end - arg, NULL,
2358                                                 converted, &converted_len);
2359 #  else
2360                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
2361                         converted =
2362                           U32_TO_DCHAR (arg, arg_end - arg,
2363                                         converted, &converted_len);
2364 #  endif
2365                         if (converted == NULL)
2366                           {
2367                             int saved_errno = errno;
2368                             if (!(result == resultbuf || result == NULL))
2369                               free (result);
2370                             if (buf_malloced != NULL)
2371                               free (buf_malloced);
2372                             CLEANUP ();
2373                             errno = saved_errno;
2374                             return NULL;
2375                           }
2376                         if (converted != result + length)
2377                           {
2378                             ENSURE_ALLOCATION (xsum (length, converted_len));
2379                             DCHAR_CPY (result + length, converted, converted_len);
2380                             free (converted);
2381                           }
2382                         length += converted_len;
2383                       }
2384 # endif
2385 
2386                       if (has_width && width > characters
2387                           && (dp->flags & FLAG_LEFT))
2388                         {
2389                           size_t n = width - characters;
2390                           ENSURE_ALLOCATION (xsum (length, n));
2391                           DCHAR_SET (result + length, ' ', n);
2392                           length += n;
2393                         }
2394                     }
2395                     break;
2396 
2397                   default:
2398                     abort ();
2399                   }
2400               }
2401 #endif
2402 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2403             else if (dp->conversion == 's'
2404 # if WIDE_CHAR_VERSION
2405                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2406 # else
2407                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2408 # endif
2409                     )
2410               {
2411                 /* The normal handling of the 's' directive below requires
2412                    allocating a temporary buffer.  The determination of its
2413                    length (tmp_length), in the case when a precision is
2414                    specified, below requires a conversion between a char[]
2415                    string and a wchar_t[] wide string.  It could be done, but
2416                    we have no guarantee that the implementation of sprintf will
2417                    use the exactly same algorithm.  Without this guarantee, it
2418                    is possible to have buffer overrun bugs.  In order to avoid
2419                    such bugs, we implement the entire processing of the 's'
2420                    directive ourselves.  */
2421                 int flags = dp->flags;
2422                 int has_width;
2423                 size_t width;
2424                 int has_precision;
2425                 size_t precision;
2426 
2427                 has_width = 0;
2428                 width = 0;
2429                 if (dp->width_start != dp->width_end)
2430                   {
2431                     if (dp->width_arg_index != ARG_NONE)
2432                       {
2433                         int arg;
2434 
2435                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2436                           abort ();
2437                         arg = a.arg[dp->width_arg_index].a.a_int;
2438                         if (arg < 0)
2439                           {
2440                             /* "A negative field width is taken as a '-' flag
2441                                 followed by a positive field width."  */
2442                             flags |= FLAG_LEFT;
2443                             width = (unsigned int) (-arg);
2444                           }
2445                         else
2446                           width = arg;
2447                       }
2448                     else
2449                       {
2450                         const FCHAR_T *digitp = dp->width_start;
2451 
2452                         do
2453                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2454                         while (digitp != dp->width_end);
2455                       }
2456                     has_width = 1;
2457                   }
2458 
2459                 has_precision = 0;
2460                 precision = 6;
2461                 if (dp->precision_start != dp->precision_end)
2462                   {
2463                     if (dp->precision_arg_index != ARG_NONE)
2464                       {
2465                         int arg;
2466 
2467                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2468                           abort ();
2469                         arg = a.arg[dp->precision_arg_index].a.a_int;
2470                         /* "A negative precision is taken as if the precision
2471                             were omitted."  */
2472                         if (arg >= 0)
2473                           {
2474                             precision = arg;
2475                             has_precision = 1;
2476                           }
2477                       }
2478                     else
2479                       {
2480                         const FCHAR_T *digitp = dp->precision_start + 1;
2481 
2482                         precision = 0;
2483                         while (digitp != dp->precision_end)
2484                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2485                         has_precision = 1;
2486                       }
2487                   }
2488 
2489 # if WIDE_CHAR_VERSION
2490                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
2491                 {
2492                   const char *arg = a.arg[dp->arg_index].a.a_string;
2493                   const char *arg_end;
2494                   size_t characters;
2495 
2496                   if (has_precision)
2497                     {
2498                       /* Use only as many bytes as needed to produce PRECISION
2499                          wide characters, from the left.  */
2500 #  if HAVE_MBRTOWC
2501                       mbstate_t state;
2502                       memset (&state, '\0', sizeof (mbstate_t));
2503 #  endif
2504                       arg_end = arg;
2505                       characters = 0;
2506                       for (; precision > 0; precision--)
2507                         {
2508                           int count;
2509 #  if HAVE_MBRTOWC
2510                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2511 #  else
2512                           count = mblen (arg_end, MB_CUR_MAX);
2513 #  endif
2514                           if (count == 0)
2515                             /* Found the terminating NUL.  */
2516                             break;
2517                           if (count < 0)
2518                             {
2519                               /* Invalid or incomplete multibyte character.  */
2520                               if (!(result == resultbuf || result == NULL))
2521                                 free (result);
2522                               if (buf_malloced != NULL)
2523                                 free (buf_malloced);
2524                               CLEANUP ();
2525                               errno = EILSEQ;
2526                               return NULL;
2527                             }
2528                           arg_end += count;
2529                           characters++;
2530                         }
2531                     }
2532                   else if (has_width)
2533                     {
2534                       /* Use the entire string, and count the number of wide
2535                          characters.  */
2536 #  if HAVE_MBRTOWC
2537                       mbstate_t state;
2538                       memset (&state, '\0', sizeof (mbstate_t));
2539 #  endif
2540                       arg_end = arg;
2541                       characters = 0;
2542                       for (;;)
2543                         {
2544                           int count;
2545 #  if HAVE_MBRTOWC
2546                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2547 #  else
2548                           count = mblen (arg_end, MB_CUR_MAX);
2549 #  endif
2550                           if (count == 0)
2551                             /* Found the terminating NUL.  */
2552                             break;
2553                           if (count < 0)
2554                             {
2555                               /* Invalid or incomplete multibyte character.  */
2556                               if (!(result == resultbuf || result == NULL))
2557                                 free (result);
2558                               if (buf_malloced != NULL)
2559                                 free (buf_malloced);
2560                               CLEANUP ();
2561                               errno = EILSEQ;
2562                               return NULL;
2563                             }
2564                           arg_end += count;
2565                           characters++;
2566                         }
2567                     }
2568                   else
2569                     {
2570                       /* Use the entire string.  */
2571                       arg_end = arg + strlen (arg);
2572                       /* The number of characters doesn't matter.  */
2573                       characters = 0;
2574                     }
2575 
2576                   if (has_width && width > characters
2577                       && !(dp->flags & FLAG_LEFT))
2578                     {
2579                       size_t n = width - characters;
2580                       ENSURE_ALLOCATION (xsum (length, n));
2581                       DCHAR_SET (result + length, ' ', n);
2582                       length += n;
2583                     }
2584 
2585                   if (has_precision || has_width)
2586                     {
2587                       /* We know the number of wide characters in advance.  */
2588                       size_t remaining;
2589 #  if HAVE_MBRTOWC
2590                       mbstate_t state;
2591                       memset (&state, '\0', sizeof (mbstate_t));
2592 #  endif
2593                       ENSURE_ALLOCATION (xsum (length, characters));
2594                       for (remaining = characters; remaining > 0; remaining--)
2595                         {
2596                           wchar_t wc;
2597                           int count;
2598 #  if HAVE_MBRTOWC
2599                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2600 #  else
2601                           count = mbtowc (&wc, arg, arg_end - arg);
2602 #  endif
2603                           if (count <= 0)
2604                             /* mbrtowc not consistent with mbrlen, or mbtowc
2605                                not consistent with mblen.  */
2606                             abort ();
2607                           result[length++] = wc;
2608                           arg += count;
2609                         }
2610                       if (!(arg == arg_end))
2611                         abort ();
2612                     }
2613                   else
2614                     {
2615 #  if HAVE_MBRTOWC
2616                       mbstate_t state;
2617                       memset (&state, '\0', sizeof (mbstate_t));
2618 #  endif
2619                       while (arg < arg_end)
2620                         {
2621                           wchar_t wc;
2622                           int count;
2623 #  if HAVE_MBRTOWC
2624                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2625 #  else
2626                           count = mbtowc (&wc, arg, arg_end - arg);
2627 #  endif
2628                           if (count <= 0)
2629                             /* mbrtowc not consistent with mbrlen, or mbtowc
2630                                not consistent with mblen.  */
2631                             abort ();
2632                           ENSURE_ALLOCATION (xsum (length, 1));
2633                           result[length++] = wc;
2634                           arg += count;
2635                         }
2636                     }
2637 
2638                   if (has_width && width > characters
2639                       && (dp->flags & FLAG_LEFT))
2640                     {
2641                       size_t n = width - characters;
2642                       ENSURE_ALLOCATION (xsum (length, n));
2643                       DCHAR_SET (result + length, ' ', n);
2644                       length += n;
2645                     }
2646                 }
2647 # else
2648                 /* %ls in vasnprintf.  See the specification of fprintf.  */
2649                 {
2650                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2651                   const wchar_t *arg_end;
2652                   size_t characters;
2653 #  if !DCHAR_IS_TCHAR
2654                   /* This code assumes that TCHAR_T is 'char'.  */
2655                   verify (sizeof (TCHAR_T) == 1);
2656                   TCHAR_T *tmpsrc;
2657                   DCHAR_T *tmpdst;
2658                   size_t tmpdst_len;
2659 #  endif
2660                   size_t w;
2661 
2662                   if (has_precision)
2663                     {
2664                       /* Use only as many wide characters as needed to produce
2665                          at most PRECISION bytes, from the left.  */
2666 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2667                       mbstate_t state;
2668                       memset (&state, '\0', sizeof (mbstate_t));
2669 #  endif
2670                       arg_end = arg;
2671                       characters = 0;
2672                       while (precision > 0)
2673                         {
2674                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2675                           int count;
2676 
2677                           if (*arg_end == 0)
2678                             /* Found the terminating null wide character.  */
2679                             break;
2680 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2681                           count = wcrtomb (cbuf, *arg_end, &state);
2682 #  else
2683                           count = wctomb (cbuf, *arg_end);
2684 #  endif
2685                           if (count < 0)
2686                             {
2687                               /* Cannot convert.  */
2688                               if (!(result == resultbuf || result == NULL))
2689                                 free (result);
2690                               if (buf_malloced != NULL)
2691                                 free (buf_malloced);
2692                               CLEANUP ();
2693                               errno = EILSEQ;
2694                               return NULL;
2695                             }
2696                           if (precision < count)
2697                             break;
2698                           arg_end++;
2699                           characters += count;
2700                           precision -= count;
2701                         }
2702                     }
2703 #  if DCHAR_IS_TCHAR
2704                   else if (has_width)
2705 #  else
2706                   else
2707 #  endif
2708                     {
2709                       /* Use the entire string, and count the number of
2710                          bytes.  */
2711 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2712                       mbstate_t state;
2713                       memset (&state, '\0', sizeof (mbstate_t));
2714 #  endif
2715                       arg_end = arg;
2716                       characters = 0;
2717                       for (;;)
2718                         {
2719                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2720                           int count;
2721 
2722                           if (*arg_end == 0)
2723                             /* Found the terminating null wide character.  */
2724                             break;
2725 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2726                           count = wcrtomb (cbuf, *arg_end, &state);
2727 #  else
2728                           count = wctomb (cbuf, *arg_end);
2729 #  endif
2730                           if (count < 0)
2731                             {
2732                               /* Cannot convert.  */
2733                               if (!(result == resultbuf || result == NULL))
2734                                 free (result);
2735                               if (buf_malloced != NULL)
2736                                 free (buf_malloced);
2737                               CLEANUP ();
2738                               errno = EILSEQ;
2739                               return NULL;
2740                             }
2741                           arg_end++;
2742                           characters += count;
2743                         }
2744                     }
2745 #  if DCHAR_IS_TCHAR
2746                   else
2747                     {
2748                       /* Use the entire string.  */
2749                       arg_end = arg + local_wcslen (arg);
2750                       /* The number of bytes doesn't matter.  */
2751                       characters = 0;
2752                     }
2753 #  endif
2754 
2755 #  if !DCHAR_IS_TCHAR
2756                   /* Convert the string into a piece of temporary memory.  */
2757                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2758                   if (tmpsrc == NULL)
2759                     goto out_of_memory;
2760                   {
2761                     TCHAR_T *tmpptr = tmpsrc;
2762                     size_t remaining;
2763 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2764                     mbstate_t state;
2765                     memset (&state, '\0', sizeof (mbstate_t));
2766 #   endif
2767                     for (remaining = characters; remaining > 0; )
2768                       {
2769                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2770                         int count;
2771 
2772                         if (*arg == 0)
2773                           abort ();
2774 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2775                         count = wcrtomb (cbuf, *arg, &state);
2776 #   else
2777                         count = wctomb (cbuf, *arg);
2778 #   endif
2779                         if (count <= 0)
2780                           /* Inconsistency.  */
2781                           abort ();
2782                         memcpy (tmpptr, cbuf, count);
2783                         tmpptr += count;
2784                         arg++;
2785                         remaining -= count;
2786                       }
2787                     if (!(arg == arg_end))
2788                       abort ();
2789                   }
2790 
2791                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
2792                   tmpdst =
2793                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
2794                                               iconveh_question_mark,
2795                                               tmpsrc, characters,
2796                                               NULL,
2797                                               NULL, &tmpdst_len);
2798                   if (tmpdst == NULL)
2799                     {
2800                       int saved_errno = errno;
2801                       free (tmpsrc);
2802                       if (!(result == resultbuf || result == NULL))
2803                         free (result);
2804                       if (buf_malloced != NULL)
2805                         free (buf_malloced);
2806                       CLEANUP ();
2807                       errno = saved_errno;
2808                       return NULL;
2809                     }
2810                   free (tmpsrc);
2811 #  endif
2812 
2813                   if (has_width)
2814                     {
2815 #  if ENABLE_UNISTDIO
2816                       /* Outside POSIX, it's preferable to compare the width
2817                          against the number of _characters_ of the converted
2818                          value.  */
2819                       w = DCHAR_MBSNLEN (result + length, characters);
2820 #  else
2821                       /* The width is compared against the number of _bytes_
2822                          of the converted value, says POSIX.  */
2823                       w = characters;
2824 #  endif
2825                     }
2826                   else
2827                     /* w doesn't matter.  */
2828                     w = 0;
2829 
2830                   if (has_width && width > w
2831                       && !(dp->flags & FLAG_LEFT))
2832                     {
2833                       size_t n = width - w;
2834                       ENSURE_ALLOCATION (xsum (length, n));
2835                       DCHAR_SET (result + length, ' ', n);
2836                       length += n;
2837                     }
2838 
2839 #  if DCHAR_IS_TCHAR
2840                   if (has_precision || has_width)
2841                     {
2842                       /* We know the number of bytes in advance.  */
2843                       size_t remaining;
2844 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2845                       mbstate_t state;
2846                       memset (&state, '\0', sizeof (mbstate_t));
2847 #   endif
2848                       ENSURE_ALLOCATION (xsum (length, characters));
2849                       for (remaining = characters; remaining > 0; )
2850                         {
2851                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2852                           int count;
2853 
2854                           if (*arg == 0)
2855                             abort ();
2856 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2857                           count = wcrtomb (cbuf, *arg, &state);
2858 #   else
2859                           count = wctomb (cbuf, *arg);
2860 #   endif
2861                           if (count <= 0)
2862                             /* Inconsistency.  */
2863                             abort ();
2864                           memcpy (result + length, cbuf, count);
2865                           length += count;
2866                           arg++;
2867                           remaining -= count;
2868                         }
2869                       if (!(arg == arg_end))
2870                         abort ();
2871                     }
2872                   else
2873                     {
2874 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2875                       mbstate_t state;
2876                       memset (&state, '\0', sizeof (mbstate_t));
2877 #   endif
2878                       while (arg < arg_end)
2879                         {
2880                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2881                           int count;
2882 
2883                           if (*arg == 0)
2884                             abort ();
2885 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2886                           count = wcrtomb (cbuf, *arg, &state);
2887 #   else
2888                           count = wctomb (cbuf, *arg);
2889 #   endif
2890                           if (count <= 0)
2891                             {
2892                               /* Cannot convert.  */
2893                               if (!(result == resultbuf || result == NULL))
2894                                 free (result);
2895                               if (buf_malloced != NULL)
2896                                 free (buf_malloced);
2897                               CLEANUP ();
2898                               errno = EILSEQ;
2899                               return NULL;
2900                             }
2901                           ENSURE_ALLOCATION (xsum (length, count));
2902                           memcpy (result + length, cbuf, count);
2903                           length += count;
2904                           arg++;
2905                         }
2906                     }
2907 #  else
2908                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2909                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2910                   free (tmpdst);
2911                   length += tmpdst_len;
2912 #  endif
2913 
2914                   if (has_width && width > w
2915                       && (dp->flags & FLAG_LEFT))
2916                     {
2917                       size_t n = width - w;
2918                       ENSURE_ALLOCATION (xsum (length, n));
2919                       DCHAR_SET (result + length, ' ', n);
2920                       length += n;
2921                     }
2922                 }
2923 # endif
2924               }
2925 #endif
2926 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2927             else if ((dp->conversion == 'a' || dp->conversion == 'A')
2928 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2929                      && (0
2930 #  if NEED_PRINTF_DOUBLE
2931                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
2932 #  endif
2933 #  if NEED_PRINTF_LONG_DOUBLE
2934                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2935 #  endif
2936                         )
2937 # endif
2938                     )
2939               {
2940                 arg_type type = a.arg[dp->arg_index].type;
2941                 int flags = dp->flags;
2942                 int has_width;
2943                 size_t width;
2944                 int has_precision;
2945                 size_t precision;
2946                 size_t tmp_length;
2947                 DCHAR_T tmpbuf[700];
2948                 DCHAR_T *tmp;
2949                 DCHAR_T *pad_ptr;
2950                 DCHAR_T *p;
2951 
2952                 has_width = 0;
2953                 width = 0;
2954                 if (dp->width_start != dp->width_end)
2955                   {
2956                     if (dp->width_arg_index != ARG_NONE)
2957                       {
2958                         int arg;
2959 
2960                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2961                           abort ();
2962                         arg = a.arg[dp->width_arg_index].a.a_int;
2963                         if (arg < 0)
2964                           {
2965                             /* "A negative field width is taken as a '-' flag
2966                                 followed by a positive field width."  */
2967                             flags |= FLAG_LEFT;
2968                             width = (unsigned int) (-arg);
2969                           }
2970                         else
2971                           width = arg;
2972                       }
2973                     else
2974                       {
2975                         const FCHAR_T *digitp = dp->width_start;
2976 
2977                         do
2978                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2979                         while (digitp != dp->width_end);
2980                       }
2981                     has_width = 1;
2982                   }
2983 
2984                 has_precision = 0;
2985                 precision = 0;
2986                 if (dp->precision_start != dp->precision_end)
2987                   {
2988                     if (dp->precision_arg_index != ARG_NONE)
2989                       {
2990                         int arg;
2991 
2992                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2993                           abort ();
2994                         arg = a.arg[dp->precision_arg_index].a.a_int;
2995                         /* "A negative precision is taken as if the precision
2996                             were omitted."  */
2997                         if (arg >= 0)
2998                           {
2999                             precision = arg;
3000                             has_precision = 1;
3001                           }
3002                       }
3003                     else
3004                       {
3005                         const FCHAR_T *digitp = dp->precision_start + 1;
3006 
3007                         precision = 0;
3008                         while (digitp != dp->precision_end)
3009                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3010                         has_precision = 1;
3011                       }
3012                   }
3013 
3014                 /* Allocate a temporary buffer of sufficient size.  */
3015                 if (type == TYPE_LONGDOUBLE)
3016                   tmp_length =
3017                     (unsigned int) ((LDBL_DIG + 1)
3018                                     * 0.831 /* decimal -> hexadecimal */
3019                                    )
3020                     + 1; /* turn floor into ceil */
3021                 else
3022                   tmp_length =
3023                     (unsigned int) ((DBL_DIG + 1)
3024                                     * 0.831 /* decimal -> hexadecimal */
3025                                    )
3026                     + 1; /* turn floor into ceil */
3027                 if (tmp_length < precision)
3028                   tmp_length = precision;
3029                 /* Account for sign, decimal point etc. */
3030                 tmp_length = xsum (tmp_length, 12);
3031 
3032                 if (tmp_length < width)
3033                   tmp_length = width;
3034 
3035                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3036 
3037                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3038                   tmp = tmpbuf;
3039                 else
3040                   {
3041                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3042 
3043                     if (size_overflow_p (tmp_memsize))
3044                       /* Overflow, would lead to out of memory.  */
3045                       goto out_of_memory;
3046                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3047                     if (tmp == NULL)
3048                       /* Out of memory.  */
3049                       goto out_of_memory;
3050                   }
3051 
3052                 pad_ptr = NULL;
3053                 p = tmp;
3054                 if (type == TYPE_LONGDOUBLE)
3055                   {
3056 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3057                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3058 
3059                     if (isnanl (arg))
3060                       {
3061                         if (dp->conversion == 'A')
3062                           {
3063                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3064                           }
3065                         else
3066                           {
3067                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3068                           }
3069                       }
3070                     else
3071                       {
3072                         int sign = 0;
3073                         DECL_LONG_DOUBLE_ROUNDING
3074 
3075                         BEGIN_LONG_DOUBLE_ROUNDING ();
3076 
3077                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3078                           {
3079                             sign = -1;
3080                             arg = -arg;
3081                           }
3082 
3083                         if (sign < 0)
3084                           *p++ = '-';
3085                         else if (flags & FLAG_SHOWSIGN)
3086                           *p++ = '+';
3087                         else if (flags & FLAG_SPACE)
3088                           *p++ = ' ';
3089 
3090                         if (arg > 0.0L && arg + arg == arg)
3091                           {
3092                             if (dp->conversion == 'A')
3093                               {
3094                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3095                               }
3096                             else
3097                               {
3098                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3099                               }
3100                           }
3101                         else
3102                           {
3103                             int exponent;
3104                             long double mantissa;
3105 
3106                             if (arg > 0.0L)
3107                               mantissa = printf_frexpl (arg, &exponent);
3108                             else
3109                               {
3110                                 exponent = 0;
3111                                 mantissa = 0.0L;
3112                               }
3113 
3114                             if (has_precision
3115                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3116                               {
3117                                 /* Round the mantissa.  */
3118                                 long double tail = mantissa;
3119                                 size_t q;
3120 
3121                                 for (q = precision; ; q--)
3122                                   {
3123                                     int digit = (int) tail;
3124                                     tail -= digit;
3125                                     if (q == 0)
3126                                       {
3127                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3128                                           tail = 1 - tail;
3129                                         else
3130                                           tail = - tail;
3131                                         break;
3132                                       }
3133                                     tail *= 16.0L;
3134                                   }
3135                                 if (tail != 0.0L)
3136                                   for (q = precision; q > 0; q--)
3137                                     tail *= 0.0625L;
3138                                 mantissa += tail;
3139                               }
3140 
3141                             *p++ = '0';
3142                             *p++ = dp->conversion - 'A' + 'X';
3143                             pad_ptr = p;
3144                             {
3145                               int digit;
3146 
3147                               digit = (int) mantissa;
3148                               mantissa -= digit;
3149                               *p++ = '0' + digit;
3150                               if ((flags & FLAG_ALT)
3151                                   || mantissa > 0.0L || precision > 0)
3152                                 {
3153                                   *p++ = decimal_point_char ();
3154                                   /* This loop terminates because we assume
3155                                      that FLT_RADIX is a power of 2.  */
3156                                   while (mantissa > 0.0L)
3157                                     {
3158                                       mantissa *= 16.0L;
3159                                       digit = (int) mantissa;
3160                                       mantissa -= digit;
3161                                       *p++ = digit
3162                                              + (digit < 10
3163                                                 ? '0'
3164                                                 : dp->conversion - 10);
3165                                       if (precision > 0)
3166                                         precision--;
3167                                     }
3168                                   while (precision > 0)
3169                                     {
3170                                       *p++ = '0';
3171                                       precision--;
3172                                     }
3173                                 }
3174                               }
3175                               *p++ = dp->conversion - 'A' + 'P';
3176 #  if WIDE_CHAR_VERSION
3177                               {
3178                                 static const wchar_t decimal_format[] =
3179                                   { '%', '+', 'd', '\0' };
3180                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3181                               }
3182                               while (*p != '\0')
3183                                 p++;
3184 #  else
3185                               if (sizeof (DCHAR_T) == 1)
3186                                 {
3187                                   sprintf ((char *) p, "%+d", exponent);
3188                                   while (*p != '\0')
3189                                     p++;
3190                                 }
3191                               else
3192                                 {
3193                                   char expbuf[6 + 1];
3194                                   const char *ep;
3195                                   sprintf (expbuf, "%+d", exponent);
3196                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3197                                     p++;
3198                                 }
3199 #  endif
3200                           }
3201 
3202                         END_LONG_DOUBLE_ROUNDING ();
3203                       }
3204 # else
3205                     abort ();
3206 # endif
3207                   }
3208                 else
3209                   {
3210 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3211                     double arg = a.arg[dp->arg_index].a.a_double;
3212 
3213                     if (isnand (arg))
3214                       {
3215                         if (dp->conversion == 'A')
3216                           {
3217                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3218                           }
3219                         else
3220                           {
3221                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3222                           }
3223                       }
3224                     else
3225                       {
3226                         int sign = 0;
3227 
3228                         if (signbit (arg)) /* arg < 0.0 or negative zero */
3229                           {
3230                             sign = -1;
3231                             arg = -arg;
3232                           }
3233 
3234                         if (sign < 0)
3235                           *p++ = '-';
3236                         else if (flags & FLAG_SHOWSIGN)
3237                           *p++ = '+';
3238                         else if (flags & FLAG_SPACE)
3239                           *p++ = ' ';
3240 
3241                         if (arg > 0.0 && arg + arg == arg)
3242                           {
3243                             if (dp->conversion == 'A')
3244                               {
3245                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3246                               }
3247                             else
3248                               {
3249                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3250                               }
3251                           }
3252                         else
3253                           {
3254                             int exponent;
3255                             double mantissa;
3256 
3257                             if (arg > 0.0)
3258                               mantissa = printf_frexp (arg, &exponent);
3259                             else
3260                               {
3261                                 exponent = 0;
3262                                 mantissa = 0.0;
3263                               }
3264 
3265                             if (has_precision
3266                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3267                               {
3268                                 /* Round the mantissa.  */
3269                                 double tail = mantissa;
3270                                 size_t q;
3271 
3272                                 for (q = precision; ; q--)
3273                                   {
3274                                     int digit = (int) tail;
3275                                     tail -= digit;
3276                                     if (q == 0)
3277                                       {
3278                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3279                                           tail = 1 - tail;
3280                                         else
3281                                           tail = - tail;
3282                                         break;
3283                                       }
3284                                     tail *= 16.0;
3285                                   }
3286                                 if (tail != 0.0)
3287                                   for (q = precision; q > 0; q--)
3288                                     tail *= 0.0625;
3289                                 mantissa += tail;
3290                               }
3291 
3292                             *p++ = '0';
3293                             *p++ = dp->conversion - 'A' + 'X';
3294                             pad_ptr = p;
3295                             {
3296                               int digit;
3297 
3298                               digit = (int) mantissa;
3299                               mantissa -= digit;
3300                               *p++ = '0' + digit;
3301                               if ((flags & FLAG_ALT)
3302                                   || mantissa > 0.0 || precision > 0)
3303                                 {
3304                                   *p++ = decimal_point_char ();
3305                                   /* This loop terminates because we assume
3306                                      that FLT_RADIX is a power of 2.  */
3307                                   while (mantissa > 0.0)
3308                                     {
3309                                       mantissa *= 16.0;
3310                                       digit = (int) mantissa;
3311                                       mantissa -= digit;
3312                                       *p++ = digit
3313                                              + (digit < 10
3314                                                 ? '0'
3315                                                 : dp->conversion - 10);
3316                                       if (precision > 0)
3317                                         precision--;
3318                                     }
3319                                   while (precision > 0)
3320                                     {
3321                                       *p++ = '0';
3322                                       precision--;
3323                                     }
3324                                 }
3325                               }
3326                               *p++ = dp->conversion - 'A' + 'P';
3327 #  if WIDE_CHAR_VERSION
3328                               {
3329                                 static const wchar_t decimal_format[] =
3330                                   { '%', '+', 'd', '\0' };
3331                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3332                               }
3333                               while (*p != '\0')
3334                                 p++;
3335 #  else
3336                               if (sizeof (DCHAR_T) == 1)
3337                                 {
3338                                   sprintf ((char *) p, "%+d", exponent);
3339                                   while (*p != '\0')
3340                                     p++;
3341                                 }
3342                               else
3343                                 {
3344                                   char expbuf[6 + 1];
3345                                   const char *ep;
3346                                   sprintf (expbuf, "%+d", exponent);
3347                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3348                                     p++;
3349                                 }
3350 #  endif
3351                           }
3352                       }
3353 # else
3354                     abort ();
3355 # endif
3356                   }
3357                 /* The generated string now extends from tmp to p, with the
3358                    zero padding insertion point being at pad_ptr.  */
3359                 if (has_width && p - tmp < width)
3360                   {
3361                     size_t pad = width - (p - tmp);
3362                     DCHAR_T *end = p + pad;
3363 
3364                     if (flags & FLAG_LEFT)
3365                       {
3366                         /* Pad with spaces on the right.  */
3367                         for (; pad > 0; pad--)
3368                           *p++ = ' ';
3369                       }
3370                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3371                       {
3372                         /* Pad with zeroes.  */
3373                         DCHAR_T *q = end;
3374 
3375                         while (p > pad_ptr)
3376                           *--q = *--p;
3377                         for (; pad > 0; pad--)
3378                           *p++ = '0';
3379                       }
3380                     else
3381                       {
3382                         /* Pad with spaces on the left.  */
3383                         DCHAR_T *q = end;
3384 
3385                         while (p > tmp)
3386                           *--q = *--p;
3387                         for (; pad > 0; pad--)
3388                           *p++ = ' ';
3389                       }
3390 
3391                     p = end;
3392                   }
3393 
3394                 {
3395                   size_t count = p - tmp;
3396 
3397                   if (count >= tmp_length)
3398                     /* tmp_length was incorrectly calculated - fix the
3399                        code above!  */
3400                     abort ();
3401 
3402                   /* Make room for the result.  */
3403                   if (count >= allocated - length)
3404                     {
3405                       size_t n = xsum (length, count);
3406 
3407                       ENSURE_ALLOCATION (n);
3408                     }
3409 
3410                   /* Append the result.  */
3411                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3412                   if (tmp != tmpbuf)
3413                     free (tmp);
3414                   length += count;
3415                 }
3416               }
3417 #endif
3418 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3419             else if ((dp->conversion == 'f' || dp->conversion == 'F'
3420                       || dp->conversion == 'e' || dp->conversion == 'E'
3421                       || dp->conversion == 'g' || dp->conversion == 'G'
3422                       || dp->conversion == 'a' || dp->conversion == 'A')
3423                      && (0
3424 # if NEED_PRINTF_DOUBLE
3425                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
3426 # elif NEED_PRINTF_INFINITE_DOUBLE
3427                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3428                              /* The systems (mingw) which produce wrong output
3429                                 for Inf, -Inf, and NaN also do so for -0.0.
3430                                 Therefore we treat this case here as well.  */
3431                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3432 # endif
3433 # if NEED_PRINTF_LONG_DOUBLE
3434                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3435 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3436                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3437                              /* Some systems produce wrong output for Inf,
3438                                 -Inf, and NaN.  Some systems in this category
3439                                 (IRIX 5.3) also do so for -0.0.  Therefore we
3440                                 treat this case here as well.  */
3441                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3442 # endif
3443                         ))
3444               {
3445 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3446                 arg_type type = a.arg[dp->arg_index].type;
3447 # endif
3448                 int flags = dp->flags;
3449                 int has_width;
3450                 size_t width;
3451                 int has_precision;
3452                 size_t precision;
3453                 size_t tmp_length;
3454                 DCHAR_T tmpbuf[700];
3455                 DCHAR_T *tmp;
3456                 DCHAR_T *pad_ptr;
3457                 DCHAR_T *p;
3458 
3459                 has_width = 0;
3460                 width = 0;
3461                 if (dp->width_start != dp->width_end)
3462                   {
3463                     if (dp->width_arg_index != ARG_NONE)
3464                       {
3465                         int arg;
3466 
3467                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3468                           abort ();
3469                         arg = a.arg[dp->width_arg_index].a.a_int;
3470                         if (arg < 0)
3471                           {
3472                             /* "A negative field width is taken as a '-' flag
3473                                 followed by a positive field width."  */
3474                             flags |= FLAG_LEFT;
3475                             width = (unsigned int) (-arg);
3476                           }
3477                         else
3478                           width = arg;
3479                       }
3480                     else
3481                       {
3482                         const FCHAR_T *digitp = dp->width_start;
3483 
3484                         do
3485                           width = xsum (xtimes (width, 10), *digitp++ - '0');
3486                         while (digitp != dp->width_end);
3487                       }
3488                     has_width = 1;
3489                   }
3490 
3491                 has_precision = 0;
3492                 precision = 0;
3493                 if (dp->precision_start != dp->precision_end)
3494                   {
3495                     if (dp->precision_arg_index != ARG_NONE)
3496                       {
3497                         int arg;
3498 
3499                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3500                           abort ();
3501                         arg = a.arg[dp->precision_arg_index].a.a_int;
3502                         /* "A negative precision is taken as if the precision
3503                             were omitted."  */
3504                         if (arg >= 0)
3505                           {
3506                             precision = arg;
3507                             has_precision = 1;
3508                           }
3509                       }
3510                     else
3511                       {
3512                         const FCHAR_T *digitp = dp->precision_start + 1;
3513 
3514                         precision = 0;
3515                         while (digitp != dp->precision_end)
3516                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3517                         has_precision = 1;
3518                       }
3519                   }
3520 
3521                 /* POSIX specifies the default precision to be 6 for %f, %F,
3522                    %e, %E, but not for %g, %G.  Implementations appear to use
3523                    the same default precision also for %g, %G.  But for %a, %A,
3524                    the default precision is 0.  */
3525                 if (!has_precision)
3526                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3527                     precision = 6;
3528 
3529                 /* Allocate a temporary buffer of sufficient size.  */
3530 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3531                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3532 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3533                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3534 # elif NEED_PRINTF_LONG_DOUBLE
3535                 tmp_length = LDBL_DIG + 1;
3536 # elif NEED_PRINTF_DOUBLE
3537                 tmp_length = DBL_DIG + 1;
3538 # else
3539                 tmp_length = 0;
3540 # endif
3541                 if (tmp_length < precision)
3542                   tmp_length = precision;
3543 # if NEED_PRINTF_LONG_DOUBLE
3544 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3545                 if (type == TYPE_LONGDOUBLE)
3546 #  endif
3547                   if (dp->conversion == 'f' || dp->conversion == 'F')
3548                     {
3549                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
3550                       if (!(isnanl (arg) || arg + arg == arg))
3551                         {
3552                           /* arg is finite and nonzero.  */
3553                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
3554                           if (exponent >= 0 && tmp_length < exponent + precision)
3555                             tmp_length = exponent + precision;
3556                         }
3557                     }
3558 # endif
3559 # if NEED_PRINTF_DOUBLE
3560 #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3561                 if (type == TYPE_DOUBLE)
3562 #  endif
3563                   if (dp->conversion == 'f' || dp->conversion == 'F')
3564                     {
3565                       double arg = a.arg[dp->arg_index].a.a_double;
3566                       if (!(isnand (arg) || arg + arg == arg))
3567                         {
3568                           /* arg is finite and nonzero.  */
3569                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
3570                           if (exponent >= 0 && tmp_length < exponent + precision)
3571                             tmp_length = exponent + precision;
3572                         }
3573                     }
3574 # endif
3575                 /* Account for sign, decimal point etc. */
3576                 tmp_length = xsum (tmp_length, 12);
3577 
3578                 if (tmp_length < width)
3579                   tmp_length = width;
3580 
3581                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3582 
3583                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3584                   tmp = tmpbuf;
3585                 else
3586                   {
3587                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3588 
3589                     if (size_overflow_p (tmp_memsize))
3590                       /* Overflow, would lead to out of memory.  */
3591                       goto out_of_memory;
3592                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3593                     if (tmp == NULL)
3594                       /* Out of memory.  */
3595                       goto out_of_memory;
3596                   }
3597 
3598                 pad_ptr = NULL;
3599                 p = tmp;
3600 
3601 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3602 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3603                 if (type == TYPE_LONGDOUBLE)
3604 #  endif
3605                   {
3606                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3607 
3608                     if (isnanl (arg))
3609                       {
3610                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3611                           {
3612                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3613                           }
3614                         else
3615                           {
3616                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3617                           }
3618                       }
3619                     else
3620                       {
3621                         int sign = 0;
3622                         DECL_LONG_DOUBLE_ROUNDING
3623 
3624                         BEGIN_LONG_DOUBLE_ROUNDING ();
3625 
3626                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3627                           {
3628                             sign = -1;
3629                             arg = -arg;
3630                           }
3631 
3632                         if (sign < 0)
3633                           *p++ = '-';
3634                         else if (flags & FLAG_SHOWSIGN)
3635                           *p++ = '+';
3636                         else if (flags & FLAG_SPACE)
3637                           *p++ = ' ';
3638 
3639                         if (arg > 0.0L && arg + arg == arg)
3640                           {
3641                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3642                               {
3643                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3644                               }
3645                             else
3646                               {
3647                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3648                               }
3649                           }
3650                         else
3651                           {
3652 #  if NEED_PRINTF_LONG_DOUBLE
3653                             pad_ptr = p;
3654 
3655                             if (dp->conversion == 'f' || dp->conversion == 'F')
3656                               {
3657                                 char *digits;
3658                                 size_t ndigits;
3659 
3660                                 digits =
3661                                   scale10_round_decimal_long_double (arg, precision);
3662                                 if (digits == NULL)
3663                                   {
3664                                     END_LONG_DOUBLE_ROUNDING ();
3665                                     goto out_of_memory;
3666                                   }
3667                                 ndigits = strlen (digits);
3668 
3669                                 if (ndigits > precision)
3670                                   do
3671                                     {
3672                                       --ndigits;
3673                                       *p++ = digits[ndigits];
3674                                     }
3675                                   while (ndigits > precision);
3676                                 else
3677                                   *p++ = '0';
3678                                 /* Here ndigits <= precision.  */
3679                                 if ((flags & FLAG_ALT) || precision > 0)
3680                                   {
3681                                     *p++ = decimal_point_char ();
3682                                     for (; precision > ndigits; precision--)
3683                                       *p++ = '0';
3684                                     while (ndigits > 0)
3685                                       {
3686                                         --ndigits;
3687                                         *p++ = digits[ndigits];
3688                                       }
3689                                   }
3690 
3691                                 free (digits);
3692                               }
3693                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3694                               {
3695                                 int exponent;
3696 
3697                                 if (arg == 0.0L)
3698                                   {
3699                                     exponent = 0;
3700                                     *p++ = '0';
3701                                     if ((flags & FLAG_ALT) || precision > 0)
3702                                       {
3703                                         *p++ = decimal_point_char ();
3704                                         for (; precision > 0; precision--)
3705                                           *p++ = '0';
3706                                       }
3707                                   }
3708                                 else
3709                                   {
3710                                     /* arg > 0.0L.  */
3711                                     int adjusted;
3712                                     char *digits;
3713                                     size_t ndigits;
3714 
3715                                     exponent = floorlog10l (arg);
3716                                     adjusted = 0;
3717                                     for (;;)
3718                                       {
3719                                         digits =
3720                                           scale10_round_decimal_long_double (arg,
3721                                                                              (int)precision - exponent);
3722                                         if (digits == NULL)
3723                                           {
3724                                             END_LONG_DOUBLE_ROUNDING ();
3725                                             goto out_of_memory;
3726                                           }
3727                                         ndigits = strlen (digits);
3728 
3729                                         if (ndigits == precision + 1)
3730                                           break;
3731                                         if (ndigits < precision
3732                                             || ndigits > precision + 2)
3733                                           /* The exponent was not guessed
3734                                              precisely enough.  */
3735                                           abort ();
3736                                         if (adjusted)
3737                                           /* None of two values of exponent is
3738                                              the right one.  Prevent an endless
3739                                              loop.  */
3740                                           abort ();
3741                                         free (digits);
3742                                         if (ndigits == precision)
3743                                           exponent -= 1;
3744                                         else
3745                                           exponent += 1;
3746                                         adjusted = 1;
3747                                       }
3748                                     /* Here ndigits = precision+1.  */
3749                                     if (is_borderline (digits, precision))
3750                                       {
3751                                         /* Maybe the exponent guess was too high
3752                                            and a smaller exponent can be reached
3753                                            by turning a 10...0 into 9...9x.  */
3754                                         char *digits2 =
3755                                           scale10_round_decimal_long_double (arg,
3756                                                                              (int)precision - exponent + 1);
3757                                         if (digits2 == NULL)
3758                                           {
3759                                             free (digits);
3760                                             END_LONG_DOUBLE_ROUNDING ();
3761                                             goto out_of_memory;
3762                                           }
3763                                         if (strlen (digits2) == precision + 1)
3764                                           {
3765                                             free (digits);
3766                                             digits = digits2;
3767                                             exponent -= 1;
3768                                           }
3769                                         else
3770                                           free (digits2);
3771                                       }
3772                                     /* Here ndigits = precision+1.  */
3773 
3774                                     *p++ = digits[--ndigits];
3775                                     if ((flags & FLAG_ALT) || precision > 0)
3776                                       {
3777                                         *p++ = decimal_point_char ();
3778                                         while (ndigits > 0)
3779                                           {
3780                                             --ndigits;
3781                                             *p++ = digits[ndigits];
3782                                           }
3783                                       }
3784 
3785                                     free (digits);
3786                                   }
3787 
3788                                 *p++ = dp->conversion; /* 'e' or 'E' */
3789 #   if WIDE_CHAR_VERSION
3790                                 {
3791                                   static const wchar_t decimal_format[] =
3792                                     { '%', '+', '.', '2', 'd', '\0' };
3793                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
3794                                 }
3795                                 while (*p != '\0')
3796                                   p++;
3797 #   else
3798                                 if (sizeof (DCHAR_T) == 1)
3799                                   {
3800                                     sprintf ((char *) p, "%+.2d", exponent);
3801                                     while (*p != '\0')
3802                                       p++;
3803                                   }
3804                                 else
3805                                   {
3806                                     char expbuf[6 + 1];
3807                                     const char *ep;
3808                                     sprintf (expbuf, "%+.2d", exponent);
3809                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3810                                       p++;
3811                                   }
3812 #   endif
3813                               }
3814                             else if (dp->conversion == 'g' || dp->conversion == 'G')
3815                               {
3816                                 if (precision == 0)
3817                                   precision = 1;
3818                                 /* precision >= 1.  */
3819 
3820                                 if (arg == 0.0L)
3821                                   /* The exponent is 0, >= -4, < precision.
3822                                      Use fixed-point notation.  */
3823                                   {
3824                                     size_t ndigits = precision;
3825                                     /* Number of trailing zeroes that have to be
3826                                        dropped.  */
3827                                     size_t nzeroes =
3828                                       (flags & FLAG_ALT ? 0 : precision - 1);
3829 
3830                                     --ndigits;
3831                                     *p++ = '0';
3832                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
3833                                       {
3834                                         *p++ = decimal_point_char ();
3835                                         while (ndigits > nzeroes)
3836                                           {
3837                                             --ndigits;
3838                                             *p++ = '0';
3839                                           }
3840                                       }
3841                                   }
3842                                 else
3843                                   {
3844                                     /* arg > 0.0L.  */
3845                                     int exponent;
3846                                     int adjusted;
3847                                     char *digits;
3848                                     size_t ndigits;
3849                                     size_t nzeroes;
3850 
3851                                     exponent = floorlog10l (arg);
3852                                     adjusted = 0;
3853                                     for (;;)
3854                                       {
3855                                         digits =
3856                                           scale10_round_decimal_long_double (arg,
3857                                                                              (int)(precision - 1) - exponent);
3858                                         if (digits == NULL)
3859                                           {
3860                                             END_LONG_DOUBLE_ROUNDING ();
3861                                             goto out_of_memory;
3862                                           }
3863                                         ndigits = strlen (digits);
3864 
3865                                         if (ndigits == precision)
3866                                           break;
3867                                         if (ndigits < precision - 1
3868                                             || ndigits > precision + 1)
3869                                           /* The exponent was not guessed
3870                                              precisely enough.  */
3871                                           abort ();
3872                                         if (adjusted)
3873                                           /* None of two values of exponent is
3874                                              the right one.  Prevent an endless
3875                                              loop.  */
3876                                           abort ();
3877                                         free (digits);
3878                                         if (ndigits < precision)
3879                                           exponent -= 1;
3880                                         else
3881                                           exponent += 1;
3882                                         adjusted = 1;
3883                                       }
3884                                     /* Here ndigits = precision.  */
3885                                     if (is_borderline (digits, precision - 1))
3886                                       {
3887                                         /* Maybe the exponent guess was too high
3888                                            and a smaller exponent can be reached
3889                                            by turning a 10...0 into 9...9x.  */
3890                                         char *digits2 =
3891                                           scale10_round_decimal_long_double (arg,
3892                                                                              (int)(precision - 1) - exponent + 1);
3893                                         if (digits2 == NULL)
3894                                           {
3895                                             free (digits);
3896                                             END_LONG_DOUBLE_ROUNDING ();
3897                                             goto out_of_memory;
3898                                           }
3899                                         if (strlen (digits2) == precision)
3900                                           {
3901                                             free (digits);
3902                                             digits = digits2;
3903                                             exponent -= 1;
3904                                           }
3905                                         else
3906                                           free (digits2);
3907                                       }
3908                                     /* Here ndigits = precision.  */
3909 
3910                                     /* Determine the number of trailing zeroes
3911                                        that have to be dropped.  */
3912                                     nzeroes = 0;
3913                                     if ((flags & FLAG_ALT) == 0)
3914                                       while (nzeroes < ndigits
3915                                              && digits[nzeroes] == '0')
3916                                         nzeroes++;
3917 
3918                                     /* The exponent is now determined.  */
3919                                     if (exponent >= -4
3920                                         && exponent < (long)precision)
3921                                       {
3922                                         /* Fixed-point notation:
3923                                            max(exponent,0)+1 digits, then the
3924                                            decimal point, then the remaining
3925                                            digits without trailing zeroes.  */
3926                                         if (exponent >= 0)
3927                                           {
3928                                             size_t count = exponent + 1;
3929                                             /* Note: count <= precision = ndigits.  */
3930                                             for (; count > 0; count--)
3931                                               *p++ = digits[--ndigits];
3932                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
3933                                               {
3934                                                 *p++ = decimal_point_char ();
3935                                                 while (ndigits > nzeroes)
3936                                                   {
3937                                                     --ndigits;
3938                                                     *p++ = digits[ndigits];
3939                                                   }
3940                                               }
3941                                           }
3942                                         else
3943                                           {
3944                                             size_t count = -exponent - 1;
3945                                             *p++ = '0';
3946                                             *p++ = decimal_point_char ();
3947                                             for (; count > 0; count--)
3948                                               *p++ = '0';
3949                                             while (ndigits > nzeroes)
3950                                               {
3951                                                 --ndigits;
3952                                                 *p++ = digits[ndigits];
3953                                               }
3954                                           }
3955                                       }
3956                                     else
3957                                       {
3958                                         /* Exponential notation.  */
3959                                         *p++ = digits[--ndigits];
3960                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
3961                                           {
3962                                             *p++ = decimal_point_char ();
3963                                             while (ndigits > nzeroes)
3964                                               {
3965                                                 --ndigits;
3966                                                 *p++ = digits[ndigits];
3967                                               }
3968                                           }
3969                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3970 #   if WIDE_CHAR_VERSION
3971                                         {
3972                                           static const wchar_t decimal_format[] =
3973                                             { '%', '+', '.', '2', 'd', '\0' };
3974                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
3975                                         }
3976                                         while (*p != '\0')
3977                                           p++;
3978 #   else
3979                                         if (sizeof (DCHAR_T) == 1)
3980                                           {
3981                                             sprintf ((char *) p, "%+.2d", exponent);
3982                                             while (*p != '\0')
3983                                               p++;
3984                                           }
3985                                         else
3986                                           {
3987                                             char expbuf[6 + 1];
3988                                             const char *ep;
3989                                             sprintf (expbuf, "%+.2d", exponent);
3990                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3991                                               p++;
3992                                           }
3993 #   endif
3994                                       }
3995 
3996                                     free (digits);
3997                                   }
3998                               }
3999                             else
4000                               abort ();
4001 #  else
4002                             /* arg is finite.  */
4003                             if (!(arg == 0.0L))
4004                               abort ();
4005 
4006                             pad_ptr = p;
4007 
4008                             if (dp->conversion == 'f' || dp->conversion == 'F')
4009                               {
4010                                 *p++ = '0';
4011                                 if ((flags & FLAG_ALT) || precision > 0)
4012                                   {
4013                                     *p++ = decimal_point_char ();
4014                                     for (; precision > 0; precision--)
4015                                       *p++ = '0';
4016                                   }
4017                               }
4018                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4019                               {
4020                                 *p++ = '0';
4021                                 if ((flags & FLAG_ALT) || precision > 0)
4022                                   {
4023                                     *p++ = decimal_point_char ();
4024                                     for (; precision > 0; precision--)
4025                                       *p++ = '0';
4026                                   }
4027                                 *p++ = dp->conversion; /* 'e' or 'E' */
4028                                 *p++ = '+';
4029                                 *p++ = '0';
4030                                 *p++ = '0';
4031                               }
4032                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4033                               {
4034                                 *p++ = '0';
4035                                 if (flags & FLAG_ALT)
4036                                   {
4037                                     size_t ndigits =
4038                                       (precision > 0 ? precision - 1 : 0);
4039                                     *p++ = decimal_point_char ();
4040                                     for (; ndigits > 0; --ndigits)
4041                                       *p++ = '0';
4042                                   }
4043                               }
4044                             else if (dp->conversion == 'a' || dp->conversion == 'A')
4045                               {
4046                                 *p++ = '0';
4047                                 *p++ = dp->conversion - 'A' + 'X';
4048                                 pad_ptr = p;
4049                                 *p++ = '0';
4050                                 if ((flags & FLAG_ALT) || precision > 0)
4051                                   {
4052                                     *p++ = decimal_point_char ();
4053                                     for (; precision > 0; precision--)
4054                                       *p++ = '0';
4055                                   }
4056                                 *p++ = dp->conversion - 'A' + 'P';
4057                                 *p++ = '+';
4058                                 *p++ = '0';
4059                               }
4060                             else
4061                               abort ();
4062 #  endif
4063                           }
4064 
4065                         END_LONG_DOUBLE_ROUNDING ();
4066                       }
4067                   }
4068 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4069                 else
4070 #  endif
4071 # endif
4072 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4073                   {
4074                     double arg = a.arg[dp->arg_index].a.a_double;
4075 
4076                     if (isnand (arg))
4077                       {
4078                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4079                           {
4080                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4081                           }
4082                         else
4083                           {
4084                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4085                           }
4086                       }
4087                     else
4088                       {
4089                         int sign = 0;
4090 
4091                         if (signbit (arg)) /* arg < 0.0 or negative zero */
4092                           {
4093                             sign = -1;
4094                             arg = -arg;
4095                           }
4096 
4097                         if (sign < 0)
4098                           *p++ = '-';
4099                         else if (flags & FLAG_SHOWSIGN)
4100                           *p++ = '+';
4101                         else if (flags & FLAG_SPACE)
4102                           *p++ = ' ';
4103 
4104                         if (arg > 0.0 && arg + arg == arg)
4105                           {
4106                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4107                               {
4108                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4109                               }
4110                             else
4111                               {
4112                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4113                               }
4114                           }
4115                         else
4116                           {
4117 #  if NEED_PRINTF_DOUBLE
4118                             pad_ptr = p;
4119 
4120                             if (dp->conversion == 'f' || dp->conversion == 'F')
4121                               {
4122                                 char *digits;
4123                                 size_t ndigits;
4124 
4125                                 digits =
4126                                   scale10_round_decimal_double (arg, precision);
4127                                 if (digits == NULL)
4128                                   goto out_of_memory;
4129                                 ndigits = strlen (digits);
4130 
4131                                 if (ndigits > precision)
4132                                   do
4133                                     {
4134                                       --ndigits;
4135                                       *p++ = digits[ndigits];
4136                                     }
4137                                   while (ndigits > precision);
4138                                 else
4139                                   *p++ = '0';
4140                                 /* Here ndigits <= precision.  */
4141                                 if ((flags & FLAG_ALT) || precision > 0)
4142                                   {
4143                                     *p++ = decimal_point_char ();
4144                                     for (; precision > ndigits; precision--)
4145                                       *p++ = '0';
4146                                     while (ndigits > 0)
4147                                       {
4148                                         --ndigits;
4149                                         *p++ = digits[ndigits];
4150                                       }
4151                                   }
4152 
4153                                 free (digits);
4154                               }
4155                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4156                               {
4157                                 int exponent;
4158 
4159                                 if (arg == 0.0)
4160                                   {
4161                                     exponent = 0;
4162                                     *p++ = '0';
4163                                     if ((flags & FLAG_ALT) || precision > 0)
4164                                       {
4165                                         *p++ = decimal_point_char ();
4166                                         for (; precision > 0; precision--)
4167                                           *p++ = '0';
4168                                       }
4169                                   }
4170                                 else
4171                                   {
4172                                     /* arg > 0.0.  */
4173                                     int adjusted;
4174                                     char *digits;
4175                                     size_t ndigits;
4176 
4177                                     exponent = floorlog10 (arg);
4178                                     adjusted = 0;
4179                                     for (;;)
4180                                       {
4181                                         digits =
4182                                           scale10_round_decimal_double (arg,
4183                                                                         (int)precision - exponent);
4184                                         if (digits == NULL)
4185                                           goto out_of_memory;
4186                                         ndigits = strlen (digits);
4187 
4188                                         if (ndigits == precision + 1)
4189                                           break;
4190                                         if (ndigits < precision
4191                                             || ndigits > precision + 2)
4192                                           /* The exponent was not guessed
4193                                              precisely enough.  */
4194                                           abort ();
4195                                         if (adjusted)
4196                                           /* None of two values of exponent is
4197                                              the right one.  Prevent an endless
4198                                              loop.  */
4199                                           abort ();
4200                                         free (digits);
4201                                         if (ndigits == precision)
4202                                           exponent -= 1;
4203                                         else
4204                                           exponent += 1;
4205                                         adjusted = 1;
4206                                       }
4207                                     /* Here ndigits = precision+1.  */
4208                                     if (is_borderline (digits, precision))
4209                                       {
4210                                         /* Maybe the exponent guess was too high
4211                                            and a smaller exponent can be reached
4212                                            by turning a 10...0 into 9...9x.  */
4213                                         char *digits2 =
4214                                           scale10_round_decimal_double (arg,
4215                                                                         (int)precision - exponent + 1);
4216                                         if (digits2 == NULL)
4217                                           {
4218                                             free (digits);
4219                                             goto out_of_memory;
4220                                           }
4221                                         if (strlen (digits2) == precision + 1)
4222                                           {
4223                                             free (digits);
4224                                             digits = digits2;
4225                                             exponent -= 1;
4226                                           }
4227                                         else
4228                                           free (digits2);
4229                                       }
4230                                     /* Here ndigits = precision+1.  */
4231 
4232                                     *p++ = digits[--ndigits];
4233                                     if ((flags & FLAG_ALT) || precision > 0)
4234                                       {
4235                                         *p++ = decimal_point_char ();
4236                                         while (ndigits > 0)
4237                                           {
4238                                             --ndigits;
4239                                             *p++ = digits[ndigits];
4240                                           }
4241                                       }
4242 
4243                                     free (digits);
4244                                   }
4245 
4246                                 *p++ = dp->conversion; /* 'e' or 'E' */
4247 #   if WIDE_CHAR_VERSION
4248                                 {
4249                                   static const wchar_t decimal_format[] =
4250                                     /* Produce the same number of exponent digits
4251                                        as the native printf implementation.  */
4252 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4253                                     { '%', '+', '.', '3', 'd', '\0' };
4254 #    else
4255                                     { '%', '+', '.', '2', 'd', '\0' };
4256 #    endif
4257                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
4258                                 }
4259                                 while (*p != '\0')
4260                                   p++;
4261 #   else
4262                                 {
4263                                   static const char decimal_format[] =
4264                                     /* Produce the same number of exponent digits
4265                                        as the native printf implementation.  */
4266 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4267                                     "%+.3d";
4268 #    else
4269                                     "%+.2d";
4270 #    endif
4271                                   if (sizeof (DCHAR_T) == 1)
4272                                     {
4273                                       sprintf ((char *) p, decimal_format, exponent);
4274                                       while (*p != '\0')
4275                                         p++;
4276                                     }
4277                                   else
4278                                     {
4279                                       char expbuf[6 + 1];
4280                                       const char *ep;
4281                                       sprintf (expbuf, decimal_format, exponent);
4282                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4283                                         p++;
4284                                     }
4285                                 }
4286 #   endif
4287                               }
4288                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4289                               {
4290                                 if (precision == 0)
4291                                   precision = 1;
4292                                 /* precision >= 1.  */
4293 
4294                                 if (arg == 0.0)
4295                                   /* The exponent is 0, >= -4, < precision.
4296                                      Use fixed-point notation.  */
4297                                   {
4298                                     size_t ndigits = precision;
4299                                     /* Number of trailing zeroes that have to be
4300                                        dropped.  */
4301                                     size_t nzeroes =
4302                                       (flags & FLAG_ALT ? 0 : precision - 1);
4303 
4304                                     --ndigits;
4305                                     *p++ = '0';
4306                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
4307                                       {
4308                                         *p++ = decimal_point_char ();
4309                                         while (ndigits > nzeroes)
4310                                           {
4311                                             --ndigits;
4312                                             *p++ = '0';
4313                                           }
4314                                       }
4315                                   }
4316                                 else
4317                                   {
4318                                     /* arg > 0.0.  */
4319                                     int exponent;
4320                                     int adjusted;
4321                                     char *digits;
4322                                     size_t ndigits;
4323                                     size_t nzeroes;
4324 
4325                                     exponent = floorlog10 (arg);
4326                                     adjusted = 0;
4327                                     for (;;)
4328                                       {
4329                                         digits =
4330                                           scale10_round_decimal_double (arg,
4331                                                                         (int)(precision - 1) - exponent);
4332                                         if (digits == NULL)
4333                                           goto out_of_memory;
4334                                         ndigits = strlen (digits);
4335 
4336                                         if (ndigits == precision)
4337                                           break;
4338                                         if (ndigits < precision - 1
4339                                             || ndigits > precision + 1)
4340                                           /* The exponent was not guessed
4341                                              precisely enough.  */
4342                                           abort ();
4343                                         if (adjusted)
4344                                           /* None of two values of exponent is
4345                                              the right one.  Prevent an endless
4346                                              loop.  */
4347                                           abort ();
4348                                         free (digits);
4349                                         if (ndigits < precision)
4350                                           exponent -= 1;
4351                                         else
4352                                           exponent += 1;
4353                                         adjusted = 1;
4354                                       }
4355                                     /* Here ndigits = precision.  */
4356                                     if (is_borderline (digits, precision - 1))
4357                                       {
4358                                         /* Maybe the exponent guess was too high
4359                                            and a smaller exponent can be reached
4360                                            by turning a 10...0 into 9...9x.  */
4361                                         char *digits2 =
4362                                           scale10_round_decimal_double (arg,
4363                                                                         (int)(precision - 1) - exponent + 1);
4364                                         if (digits2 == NULL)
4365                                           {
4366                                             free (digits);
4367                                             goto out_of_memory;
4368                                           }
4369                                         if (strlen (digits2) == precision)
4370                                           {
4371                                             free (digits);
4372                                             digits = digits2;
4373                                             exponent -= 1;
4374                                           }
4375                                         else
4376                                           free (digits2);
4377                                       }
4378                                     /* Here ndigits = precision.  */
4379 
4380                                     /* Determine the number of trailing zeroes
4381                                        that have to be dropped.  */
4382                                     nzeroes = 0;
4383                                     if ((flags & FLAG_ALT) == 0)
4384                                       while (nzeroes < ndigits
4385                                              && digits[nzeroes] == '0')
4386                                         nzeroes++;
4387 
4388                                     /* The exponent is now determined.  */
4389                                     if (exponent >= -4
4390                                         && exponent < (long)precision)
4391                                       {
4392                                         /* Fixed-point notation:
4393                                            max(exponent,0)+1 digits, then the
4394                                            decimal point, then the remaining
4395                                            digits without trailing zeroes.  */
4396                                         if (exponent >= 0)
4397                                           {
4398                                             size_t count = exponent + 1;
4399                                             /* Note: count <= precision = ndigits.  */
4400                                             for (; count > 0; count--)
4401                                               *p++ = digits[--ndigits];
4402                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
4403                                               {
4404                                                 *p++ = decimal_point_char ();
4405                                                 while (ndigits > nzeroes)
4406                                                   {
4407                                                     --ndigits;
4408                                                     *p++ = digits[ndigits];
4409                                                   }
4410                                               }
4411                                           }
4412                                         else
4413                                           {
4414                                             size_t count = -exponent - 1;
4415                                             *p++ = '0';
4416                                             *p++ = decimal_point_char ();
4417                                             for (; count > 0; count--)
4418                                               *p++ = '0';
4419                                             while (ndigits > nzeroes)
4420                                               {
4421                                                 --ndigits;
4422                                                 *p++ = digits[ndigits];
4423                                               }
4424                                           }
4425                                       }
4426                                     else
4427                                       {
4428                                         /* Exponential notation.  */
4429                                         *p++ = digits[--ndigits];
4430                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
4431                                           {
4432                                             *p++ = decimal_point_char ();
4433                                             while (ndigits > nzeroes)
4434                                               {
4435                                                 --ndigits;
4436                                                 *p++ = digits[ndigits];
4437                                               }
4438                                           }
4439                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4440 #   if WIDE_CHAR_VERSION
4441                                         {
4442                                           static const wchar_t decimal_format[] =
4443                                             /* Produce the same number of exponent digits
4444                                                as the native printf implementation.  */
4445 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4446                                             { '%', '+', '.', '3', 'd', '\0' };
4447 #    else
4448                                             { '%', '+', '.', '2', 'd', '\0' };
4449 #    endif
4450                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
4451                                         }
4452                                         while (*p != '\0')
4453                                           p++;
4454 #   else
4455                                         {
4456                                           static const char decimal_format[] =
4457                                             /* Produce the same number of exponent digits
4458                                                as the native printf implementation.  */
4459 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4460                                             "%+.3d";
4461 #    else
4462                                             "%+.2d";
4463 #    endif
4464                                           if (sizeof (DCHAR_T) == 1)
4465                                             {
4466                                               sprintf ((char *) p, decimal_format, exponent);
4467                                               while (*p != '\0')
4468                                                 p++;
4469                                             }
4470                                           else
4471                                             {
4472                                               char expbuf[6 + 1];
4473                                               const char *ep;
4474                                               sprintf (expbuf, decimal_format, exponent);
4475                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4476                                                 p++;
4477                                             }
4478                                         }
4479 #   endif
4480                                       }
4481 
4482                                     free (digits);
4483                                   }
4484                               }
4485                             else
4486                               abort ();
4487 #  else
4488                             /* arg is finite.  */
4489                             if (!(arg == 0.0))
4490                               abort ();
4491 
4492                             pad_ptr = p;
4493 
4494                             if (dp->conversion == 'f' || dp->conversion == 'F')
4495                               {
4496                                 *p++ = '0';
4497                                 if ((flags & FLAG_ALT) || precision > 0)
4498                                   {
4499                                     *p++ = decimal_point_char ();
4500                                     for (; precision > 0; precision--)
4501                                       *p++ = '0';
4502                                   }
4503                               }
4504                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4505                               {
4506                                 *p++ = '0';
4507                                 if ((flags & FLAG_ALT) || precision > 0)
4508                                   {
4509                                     *p++ = decimal_point_char ();
4510                                     for (; precision > 0; precision--)
4511                                       *p++ = '0';
4512                                   }
4513                                 *p++ = dp->conversion; /* 'e' or 'E' */
4514                                 *p++ = '+';
4515                                 /* Produce the same number of exponent digits as
4516                                    the native printf implementation.  */
4517 #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4518                                 *p++ = '0';
4519 #   endif
4520                                 *p++ = '0';
4521                                 *p++ = '0';
4522                               }
4523                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4524                               {
4525                                 *p++ = '0';
4526                                 if (flags & FLAG_ALT)
4527                                   {
4528                                     size_t ndigits =
4529                                       (precision > 0 ? precision - 1 : 0);
4530                                     *p++ = decimal_point_char ();
4531                                     for (; ndigits > 0; --ndigits)
4532                                       *p++ = '0';
4533                                   }
4534                               }
4535                             else
4536                               abort ();
4537 #  endif
4538                           }
4539                       }
4540                   }
4541 # endif
4542 
4543                 /* The generated string now extends from tmp to p, with the
4544                    zero padding insertion point being at pad_ptr.  */
4545                 if (has_width && p - tmp < width)
4546                   {
4547                     size_t pad = width - (p - tmp);
4548                     DCHAR_T *end = p + pad;
4549 
4550                     if (flags & FLAG_LEFT)
4551                       {
4552                         /* Pad with spaces on the right.  */
4553                         for (; pad > 0; pad--)
4554                           *p++ = ' ';
4555                       }
4556                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4557                       {
4558                         /* Pad with zeroes.  */
4559                         DCHAR_T *q = end;
4560 
4561                         while (p > pad_ptr)
4562                           *--q = *--p;
4563                         for (; pad > 0; pad--)
4564                           *p++ = '0';
4565                       }
4566                     else
4567                       {
4568                         /* Pad with spaces on the left.  */
4569                         DCHAR_T *q = end;
4570 
4571                         while (p > tmp)
4572                           *--q = *--p;
4573                         for (; pad > 0; pad--)
4574                           *p++ = ' ';
4575                       }
4576 
4577                     p = end;
4578                   }
4579 
4580                 {
4581                   size_t count = p - tmp;
4582 
4583                   if (count >= tmp_length)
4584                     /* tmp_length was incorrectly calculated - fix the
4585                        code above!  */
4586                     abort ();
4587 
4588                   /* Make room for the result.  */
4589                   if (count >= allocated - length)
4590                     {
4591                       size_t n = xsum (length, count);
4592 
4593                       ENSURE_ALLOCATION (n);
4594                     }
4595 
4596                   /* Append the result.  */
4597                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4598                   if (tmp != tmpbuf)
4599                     free (tmp);
4600                   length += count;
4601                 }
4602               }
4603 #endif
4604             else
4605               {
4606                 arg_type type = a.arg[dp->arg_index].type;
4607                 int flags = dp->flags;
4608 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4609                 int has_width;
4610                 size_t width;
4611 #endif
4612 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4613                 int has_precision;
4614                 size_t precision;
4615 #endif
4616 #if NEED_PRINTF_UNBOUNDED_PRECISION
4617                 int prec_ourselves;
4618 #else
4619 #               define prec_ourselves 0
4620 #endif
4621 #if NEED_PRINTF_FLAG_LEFTADJUST
4622 #               define pad_ourselves 1
4623 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4624                 int pad_ourselves;
4625 #else
4626 #               define pad_ourselves 0
4627 #endif
4628                 TCHAR_T *fbp;
4629                 unsigned int prefix_count;
4630                 int prefixes[2] IF_LINT (= { 0 });
4631                 int orig_errno;
4632 #if !USE_SNPRINTF
4633                 size_t tmp_length;
4634                 TCHAR_T tmpbuf[700];
4635                 TCHAR_T *tmp;
4636 #endif
4637 
4638 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4639                 has_width = 0;
4640                 width = 0;
4641                 if (dp->width_start != dp->width_end)
4642                   {
4643                     if (dp->width_arg_index != ARG_NONE)
4644                       {
4645                         int arg;
4646 
4647                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4648                           abort ();
4649                         arg = a.arg[dp->width_arg_index].a.a_int;
4650                         if (arg < 0)
4651                           {
4652                             /* "A negative field width is taken as a '-' flag
4653                                 followed by a positive field width."  */
4654                             flags |= FLAG_LEFT;
4655                             width = (unsigned int) (-arg);
4656                           }
4657                         else
4658                           width = arg;
4659                       }
4660                     else
4661                       {
4662                         const FCHAR_T *digitp = dp->width_start;
4663 
4664                         do
4665                           width = xsum (xtimes (width, 10), *digitp++ - '0');
4666                         while (digitp != dp->width_end);
4667                       }
4668                     has_width = 1;
4669                   }
4670 #endif
4671 
4672 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4673                 has_precision = 0;
4674                 precision = 6;
4675                 if (dp->precision_start != dp->precision_end)
4676                   {
4677                     if (dp->precision_arg_index != ARG_NONE)
4678                       {
4679                         int arg;
4680 
4681                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4682                           abort ();
4683                         arg = a.arg[dp->precision_arg_index].a.a_int;
4684                         /* "A negative precision is taken as if the precision
4685                             were omitted."  */
4686                         if (arg >= 0)
4687                           {
4688                             precision = arg;
4689                             has_precision = 1;
4690                           }
4691                       }
4692                     else
4693                       {
4694                         const FCHAR_T *digitp = dp->precision_start + 1;
4695 
4696                         precision = 0;
4697                         while (digitp != dp->precision_end)
4698                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4699                         has_precision = 1;
4700                       }
4701                   }
4702 #endif
4703 
4704                 /* Decide whether to handle the precision ourselves.  */
4705 #if NEED_PRINTF_UNBOUNDED_PRECISION
4706                 switch (dp->conversion)
4707                   {
4708                   case 'd': case 'i': case 'u':
4709                   case 'o':
4710                   case 'x': case 'X': case 'p':
4711                     prec_ourselves = has_precision && (precision > 0);
4712                     break;
4713                   default:
4714                     prec_ourselves = 0;
4715                     break;
4716                   }
4717 #endif
4718 
4719                 /* Decide whether to perform the padding ourselves.  */
4720 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4721                 switch (dp->conversion)
4722                   {
4723 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4724                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4725                      to perform the padding after this conversion.  Functions
4726                      with unistdio extensions perform the padding based on
4727                      character count rather than element count.  */
4728                   case 'c': case 's':
4729 # endif
4730 # if NEED_PRINTF_FLAG_ZERO
4731                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4732                   case 'a': case 'A':
4733 # endif
4734                     pad_ourselves = 1;
4735                     break;
4736                   default:
4737                     pad_ourselves = prec_ourselves;
4738                     break;
4739                   }
4740 #endif
4741 
4742 #if !USE_SNPRINTF
4743                 /* Allocate a temporary buffer of sufficient size for calling
4744                    sprintf.  */
4745                 tmp_length =
4746                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4747                                    flags, width, has_precision, precision,
4748                                    pad_ourselves);
4749 
4750                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4751                   tmp = tmpbuf;
4752                 else
4753                   {
4754                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4755 
4756                     if (size_overflow_p (tmp_memsize))
4757                       /* Overflow, would lead to out of memory.  */
4758                       goto out_of_memory;
4759                     tmp = (TCHAR_T *) malloc (tmp_memsize);
4760                     if (tmp == NULL)
4761                       /* Out of memory.  */
4762                       goto out_of_memory;
4763                   }
4764 #endif
4765 
4766                 /* Construct the format string for calling snprintf or
4767                    sprintf.  */
4768                 fbp = buf;
4769                 *fbp++ = '%';
4770 #if NEED_PRINTF_FLAG_GROUPING
4771                 /* The underlying implementation doesn't support the ' flag.
4772                    Produce no grouping characters in this case; this is
4773                    acceptable because the grouping is locale dependent.  */
4774 #else
4775                 if (flags & FLAG_GROUP)
4776                   *fbp++ = '\'';
4777 #endif
4778                 if (flags & FLAG_LEFT)
4779                   *fbp++ = '-';
4780                 if (flags & FLAG_SHOWSIGN)
4781                   *fbp++ = '+';
4782                 if (flags & FLAG_SPACE)
4783                   *fbp++ = ' ';
4784                 if (flags & FLAG_ALT)
4785                   *fbp++ = '#';
4786 #if __GLIBC__ >= 2 && !defined __UCLIBC__
4787                 if (flags & FLAG_LOCALIZED)
4788                   *fbp++ = 'I';
4789 #endif
4790                 if (!pad_ourselves)
4791                   {
4792                     if (flags & FLAG_ZERO)
4793                       *fbp++ = '0';
4794                     if (dp->width_start != dp->width_end)
4795                       {
4796                         size_t n = dp->width_end - dp->width_start;
4797                         /* The width specification is known to consist only
4798                            of standard ASCII characters.  */
4799                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4800                           {
4801                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4802                             fbp += n;
4803                           }
4804                         else
4805                           {
4806                             const FCHAR_T *mp = dp->width_start;
4807                             do
4808                               *fbp++ = (unsigned char) *mp++;
4809                             while (--n > 0);
4810                           }
4811                       }
4812                   }
4813                 if (!prec_ourselves)
4814                   {
4815                     if (dp->precision_start != dp->precision_end)
4816                       {
4817                         size_t n = dp->precision_end - dp->precision_start;
4818                         /* The precision specification is known to consist only
4819                            of standard ASCII characters.  */
4820                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4821                           {
4822                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4823                             fbp += n;
4824                           }
4825                         else
4826                           {
4827                             const FCHAR_T *mp = dp->precision_start;
4828                             do
4829                               *fbp++ = (unsigned char) *mp++;
4830                             while (--n > 0);
4831                           }
4832                       }
4833                   }
4834 
4835                 switch (type)
4836                   {
4837 #if HAVE_LONG_LONG_INT
4838                   case TYPE_LONGLONGINT:
4839                   case TYPE_ULONGLONGINT:
4840 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4841                     *fbp++ = 'I';
4842                     *fbp++ = '6';
4843                     *fbp++ = '4';
4844                     break;
4845 # else
4846                     *fbp++ = 'l';
4847                     /*FALLTHROUGH*/
4848 # endif
4849 #endif
4850                   case TYPE_LONGINT:
4851                   case TYPE_ULONGINT:
4852 #if HAVE_WINT_T
4853                   case TYPE_WIDE_CHAR:
4854 #endif
4855 #if HAVE_WCHAR_T
4856                   case TYPE_WIDE_STRING:
4857 #endif
4858                     *fbp++ = 'l';
4859                     break;
4860                   case TYPE_LONGDOUBLE:
4861                     *fbp++ = 'L';
4862                     break;
4863                   default:
4864                     break;
4865                   }
4866 #if NEED_PRINTF_DIRECTIVE_F
4867                 if (dp->conversion == 'F')
4868                   *fbp = 'f';
4869                 else
4870 #endif
4871                   *fbp = dp->conversion;
4872 #if USE_SNPRINTF
4873 # if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4874                 fbp[1] = '%';
4875                 fbp[2] = 'n';
4876                 fbp[3] = '\0';
4877 # else
4878                 /* On glibc2 systems from glibc >= 2.3 - probably also older
4879                    ones - we know that snprintf's return value conforms to
4880                    ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
4881                    gl_SNPRINTF_TRUNCATION_C99 pass.
4882                    Therefore we can avoid using %n in this situation.
4883                    On glibc2 systems from 2004-10-18 or newer, the use of %n
4884                    in format strings in writable memory may crash the program
4885                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4886                    in this situation.  */
4887                 /* On native Windows systems (such as mingw), we can avoid using
4888                    %n because:
4889                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4890                        snprintf does not write more than the specified number
4891                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4892                        '4', '5', '6' into buf, not '4', '5', '\0'.)
4893                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4894                        allows us to recognize the case of an insufficient
4895                        buffer size: it returns -1 in this case.
4896                    On native Windows systems (such as mingw) where the OS is
4897                    Windows Vista, the use of %n in format strings by default
4898                    crashes the program. See
4899                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4900                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4901                    So we should avoid %n in this situation.  */
4902                 fbp[1] = '\0';
4903 # endif
4904 #else
4905                 fbp[1] = '\0';
4906 #endif
4907 
4908                 /* Construct the arguments for calling snprintf or sprintf.  */
4909                 prefix_count = 0;
4910                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4911                   {
4912                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4913                       abort ();
4914                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4915                   }
4916                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4917                   {
4918                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4919                       abort ();
4920                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4921                   }
4922 
4923 #if USE_SNPRINTF
4924                 /* The SNPRINTF result is appended after result[0..length].
4925                    The latter is an array of DCHAR_T; SNPRINTF appends an
4926                    array of TCHAR_T to it.  This is possible because
4927                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4928                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
4929 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4930                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
4931                    where an snprintf() with maxlen==1 acts like sprintf().  */
4932                 ENSURE_ALLOCATION (xsum (length,
4933                                          (2 + TCHARS_PER_DCHAR - 1)
4934                                          / TCHARS_PER_DCHAR));
4935                 /* Prepare checking whether snprintf returns the count
4936                    via %n.  */
4937                 *(TCHAR_T *) (result + length) = '\0';
4938 #endif
4939 
4940                 orig_errno = errno;
4941 
4942                 for (;;)
4943                   {
4944                     int count = -1;
4945 
4946 #if USE_SNPRINTF
4947                     int retcount = 0;
4948                     size_t maxlen = allocated - length;
4949                     /* SNPRINTF can fail if its second argument is
4950                        > INT_MAX.  */
4951                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4952                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
4953                     maxlen = maxlen * TCHARS_PER_DCHAR;
4954 # define SNPRINTF_BUF(arg) \
4955                     switch (prefix_count)                                   \
4956                       {                                                     \
4957                       case 0:                                               \
4958                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4959                                              maxlen, buf,                   \
4960                                              arg, &count);                  \
4961                         break;                                              \
4962                       case 1:                                               \
4963                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4964                                              maxlen, buf,                   \
4965                                              prefixes[0], arg, &count);     \
4966                         break;                                              \
4967                       case 2:                                               \
4968                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4969                                              maxlen, buf,                   \
4970                                              prefixes[0], prefixes[1], arg, \
4971                                              &count);                       \
4972                         break;                                              \
4973                       default:                                              \
4974                         abort ();                                           \
4975                       }
4976 #else
4977 # define SNPRINTF_BUF(arg) \
4978                     switch (prefix_count)                                   \
4979                       {                                                     \
4980                       case 0:                                               \
4981                         count = sprintf (tmp, buf, arg);                    \
4982                         break;                                              \
4983                       case 1:                                               \
4984                         count = sprintf (tmp, buf, prefixes[0], arg);       \
4985                         break;                                              \
4986                       case 2:                                               \
4987                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4988                                          arg);                              \
4989                         break;                                              \
4990                       default:                                              \
4991                         abort ();                                           \
4992                       }
4993 #endif
4994 
4995                     errno = 0;
4996                     switch (type)
4997                       {
4998                       case TYPE_SCHAR:
4999                         {
5000                           int arg = a.arg[dp->arg_index].a.a_schar;
5001                           SNPRINTF_BUF (arg);
5002                         }
5003                         break;
5004                       case TYPE_UCHAR:
5005                         {
5006                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
5007                           SNPRINTF_BUF (arg);
5008                         }
5009                         break;
5010                       case TYPE_SHORT:
5011                         {
5012                           int arg = a.arg[dp->arg_index].a.a_short;
5013                           SNPRINTF_BUF (arg);
5014                         }
5015                         break;
5016                       case TYPE_USHORT:
5017                         {
5018                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
5019                           SNPRINTF_BUF (arg);
5020                         }
5021                         break;
5022                       case TYPE_INT:
5023                         {
5024                           int arg = a.arg[dp->arg_index].a.a_int;
5025                           SNPRINTF_BUF (arg);
5026                         }
5027                         break;
5028                       case TYPE_UINT:
5029                         {
5030                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5031                           SNPRINTF_BUF (arg);
5032                         }
5033                         break;
5034                       case TYPE_LONGINT:
5035                         {
5036                           long int arg = a.arg[dp->arg_index].a.a_longint;
5037                           SNPRINTF_BUF (arg);
5038                         }
5039                         break;
5040                       case TYPE_ULONGINT:
5041                         {
5042                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5043                           SNPRINTF_BUF (arg);
5044                         }
5045                         break;
5046 #if HAVE_LONG_LONG_INT
5047                       case TYPE_LONGLONGINT:
5048                         {
5049                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5050                           SNPRINTF_BUF (arg);
5051                         }
5052                         break;
5053                       case TYPE_ULONGLONGINT:
5054                         {
5055                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5056                           SNPRINTF_BUF (arg);
5057                         }
5058                         break;
5059 #endif
5060                       case TYPE_DOUBLE:
5061                         {
5062                           double arg = a.arg[dp->arg_index].a.a_double;
5063                           SNPRINTF_BUF (arg);
5064                         }
5065                         break;
5066                       case TYPE_LONGDOUBLE:
5067                         {
5068                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
5069                           SNPRINTF_BUF (arg);
5070                         }
5071                         break;
5072                       case TYPE_CHAR:
5073                         {
5074                           int arg = a.arg[dp->arg_index].a.a_char;
5075                           SNPRINTF_BUF (arg);
5076                         }
5077                         break;
5078 #if HAVE_WINT_T
5079                       case TYPE_WIDE_CHAR:
5080                         {
5081                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5082                           SNPRINTF_BUF (arg);
5083                         }
5084                         break;
5085 #endif
5086                       case TYPE_STRING:
5087                         {
5088                           const char *arg = a.arg[dp->arg_index].a.a_string;
5089                           SNPRINTF_BUF (arg);
5090                         }
5091                         break;
5092 #if HAVE_WCHAR_T
5093                       case TYPE_WIDE_STRING:
5094                         {
5095                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5096                           SNPRINTF_BUF (arg);
5097                         }
5098                         break;
5099 #endif
5100                       case TYPE_POINTER:
5101                         {
5102                           void *arg = a.arg[dp->arg_index].a.a_pointer;
5103                           SNPRINTF_BUF (arg);
5104                         }
5105                         break;
5106                       default:
5107                         abort ();
5108                       }
5109 
5110 #if USE_SNPRINTF
5111                     /* Portability: Not all implementations of snprintf()
5112                        are ISO C 99 compliant.  Determine the number of
5113                        bytes that snprintf() has produced or would have
5114                        produced.  */
5115                     if (count >= 0)
5116                       {
5117                         /* Verify that snprintf() has NUL-terminated its
5118                            result.  */
5119                         if (count < maxlen
5120                             && ((TCHAR_T *) (result + length)) [count] != '\0')
5121                           abort ();
5122                         /* Portability hack.  */
5123                         if (retcount > count)
5124                           count = retcount;
5125                       }
5126                     else
5127                       {
5128                         /* snprintf() doesn't understand the '%n'
5129                            directive.  */
5130                         if (fbp[1] != '\0')
5131                           {
5132                             /* Don't use the '%n' directive; instead, look
5133                                at the snprintf() return value.  */
5134                             fbp[1] = '\0';
5135                             continue;
5136                           }
5137                         else
5138                           {
5139                             /* Look at the snprintf() return value.  */
5140                             if (retcount < 0)
5141                               {
5142 # if !HAVE_SNPRINTF_RETVAL_C99
5143                                 /* HP-UX 10.20 snprintf() is doubly deficient:
5144                                    It doesn't understand the '%n' directive,
5145                                    *and* it returns -1 (rather than the length
5146                                    that would have been required) when the
5147                                    buffer is too small.
5148                                    But a failure at this point can also come
5149                                    from other reasons than a too small buffer,
5150                                    such as an invalid wide string argument to
5151                                    the %ls directive, or possibly an invalid
5152                                    floating-point argument.  */
5153                                 size_t tmp_length =
5154                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
5155                                                    dp->conversion, type, flags,
5156                                                    width, has_precision,
5157                                                    precision, pad_ourselves);
5158 
5159                                 if (maxlen < tmp_length)
5160                                   {
5161                                     /* Make more room.  But try to do through
5162                                        this reallocation only once.  */
5163                                     size_t bigger_need =
5164                                       xsum (length,
5165                                             xsum (tmp_length,
5166                                                   TCHARS_PER_DCHAR - 1)
5167                                             / TCHARS_PER_DCHAR);
5168                                     /* And always grow proportionally.
5169                                        (There may be several arguments, each
5170                                        needing a little more room than the
5171                                        previous one.)  */
5172                                     size_t bigger_need2 =
5173                                       xsum (xtimes (allocated, 2), 12);
5174                                     if (bigger_need < bigger_need2)
5175                                       bigger_need = bigger_need2;
5176                                     ENSURE_ALLOCATION (bigger_need);
5177                                     continue;
5178                                   }
5179 # endif
5180                               }
5181                             else
5182                               count = retcount;
5183                           }
5184                       }
5185 #endif
5186 
5187                     /* Attempt to handle failure.  */
5188                     if (count < 0)
5189                       {
5190                         /* SNPRINTF or sprintf failed.  Save and use the errno
5191                            that it has set, if any.  */
5192                         int saved_errno = errno;
5193 
5194                         if (!(result == resultbuf || result == NULL))
5195                           free (result);
5196                         if (buf_malloced != NULL)
5197                           free (buf_malloced);
5198                         CLEANUP ();
5199                         errno =
5200                           (saved_errno != 0
5201                            ? saved_errno
5202                            : (dp->conversion == 'c' || dp->conversion == 's'
5203                               ? EILSEQ
5204                               : EINVAL));
5205                         return NULL;
5206                       }
5207 
5208 #if USE_SNPRINTF
5209                     /* Handle overflow of the allocated buffer.
5210                        If such an overflow occurs, a C99 compliant snprintf()
5211                        returns a count >= maxlen.  However, a non-compliant
5212                        snprintf() function returns only count = maxlen - 1.  To
5213                        cover both cases, test whether count >= maxlen - 1.  */
5214                     if ((unsigned int) count + 1 >= maxlen)
5215                       {
5216                         /* If maxlen already has attained its allowed maximum,
5217                            allocating more memory will not increase maxlen.
5218                            Instead of looping, bail out.  */
5219                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5220                           goto overflow;
5221                         else
5222                           {
5223                             /* Need at least (count + 1) * sizeof (TCHAR_T)
5224                                bytes.  (The +1 is for the trailing NUL.)
5225                                But ask for (count + 2) * sizeof (TCHAR_T)
5226                                bytes, so that in the next round, we likely get
5227                                  maxlen > (unsigned int) count + 1
5228                                and so we don't get here again.
5229                                And allocate proportionally, to avoid looping
5230                                eternally if snprintf() reports a too small
5231                                count.  */
5232                             size_t n =
5233                               xmax (xsum (length,
5234                                           ((unsigned int) count + 2
5235                                            + TCHARS_PER_DCHAR - 1)
5236                                           / TCHARS_PER_DCHAR),
5237                                     xtimes (allocated, 2));
5238 
5239                             ENSURE_ALLOCATION (n);
5240                             continue;
5241                           }
5242                       }
5243 #endif
5244 
5245 #if NEED_PRINTF_UNBOUNDED_PRECISION
5246                     if (prec_ourselves)
5247                       {
5248                         /* Handle the precision.  */
5249                         TCHAR_T *prec_ptr =
5250 # if USE_SNPRINTF
5251                           (TCHAR_T *) (result + length);
5252 # else
5253                           tmp;
5254 # endif
5255                         size_t prefix_count;
5256                         size_t move;
5257 
5258                         prefix_count = 0;
5259                         /* Put the additional zeroes after the sign.  */
5260                         if (count >= 1
5261                             && (*prec_ptr == '-' || *prec_ptr == '+'
5262                                 || *prec_ptr == ' '))
5263                           prefix_count = 1;
5264                         /* Put the additional zeroes after the 0x prefix if
5265                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
5266                         else if (count >= 2
5267                                  && prec_ptr[0] == '0'
5268                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5269                           prefix_count = 2;
5270 
5271                         move = count - prefix_count;
5272                         if (precision > move)
5273                           {
5274                             /* Insert zeroes.  */
5275                             size_t insert = precision - move;
5276                             TCHAR_T *prec_end;
5277 
5278 # if USE_SNPRINTF
5279                             size_t n =
5280                               xsum (length,
5281                                     (count + insert + TCHARS_PER_DCHAR - 1)
5282                                     / TCHARS_PER_DCHAR);
5283                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5284                             ENSURE_ALLOCATION (n);
5285                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5286                             prec_ptr = (TCHAR_T *) (result + length);
5287 # endif
5288 
5289                             prec_end = prec_ptr + count;
5290                             prec_ptr += prefix_count;
5291 
5292                             while (prec_end > prec_ptr)
5293                               {
5294                                 prec_end--;
5295                                 prec_end[insert] = prec_end[0];
5296                               }
5297 
5298                             prec_end += insert;
5299                             do
5300                               *--prec_end = '0';
5301                             while (prec_end > prec_ptr);
5302 
5303                             count += insert;
5304                           }
5305                       }
5306 #endif
5307 
5308 #if !USE_SNPRINTF
5309                     if (count >= tmp_length)
5310                       /* tmp_length was incorrectly calculated - fix the
5311                          code above!  */
5312                       abort ();
5313 #endif
5314 
5315 #if !DCHAR_IS_TCHAR
5316                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
5317                     if (dp->conversion == 'c' || dp->conversion == 's')
5318                       {
5319                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5320                            TYPE_WIDE_STRING.
5321                            The result string is not certainly ASCII.  */
5322                         const TCHAR_T *tmpsrc;
5323                         DCHAR_T *tmpdst;
5324                         size_t tmpdst_len;
5325                         /* This code assumes that TCHAR_T is 'char'.  */
5326                         verify (sizeof (TCHAR_T) == 1);
5327 # if USE_SNPRINTF
5328                         tmpsrc = (TCHAR_T *) (result + length);
5329 # else
5330                         tmpsrc = tmp;
5331 # endif
5332                         tmpdst =
5333                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
5334                                                     iconveh_question_mark,
5335                                                     tmpsrc, count,
5336                                                     NULL,
5337                                                     NULL, &tmpdst_len);
5338                         if (tmpdst == NULL)
5339                           {
5340                             int saved_errno = errno;
5341                             if (!(result == resultbuf || result == NULL))
5342                               free (result);
5343                             if (buf_malloced != NULL)
5344                               free (buf_malloced);
5345                             CLEANUP ();
5346                             errno = saved_errno;
5347                             return NULL;
5348                           }
5349                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5350                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5351                         free (tmpdst);
5352                         count = tmpdst_len;
5353                       }
5354                     else
5355                       {
5356                         /* The result string is ASCII.
5357                            Simple 1:1 conversion.  */
5358 # if USE_SNPRINTF
5359                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5360                            no-op conversion, in-place on the array starting
5361                            at (result + length).  */
5362                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5363 # endif
5364                           {
5365                             const TCHAR_T *tmpsrc;
5366                             DCHAR_T *tmpdst;
5367                             size_t n;
5368 
5369 # if USE_SNPRINTF
5370                             if (result == resultbuf)
5371                               {
5372                                 tmpsrc = (TCHAR_T *) (result + length);
5373                                 /* ENSURE_ALLOCATION will not move tmpsrc
5374                                    (because it's part of resultbuf).  */
5375                                 ENSURE_ALLOCATION (xsum (length, count));
5376                               }
5377                             else
5378                               {
5379                                 /* ENSURE_ALLOCATION will move the array
5380                                    (because it uses realloc().  */
5381                                 ENSURE_ALLOCATION (xsum (length, count));
5382                                 tmpsrc = (TCHAR_T *) (result + length);
5383                               }
5384 # else
5385                             tmpsrc = tmp;
5386                             ENSURE_ALLOCATION (xsum (length, count));
5387 # endif
5388                             tmpdst = result + length;
5389                             /* Copy backwards, because of overlapping.  */
5390                             tmpsrc += count;
5391                             tmpdst += count;
5392                             for (n = count; n > 0; n--)
5393                               *--tmpdst = (unsigned char) *--tmpsrc;
5394                           }
5395                       }
5396 #endif
5397 
5398 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5399                     /* Make room for the result.  */
5400                     if (count > allocated - length)
5401                       {
5402                         /* Need at least count elements.  But allocate
5403                            proportionally.  */
5404                         size_t n =
5405                           xmax (xsum (length, count), xtimes (allocated, 2));
5406 
5407                         ENSURE_ALLOCATION (n);
5408                       }
5409 #endif
5410 
5411                     /* Here count <= allocated - length.  */
5412 
5413                     /* Perform padding.  */
5414 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5415                     if (pad_ourselves && has_width)
5416                       {
5417                         size_t w;
5418 # if ENABLE_UNISTDIO
5419                         /* Outside POSIX, it's preferable to compare the width
5420                            against the number of _characters_ of the converted
5421                            value.  */
5422                         w = DCHAR_MBSNLEN (result + length, count);
5423 # else
5424                         /* The width is compared against the number of _bytes_
5425                            of the converted value, says POSIX.  */
5426                         w = count;
5427 # endif
5428                         if (w < width)
5429                           {
5430                             size_t pad = width - w;
5431 
5432                             /* Make room for the result.  */
5433                             if (xsum (count, pad) > allocated - length)
5434                               {
5435                                 /* Need at least count + pad elements.  But
5436                                    allocate proportionally.  */
5437                                 size_t n =
5438                                   xmax (xsum3 (length, count, pad),
5439                                         xtimes (allocated, 2));
5440 
5441 # if USE_SNPRINTF
5442                                 length += count;
5443                                 ENSURE_ALLOCATION (n);
5444                                 length -= count;
5445 # else
5446                                 ENSURE_ALLOCATION (n);
5447 # endif
5448                               }
5449                             /* Here count + pad <= allocated - length.  */
5450 
5451                             {
5452 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5453                               DCHAR_T * const rp = result + length;
5454 # else
5455                               DCHAR_T * const rp = tmp;
5456 # endif
5457                               DCHAR_T *p = rp + count;
5458                               DCHAR_T *end = p + pad;
5459                               DCHAR_T *pad_ptr;
5460 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5461                               if (dp->conversion == 'c'
5462                                   || dp->conversion == 's')
5463                                 /* No zero-padding for string directives.  */
5464                                 pad_ptr = NULL;
5465                               else
5466 # endif
5467                                 {
5468                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
5469                                   /* No zero-padding of "inf" and "nan".  */
5470                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5471                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5472                                     pad_ptr = NULL;
5473                                 }
5474                               /* The generated string now extends from rp to p,
5475                                  with the zero padding insertion point being at
5476                                  pad_ptr.  */
5477 
5478                               count = count + pad; /* = end - rp */
5479 
5480                               if (flags & FLAG_LEFT)
5481                                 {
5482                                   /* Pad with spaces on the right.  */
5483                                   for (; pad > 0; pad--)
5484                                     *p++ = ' ';
5485                                 }
5486                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5487                                 {
5488                                   /* Pad with zeroes.  */
5489                                   DCHAR_T *q = end;
5490 
5491                                   while (p > pad_ptr)
5492                                     *--q = *--p;
5493                                   for (; pad > 0; pad--)
5494                                     *p++ = '0';
5495                                 }
5496                               else
5497                                 {
5498                                   /* Pad with spaces on the left.  */
5499                                   DCHAR_T *q = end;
5500 
5501                                   while (p > rp)
5502                                     *--q = *--p;
5503                                   for (; pad > 0; pad--)
5504                                     *p++ = ' ';
5505                                 }
5506                             }
5507                           }
5508                       }
5509 #endif
5510 
5511                     /* Here still count <= allocated - length.  */
5512 
5513 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5514                     /* The snprintf() result did fit.  */
5515 #else
5516                     /* Append the sprintf() result.  */
5517                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5518 #endif
5519 #if !USE_SNPRINTF
5520                     if (tmp != tmpbuf)
5521                       free (tmp);
5522 #endif
5523 
5524 #if NEED_PRINTF_DIRECTIVE_F
5525                     if (dp->conversion == 'F')
5526                       {
5527                         /* Convert the %f result to upper case for %F.  */
5528                         DCHAR_T *rp = result + length;
5529                         size_t rc;
5530                         for (rc = count; rc > 0; rc--, rp++)
5531                           if (*rp >= 'a' && *rp <= 'z')
5532                             *rp = *rp - 'a' + 'A';
5533                       }
5534 #endif
5535 
5536                     length += count;
5537                     break;
5538                   }
5539                 errno = orig_errno;
5540 #undef pad_ourselves
5541 #undef prec_ourselves
5542               }
5543           }
5544       }
5545 
5546     /* Add the final NUL.  */
5547     ENSURE_ALLOCATION (xsum (length, 1));
5548     result[length] = '\0';
5549 
5550     if (result != resultbuf && length + 1 < allocated)
5551       {
5552         /* Shrink the allocated memory if possible.  */
5553         DCHAR_T *memory;
5554 
5555         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5556         if (memory != NULL)
5557           result = memory;
5558       }
5559 
5560     if (buf_malloced != NULL)
5561       free (buf_malloced);
5562     CLEANUP ();
5563     *lengthp = length;
5564     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
5565        says that snprintf() fails with errno = EOVERFLOW in this case, but
5566        that's only because snprintf() returns an 'int'.  This function does
5567        not have this limitation.  */
5568     return result;
5569 
5570 #if USE_SNPRINTF
5571   overflow:
5572     if (!(result == resultbuf || result == NULL))
5573       free (result);
5574     if (buf_malloced != NULL)
5575       free (buf_malloced);
5576     CLEANUP ();
5577     errno = EOVERFLOW;
5578     return NULL;
5579 #endif
5580 
5581   out_of_memory:
5582     if (!(result == resultbuf || result == NULL))
5583       free (result);
5584     if (buf_malloced != NULL)
5585       free (buf_malloced);
5586   out_of_memory_1:
5587     CLEANUP ();
5588     errno = ENOMEM;
5589     return NULL;
5590   }
5591 }
5592 
5593 #undef MAX_ROOM_NEEDED
5594 #undef TCHARS_PER_DCHAR
5595 #undef SNPRINTF
5596 #undef USE_SNPRINTF
5597 #undef DCHAR_SET
5598 #undef DCHAR_CPY
5599 #undef PRINTF_PARSE
5600 #undef DIRECTIVES
5601 #undef DIRECTIVE
5602 #undef DCHAR_IS_TCHAR
5603 #undef TCHAR_T
5604 #undef DCHAR_T
5605 #undef FCHAR_T
5606 #undef VASNPRINTF
5607