Back to index

courier  0.68.2
vasnprintf.c
Go to the documentation of this file.
00001 /* vsprintf with automatic memory allocation.
00002    Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc.
00003 
00004    This program is free software; you can redistribute it and/or modify it
00005    under the terms of the GNU Library General Public License as published
00006    by the Free Software Foundation; either version 2, or (at your option)
00007    any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public
00015    License along with this program; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00017    USA.  */
00018 
00019 /* This file can be parametrized with the following macros:
00020      VASNPRINTF         The name of the function being defined.
00021      FCHAR_T            The element type of the format string.
00022      DCHAR_T            The element type of the destination (result) string.
00023      FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
00024                         in the format string are ASCII. MUST be set if
00025                         FCHAR_T and DCHAR_T are not the same type.
00026      DIRECTIVE          Structure denoting a format directive.
00027                         Depends on FCHAR_T.
00028      DIRECTIVES         Structure denoting the set of format directives of a
00029                         format string.  Depends on FCHAR_T.
00030      PRINTF_PARSE       Function that parses a format string.
00031                         Depends on FCHAR_T.
00032      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
00033      DCHAR_SET          memset like function for DCHAR_T[] arrays.
00034      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
00035      SNPRINTF           The system's snprintf (or similar) function.
00036                         This may be either snprintf or swprintf.
00037      TCHAR_T            The element type of the argument and result string
00038                         of the said SNPRINTF function.  This may be either
00039                         char or wchar_t.  The code exploits that
00040                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
00041                         alignof (TCHAR_T) <= alignof (DCHAR_T).
00042      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
00043      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
00044      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
00045      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
00046      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.  */
00047 
00048 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
00049    This must come before <config.h> because <config.h> may include
00050    <features.h>, and once <features.h> has been included, it's too late.  */
00051 #ifndef _GNU_SOURCE
00052 # define _GNU_SOURCE    1
00053 #endif
00054 
00055 #ifndef VASNPRINTF
00056 # include <config.h>
00057 #endif
00058 #ifndef IN_LIBINTL
00059 # include <alloca.h>
00060 #endif
00061 
00062 /* Specification.  */
00063 #ifndef VASNPRINTF
00064 # if WIDE_CHAR_VERSION
00065 #  include "vasnwprintf.h"
00066 # else
00067 #  include "vasnprintf.h"
00068 # endif
00069 #endif
00070 
00071 #include <locale.h>     /* localeconv() */
00072 #include <stdio.h>      /* snprintf(), sprintf() */
00073 #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
00074 #include <string.h>     /* memcpy(), strlen() */
00075 #include <errno.h>      /* errno */
00076 #include <limits.h>     /* CHAR_BIT */
00077 #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
00078 #if HAVE_NL_LANGINFO
00079 # include <langinfo.h>
00080 #endif
00081 #ifndef VASNPRINTF
00082 # if WIDE_CHAR_VERSION
00083 #  include "wprintf-parse.h"
00084 # else
00085 #  include "printf-parse.h"
00086 # endif
00087 #endif
00088 
00089 /* Checked size_t computations.  */
00090 #include "xsize.h"
00091 
00092 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
00093 # include <math.h>
00094 # include "float+.h"
00095 #endif
00096 
00097 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
00098 # include <math.h>
00099 # include "isnand-nolibm.h"
00100 #endif
00101 
00102 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
00103 # include <math.h>
00104 # include "isnanl-nolibm.h"
00105 # include "fpucw.h"
00106 #endif
00107 
00108 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
00109 # include <math.h>
00110 # include "isnand-nolibm.h"
00111 # include "printf-frexp.h"
00112 #endif
00113 
00114 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
00115 # include <math.h>
00116 # include "isnanl-nolibm.h"
00117 # include "printf-frexpl.h"
00118 # include "fpucw.h"
00119 #endif
00120 
00121 /* Default parameters.  */
00122 #ifndef VASNPRINTF
00123 # if WIDE_CHAR_VERSION
00124 #  define VASNPRINTF vasnwprintf
00125 #  define FCHAR_T wchar_t
00126 #  define DCHAR_T wchar_t
00127 #  define TCHAR_T wchar_t
00128 #  define DCHAR_IS_TCHAR 1
00129 #  define DIRECTIVE wchar_t_directive
00130 #  define DIRECTIVES wchar_t_directives
00131 #  define PRINTF_PARSE wprintf_parse
00132 #  define DCHAR_CPY wmemcpy
00133 #  define DCHAR_SET wmemset
00134 # else
00135 #  define VASNPRINTF vasnprintf
00136 #  define FCHAR_T char
00137 #  define DCHAR_T char
00138 #  define TCHAR_T char
00139 #  define DCHAR_IS_TCHAR 1
00140 #  define DIRECTIVE char_directive
00141 #  define DIRECTIVES char_directives
00142 #  define PRINTF_PARSE printf_parse
00143 #  define DCHAR_CPY memcpy
00144 #  define DCHAR_SET memset
00145 # endif
00146 #endif
00147 #if WIDE_CHAR_VERSION
00148   /* TCHAR_T is wchar_t.  */
00149 # define USE_SNPRINTF 1
00150 # if HAVE_DECL__SNWPRINTF
00151    /* On Windows, the function swprintf() has a different signature than
00152       on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
00153       instead.  The mingw function snwprintf() has fewer bugs than the
00154       MSVCRT function _snwprintf(), so prefer that.  */
00155 #  if defined __MINGW32__
00156 #   define SNPRINTF snwprintf
00157 #  else
00158 #   define SNPRINTF _snwprintf
00159 #  endif
00160 # else
00161    /* Unix.  */
00162 #  define SNPRINTF swprintf
00163 # endif
00164 #else
00165   /* TCHAR_T is char.  */
00166   /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
00167      But don't use it on BeOS, since BeOS snprintf produces no output if the
00168      size argument is >= 0x3000000.
00169      Also don't use it on Linux libc5, since there snprintf with size = 1
00170      writes any output without bounds, like sprintf.  */
00171 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
00172 #  define USE_SNPRINTF 1
00173 # else
00174 #  define USE_SNPRINTF 0
00175 # endif
00176 # if HAVE_DECL__SNPRINTF
00177    /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
00178       function _snprintf(), so prefer that.  */
00179 #  if defined __MINGW32__
00180 #   define SNPRINTF snprintf
00181     /* Here we need to call the native snprintf, not rpl_snprintf.  */
00182 #   undef snprintf
00183 #  else
00184 #   define SNPRINTF _snprintf
00185 #  endif
00186 # else
00187    /* Unix.  */
00188 #  define SNPRINTF snprintf
00189    /* Here we need to call the native snprintf, not rpl_snprintf.  */
00190 #  undef snprintf
00191 # endif
00192 #endif
00193 /* Here we need to call the native sprintf, not rpl_sprintf.  */
00194 #undef sprintf
00195 
00196 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
00197    warnings in this file.  Use -Dlint to suppress them.  */
00198 #ifdef lint
00199 # define IF_LINT(Code) Code
00200 #else
00201 # define IF_LINT(Code) /* empty */
00202 #endif
00203 
00204 /* Avoid some warnings from "gcc -Wshadow".
00205    This file doesn't use the exp() and remainder() functions.  */
00206 #undef exp
00207 #define exp expo
00208 #undef remainder
00209 #define remainder rem
00210 
00211 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
00212 # if (HAVE_STRNLEN && !defined _AIX)
00213 #  define local_strnlen strnlen
00214 # else
00215 #  ifndef local_strnlen_defined
00216 #   define local_strnlen_defined 1
00217 static size_t
00218 local_strnlen (const char *string, size_t maxlen)
00219 {
00220   const char *end = memchr (string, '\0', maxlen);
00221   return end ? (size_t) (end - string) : maxlen;
00222 }
00223 #  endif
00224 # endif
00225 #endif
00226 
00227 #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
00228 # if HAVE_WCSLEN
00229 #  define local_wcslen wcslen
00230 # else
00231    /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
00232       a dependency towards this library, here is a local substitute.
00233       Define this substitute only once, even if this file is included
00234       twice in the same compilation unit.  */
00235 #  ifndef local_wcslen_defined
00236 #   define local_wcslen_defined 1
00237 static size_t
00238 local_wcslen (const wchar_t *s)
00239 {
00240   const wchar_t *ptr;
00241 
00242   for (ptr = s; *ptr != (wchar_t) 0; ptr++)
00243     ;
00244   return ptr - s;
00245 }
00246 #  endif
00247 # endif
00248 #endif
00249 
00250 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
00251 # if HAVE_WCSNLEN
00252 #  define local_wcsnlen wcsnlen
00253 # else
00254 #  ifndef local_wcsnlen_defined
00255 #   define local_wcsnlen_defined 1
00256 static size_t
00257 local_wcsnlen (const wchar_t *s, size_t maxlen)
00258 {
00259   const wchar_t *ptr;
00260 
00261   for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
00262     ;
00263   return ptr - s;
00264 }
00265 #  endif
00266 # endif
00267 #endif
00268 
00269 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
00270 /* Determine the decimal-point character according to the current locale.  */
00271 # ifndef decimal_point_char_defined
00272 #  define decimal_point_char_defined 1
00273 static char
00274 decimal_point_char (void)
00275 {
00276   const char *point;
00277   /* Determine it in a multithread-safe way.  We know nl_langinfo is
00278      multithread-safe on glibc systems and MacOS X systems, but is not required
00279      to be multithread-safe by POSIX.  sprintf(), however, is multithread-safe.
00280      localeconv() is rarely multithread-safe.  */
00281 #  if HAVE_NL_LANGINFO && (__GLIBC__ || (defined __APPLE__ && defined __MACH__))
00282   point = nl_langinfo (RADIXCHAR);
00283 #  elif 1
00284   char pointbuf[5];
00285   sprintf (pointbuf, "%#.0f", 1.0);
00286   point = &pointbuf[1];
00287 #  else
00288   point = localeconv () -> decimal_point;
00289 #  endif
00290   /* The decimal point is always a single byte: either '.' or ','.  */
00291   return (point[0] != '\0' ? point[0] : '.');
00292 }
00293 # endif
00294 #endif
00295 
00296 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
00297 
00298 /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
00299 static int
00300 is_infinite_or_zero (double x)
00301 {
00302   return isnand (x) || x + x == x;
00303 }
00304 
00305 #endif
00306 
00307 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
00308 
00309 /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
00310 static int
00311 is_infinite_or_zerol (long double x)
00312 {
00313   return isnanl (x) || x + x == x;
00314 }
00315 
00316 #endif
00317 
00318 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
00319 
00320 /* Converting 'long double' to decimal without rare rounding bugs requires
00321    real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
00322    (and slower) algorithms.  */
00323 
00324 typedef unsigned int mp_limb_t;
00325 # define GMP_LIMB_BITS 32
00326 typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1];
00327 
00328 typedef unsigned long long mp_twolimb_t;
00329 # define GMP_TWOLIMB_BITS 64
00330 typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1];
00331 
00332 /* Representation of a bignum >= 0.  */
00333 typedef struct
00334 {
00335   size_t nlimbs;
00336   mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  */
00337 } mpn_t;
00338 
00339 /* Compute the product of two bignums >= 0.
00340    Return the allocated memory in case of success, NULL in case of memory
00341    allocation failure.  */
00342 static void *
00343 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
00344 {
00345   const mp_limb_t *p1;
00346   const mp_limb_t *p2;
00347   size_t len1;
00348   size_t len2;
00349 
00350   if (src1.nlimbs <= src2.nlimbs)
00351     {
00352       len1 = src1.nlimbs;
00353       p1 = src1.limbs;
00354       len2 = src2.nlimbs;
00355       p2 = src2.limbs;
00356     }
00357   else
00358     {
00359       len1 = src2.nlimbs;
00360       p1 = src2.limbs;
00361       len2 = src1.nlimbs;
00362       p2 = src1.limbs;
00363     }
00364   /* Now 0 <= len1 <= len2.  */
00365   if (len1 == 0)
00366     {
00367       /* src1 or src2 is zero.  */
00368       dest->nlimbs = 0;
00369       dest->limbs = (mp_limb_t *) malloc (1);
00370     }
00371   else
00372     {
00373       /* Here 1 <= len1 <= len2.  */
00374       size_t dlen;
00375       mp_limb_t *dp;
00376       size_t k, i, j;
00377 
00378       dlen = len1 + len2;
00379       dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
00380       if (dp == NULL)
00381         return NULL;
00382       for (k = len2; k > 0; )
00383         dp[--k] = 0;
00384       for (i = 0; i < len1; i++)
00385         {
00386           mp_limb_t digit1 = p1[i];
00387           mp_twolimb_t carry = 0;
00388           for (j = 0; j < len2; j++)
00389             {
00390               mp_limb_t digit2 = p2[j];
00391               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
00392               carry += dp[i + j];
00393               dp[i + j] = (mp_limb_t) carry;
00394               carry = carry >> GMP_LIMB_BITS;
00395             }
00396           dp[i + len2] = (mp_limb_t) carry;
00397         }
00398       /* Normalise.  */
00399       while (dlen > 0 && dp[dlen - 1] == 0)
00400         dlen--;
00401       dest->nlimbs = dlen;
00402       dest->limbs = dp;
00403     }
00404   return dest->limbs;
00405 }
00406 
00407 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
00408    a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
00409    the remainder.
00410    Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
00411    q is incremented.
00412    Return the allocated memory in case of success, NULL in case of memory
00413    allocation failure.  */
00414 static void *
00415 divide (mpn_t a, mpn_t b, mpn_t *q)
00416 {
00417   /* Algorithm:
00418      First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
00419      with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
00420      If m<n, then q:=0 and r:=a.
00421      If m>=n=1, perform a single-precision division:
00422        r:=0, j:=m,
00423        while j>0 do
00424          {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
00425                = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
00426          j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
00427        Normalise [q[m-1],...,q[0]], yields q.
00428      If m>=n>1, perform a multiple-precision division:
00429        We have a/b < beta^(m-n+1).
00430        s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
00431        Shift a and b left by s bits, copying them. r:=a.
00432        r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
00433        For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
00434          Compute q* :
00435            q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
00436            In case of overflow (q* >= beta) set q* := beta-1.
00437            Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
00438            and c3 := b[n-2] * q*.
00439            {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
00440             occurred.  Furthermore 0 <= c3 < beta^2.
00441             If there was overflow and
00442             r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
00443             the next test can be skipped.}
00444            While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
00445              Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
00446            If q* > 0:
00447              Put r := r - b * q* * beta^j. In detail:
00448                [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
00449                hence: u:=0, for i:=0 to n-1 do
00450                               u := u + q* * b[i],
00451                               r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
00452                               u:=u div beta (+ 1, if carry in subtraction)
00453                       r[n+j]:=r[n+j]-u.
00454                {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
00455                                < q* + 1 <= beta,
00456                 the carry u does not overflow.}
00457              If a negative carry occurs, put q* := q* - 1
00458                and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
00459          Set q[j] := q*.
00460        Normalise [q[m-n],..,q[0]]; this yields the quotient q.
00461        Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
00462        rest r.
00463        The room for q[j] can be allocated at the memory location of r[n+j].
00464      Finally, round-to-even:
00465        Shift r left by 1 bit.
00466        If r > b or if r = b and q[0] is odd, q := q+1.
00467    */
00468   const mp_limb_t *a_ptr = a.limbs;
00469   size_t a_len = a.nlimbs;
00470   const mp_limb_t *b_ptr = b.limbs;
00471   size_t b_len = b.nlimbs;
00472   mp_limb_t *roomptr;
00473   mp_limb_t *tmp_roomptr = NULL;
00474   mp_limb_t *q_ptr;
00475   size_t q_len;
00476   mp_limb_t *r_ptr;
00477   size_t r_len;
00478 
00479   /* Allocate room for a_len+2 digits.
00480      (Need a_len+1 digits for the real division and 1 more digit for the
00481      final rounding of q.)  */
00482   roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
00483   if (roomptr == NULL)
00484     return NULL;
00485 
00486   /* Normalise a.  */
00487   while (a_len > 0 && a_ptr[a_len - 1] == 0)
00488     a_len--;
00489 
00490   /* Normalise b.  */
00491   for (;;)
00492     {
00493       if (b_len == 0)
00494         /* Division by zero.  */
00495         abort ();
00496       if (b_ptr[b_len - 1] == 0)
00497         b_len--;
00498       else
00499         break;
00500     }
00501 
00502   /* Here m = a_len >= 0 and n = b_len > 0.  */
00503 
00504   if (a_len < b_len)
00505     {
00506       /* m<n: trivial case.  q=0, r := copy of a.  */
00507       r_ptr = roomptr;
00508       r_len = a_len;
00509       memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
00510       q_ptr = roomptr + a_len;
00511       q_len = 0;
00512     }
00513   else if (b_len == 1)
00514     {
00515       /* n=1: single precision division.
00516          beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
00517       r_ptr = roomptr;
00518       q_ptr = roomptr + 1;
00519       {
00520         mp_limb_t den = b_ptr[0];
00521         mp_limb_t remainder = 0;
00522         const mp_limb_t *sourceptr = a_ptr + a_len;
00523         mp_limb_t *destptr = q_ptr + a_len;
00524         size_t count;
00525         for (count = a_len; count > 0; count--)
00526           {
00527             mp_twolimb_t num =
00528               ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
00529             *--destptr = num / den;
00530             remainder = num % den;
00531           }
00532         /* Normalise and store r.  */
00533         if (remainder > 0)
00534           {
00535             r_ptr[0] = remainder;
00536             r_len = 1;
00537           }
00538         else
00539           r_len = 0;
00540         /* Normalise q.  */
00541         q_len = a_len;
00542         if (q_ptr[q_len - 1] == 0)
00543           q_len--;
00544       }
00545     }
00546   else
00547     {
00548       /* n>1: multiple precision division.
00549          beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
00550          beta^(m-n-1) <= a/b < beta^(m-n+1).  */
00551       /* Determine s.  */
00552       size_t s;
00553       {
00554         mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
00555         s = 31;
00556         if (msd >= 0x10000)
00557           {
00558             msd = msd >> 16;
00559             s -= 16;
00560           }
00561         if (msd >= 0x100)
00562           {
00563             msd = msd >> 8;
00564             s -= 8;
00565           }
00566         if (msd >= 0x10)
00567           {
00568             msd = msd >> 4;
00569             s -= 4;
00570           }
00571         if (msd >= 0x4)
00572           {
00573             msd = msd >> 2;
00574             s -= 2;
00575           }
00576         if (msd >= 0x2)
00577           {
00578             msd = msd >> 1;
00579             s -= 1;
00580           }
00581       }
00582       /* 0 <= s < GMP_LIMB_BITS.
00583          Copy b, shifting it left by s bits.  */
00584       if (s > 0)
00585         {
00586           tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
00587           if (tmp_roomptr == NULL)
00588             {
00589               free (roomptr);
00590               return NULL;
00591             }
00592           {
00593             const mp_limb_t *sourceptr = b_ptr;
00594             mp_limb_t *destptr = tmp_roomptr;
00595             mp_twolimb_t accu = 0;
00596             size_t count;
00597             for (count = b_len; count > 0; count--)
00598               {
00599                 accu += (mp_twolimb_t) *sourceptr++ << s;
00600                 *destptr++ = (mp_limb_t) accu;
00601                 accu = accu >> GMP_LIMB_BITS;
00602               }
00603             /* accu must be zero, since that was how s was determined.  */
00604             if (accu != 0)
00605               abort ();
00606           }
00607           b_ptr = tmp_roomptr;
00608         }
00609       /* Copy a, shifting it left by s bits, yields r.
00610          Memory layout:
00611          At the beginning: r = roomptr[0..a_len],
00612          at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
00613       r_ptr = roomptr;
00614       if (s == 0)
00615         {
00616           memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
00617           r_ptr[a_len] = 0;
00618         }
00619       else
00620         {
00621           const mp_limb_t *sourceptr = a_ptr;
00622           mp_limb_t *destptr = r_ptr;
00623           mp_twolimb_t accu = 0;
00624           size_t count;
00625           for (count = a_len; count > 0; count--)
00626             {
00627               accu += (mp_twolimb_t) *sourceptr++ << s;
00628               *destptr++ = (mp_limb_t) accu;
00629               accu = accu >> GMP_LIMB_BITS;
00630             }
00631           *destptr++ = (mp_limb_t) accu;
00632         }
00633       q_ptr = roomptr + b_len;
00634       q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
00635       {
00636         size_t j = a_len - b_len; /* m-n */
00637         mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
00638         mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
00639         mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
00640           ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
00641         /* Division loop, traversed m-n+1 times.
00642            j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
00643         for (;;)
00644           {
00645             mp_limb_t q_star;
00646             mp_limb_t c1;
00647             if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
00648               {
00649                 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
00650                 mp_twolimb_t num =
00651                   ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
00652                   | r_ptr[j + b_len - 1];
00653                 q_star = num / b_msd;
00654                 c1 = num % b_msd;
00655               }
00656             else
00657               {
00658                 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
00659                 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
00660                 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
00661                    <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
00662                    <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
00663                         {<= beta !}.
00664                    If yes, jump directly to the subtraction loop.
00665                    (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
00666                     <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
00667                 if (r_ptr[j + b_len] > b_msd
00668                     || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
00669                   /* r[j+n] >= b[n-1]+1 or
00670                      r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
00671                      carry.  */
00672                   goto subtract;
00673               }
00674             /* q_star = q*,
00675                c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
00676             {
00677               mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
00678                 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
00679               mp_twolimb_t c3 = /* b[n-2] * q* */
00680                 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
00681               /* While c2 < c3, increase c2 and decrease c3.
00682                  Consider c3-c2.  While it is > 0, decrease it by
00683                  b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
00684                  this can happen only twice.  */
00685               if (c3 > c2)
00686                 {
00687                   q_star = q_star - 1; /* q* := q* - 1 */
00688                   if (c3 - c2 > b_msdd)
00689                     q_star = q_star - 1; /* q* := q* - 1 */
00690                 }
00691             }
00692             if (q_star > 0)
00693               subtract:
00694               {
00695                 /* Subtract r := r - b * q* * beta^j.  */
00696                 mp_limb_t cr;
00697                 {
00698                   const mp_limb_t *sourceptr = b_ptr;
00699                   mp_limb_t *destptr = r_ptr + j;
00700                   mp_twolimb_t carry = 0;
00701                   size_t count;
00702                   for (count = b_len; count > 0; count--)
00703                     {
00704                       /* Here 0 <= carry <= q*.  */
00705                       carry =
00706                         carry
00707                         + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
00708                         + (mp_limb_t) ~(*destptr);
00709                       /* Here 0 <= carry <= beta*q* + beta-1.  */
00710                       *destptr++ = ~(mp_limb_t) carry;
00711                       carry = carry >> GMP_LIMB_BITS; /* <= q* */
00712                     }
00713                   cr = (mp_limb_t) carry;
00714                 }
00715                 /* Subtract cr from r_ptr[j + b_len], then forget about
00716                    r_ptr[j + b_len].  */
00717                 if (cr > r_ptr[j + b_len])
00718                   {
00719                     /* Subtraction gave a carry.  */
00720                     q_star = q_star - 1; /* q* := q* - 1 */
00721                     /* Add b back.  */
00722                     {
00723                       const mp_limb_t *sourceptr = b_ptr;
00724                       mp_limb_t *destptr = r_ptr + j;
00725                       mp_limb_t carry = 0;
00726                       size_t count;
00727                       for (count = b_len; count > 0; count--)
00728                         {
00729                           mp_limb_t source1 = *sourceptr++;
00730                           mp_limb_t source2 = *destptr;
00731                           *destptr++ = source1 + source2 + carry;
00732                           carry =
00733                             (carry
00734                              ? source1 >= (mp_limb_t) ~source2
00735                              : source1 > (mp_limb_t) ~source2);
00736                         }
00737                     }
00738                     /* Forget about the carry and about r[j+n].  */
00739                   }
00740               }
00741             /* q* is determined.  Store it as q[j].  */
00742             q_ptr[j] = q_star;
00743             if (j == 0)
00744               break;
00745             j--;
00746           }
00747       }
00748       r_len = b_len;
00749       /* Normalise q.  */
00750       if (q_ptr[q_len - 1] == 0)
00751         q_len--;
00752 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
00753           b is shifted left by s bits.  */
00754       /* Shift r right by s bits.  */
00755       if (s > 0)
00756         {
00757           mp_limb_t ptr = r_ptr + r_len;
00758           mp_twolimb_t accu = 0;
00759           size_t count;
00760           for (count = r_len; count > 0; count--)
00761             {
00762               accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
00763               accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
00764               *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
00765             }
00766         }
00767 # endif
00768       /* Normalise r.  */
00769       while (r_len > 0 && r_ptr[r_len - 1] == 0)
00770         r_len--;
00771     }
00772   /* Compare r << 1 with b.  */
00773   if (r_len > b_len)
00774     goto increment_q;
00775   {
00776     size_t i;
00777     for (i = b_len;;)
00778       {
00779         mp_limb_t r_i =
00780           (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
00781           | (i < r_len ? r_ptr[i] << 1 : 0);
00782         mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
00783         if (r_i > b_i)
00784           goto increment_q;
00785         if (r_i < b_i)
00786           goto keep_q;
00787         if (i == 0)
00788           break;
00789         i--;
00790       }
00791   }
00792   if (q_len > 0 && ((q_ptr[0] & 1) != 0))
00793     /* q is odd.  */
00794     increment_q:
00795     {
00796       size_t i;
00797       for (i = 0; i < q_len; i++)
00798         if (++(q_ptr[i]) != 0)
00799           goto keep_q;
00800       q_ptr[q_len++] = 1;
00801     }
00802   keep_q:
00803   if (tmp_roomptr != NULL)
00804     free (tmp_roomptr);
00805   q->limbs = q_ptr;
00806   q->nlimbs = q_len;
00807   return roomptr;
00808 }
00809 
00810 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
00811    representation.
00812    Destroys the contents of a.
00813    Return the allocated memory - containing the decimal digits in low-to-high
00814    order, terminated with a NUL character - in case of success, NULL in case
00815    of memory allocation failure.  */
00816 static char *
00817 convert_to_decimal (mpn_t a, size_t extra_zeroes)
00818 {
00819   mp_limb_t *a_ptr = a.limbs;
00820   size_t a_len = a.nlimbs;
00821   /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
00822   size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
00823   char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
00824   if (c_ptr != NULL)
00825     {
00826       char *d_ptr = c_ptr;
00827       for (; extra_zeroes > 0; extra_zeroes--)
00828         *d_ptr++ = '0';
00829       while (a_len > 0)
00830         {
00831           /* Divide a by 10^9, in-place.  */
00832           mp_limb_t remainder = 0;
00833           mp_limb_t *ptr = a_ptr + a_len;
00834           size_t count;
00835           for (count = a_len; count > 0; count--)
00836             {
00837               mp_twolimb_t num =
00838                 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
00839               *ptr = num / 1000000000;
00840               remainder = num % 1000000000;
00841             }
00842           /* Store the remainder as 9 decimal digits.  */
00843           for (count = 9; count > 0; count--)
00844             {
00845               *d_ptr++ = '0' + (remainder % 10);
00846               remainder = remainder / 10;
00847             }
00848           /* Normalize a.  */
00849           if (a_ptr[a_len - 1] == 0)
00850             a_len--;
00851         }
00852       /* Remove leading zeroes.  */
00853       while (d_ptr > c_ptr && d_ptr[-1] == '0')
00854         d_ptr--;
00855       /* But keep at least one zero.  */
00856       if (d_ptr == c_ptr)
00857         *d_ptr++ = '0';
00858       /* Terminate the string.  */
00859       *d_ptr = '\0';
00860     }
00861   return c_ptr;
00862 }
00863 
00864 # if NEED_PRINTF_LONG_DOUBLE
00865 
00866 /* Assuming x is finite and >= 0:
00867    write x as x = 2^e * m, where m is a bignum.
00868    Return the allocated memory in case of success, NULL in case of memory
00869    allocation failure.  */
00870 static void *
00871 decode_long_double (long double x, int *ep, mpn_t *mp)
00872 {
00873   mpn_t m;
00874   int exp;
00875   long double y;
00876   size_t i;
00877 
00878   /* Allocate memory for result.  */
00879   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
00880   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
00881   if (m.limbs == NULL)
00882     return NULL;
00883   /* Split into exponential part and mantissa.  */
00884   y = frexpl (x, &exp);
00885   if (!(y >= 0.0L && y < 1.0L))
00886     abort ();
00887   /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
00888      latter is an integer.  */
00889   /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
00890      I'm not sure whether it's safe to cast a 'long double' value between
00891      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
00892      'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
00893      doesn't matter).  */
00894 #  if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
00895 #   if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
00896     {
00897       mp_limb_t hi, lo;
00898       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
00899       hi = (int) y;
00900       y -= hi;
00901       if (!(y >= 0.0L && y < 1.0L))
00902         abort ();
00903       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
00904       lo = (int) y;
00905       y -= lo;
00906       if (!(y >= 0.0L && y < 1.0L))
00907         abort ();
00908       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
00909     }
00910 #   else
00911     {
00912       mp_limb_t d;
00913       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
00914       d = (int) y;
00915       y -= d;
00916       if (!(y >= 0.0L && y < 1.0L))
00917         abort ();
00918       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
00919     }
00920 #   endif
00921 #  endif
00922   for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
00923     {
00924       mp_limb_t hi, lo;
00925       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
00926       hi = (int) y;
00927       y -= hi;
00928       if (!(y >= 0.0L && y < 1.0L))
00929         abort ();
00930       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
00931       lo = (int) y;
00932       y -= lo;
00933       if (!(y >= 0.0L && y < 1.0L))
00934         abort ();
00935       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
00936     }
00937 #if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
00938          precision.  */
00939   if (!(y == 0.0L))
00940     abort ();
00941 #endif
00942   /* Normalise.  */
00943   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
00944     m.nlimbs--;
00945   *mp = m;
00946   *ep = exp - LDBL_MANT_BIT;
00947   return m.limbs;
00948 }
00949 
00950 # endif
00951 
00952 # if NEED_PRINTF_DOUBLE
00953 
00954 /* Assuming x is finite and >= 0:
00955    write x as x = 2^e * m, where m is a bignum.
00956    Return the allocated memory in case of success, NULL in case of memory
00957    allocation failure.  */
00958 static void *
00959 decode_double (double x, int *ep, mpn_t *mp)
00960 {
00961   mpn_t m;
00962   int exp;
00963   double y;
00964   size_t i;
00965 
00966   /* Allocate memory for result.  */
00967   m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
00968   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
00969   if (m.limbs == NULL)
00970     return NULL;
00971   /* Split into exponential part and mantissa.  */
00972   y = frexp (x, &exp);
00973   if (!(y >= 0.0 && y < 1.0))
00974     abort ();
00975   /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
00976      latter is an integer.  */
00977   /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
00978      I'm not sure whether it's safe to cast a 'double' value between
00979      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
00980      'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
00981      doesn't matter).  */
00982 #  if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
00983 #   if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
00984     {
00985       mp_limb_t hi, lo;
00986       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
00987       hi = (int) y;
00988       y -= hi;
00989       if (!(y >= 0.0 && y < 1.0))
00990         abort ();
00991       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
00992       lo = (int) y;
00993       y -= lo;
00994       if (!(y >= 0.0 && y < 1.0))
00995         abort ();
00996       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
00997     }
00998 #   else
00999     {
01000       mp_limb_t d;
01001       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
01002       d = (int) y;
01003       y -= d;
01004       if (!(y >= 0.0 && y < 1.0))
01005         abort ();
01006       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
01007     }
01008 #   endif
01009 #  endif
01010   for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
01011     {
01012       mp_limb_t hi, lo;
01013       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
01014       hi = (int) y;
01015       y -= hi;
01016       if (!(y >= 0.0 && y < 1.0))
01017         abort ();
01018       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
01019       lo = (int) y;
01020       y -= lo;
01021       if (!(y >= 0.0 && y < 1.0))
01022         abort ();
01023       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
01024     }
01025   if (!(y == 0.0))
01026     abort ();
01027   /* Normalise.  */
01028   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
01029     m.nlimbs--;
01030   *mp = m;
01031   *ep = exp - DBL_MANT_BIT;
01032   return m.limbs;
01033 }
01034 
01035 # endif
01036 
01037 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
01038    Returns the decimal representation of round (x * 10^n).
01039    Return the allocated memory - containing the decimal digits in low-to-high
01040    order, terminated with a NUL character - in case of success, NULL in case
01041    of memory allocation failure.  */
01042 static char *
01043 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
01044 {
01045   int s;
01046   size_t extra_zeroes;
01047   unsigned int abs_n;
01048   unsigned int abs_s;
01049   mp_limb_t *pow5_ptr;
01050   size_t pow5_len;
01051   unsigned int s_limbs;
01052   unsigned int s_bits;
01053   mpn_t pow5;
01054   mpn_t z;
01055   void *z_memory;
01056   char *digits;
01057 
01058   if (memory == NULL)
01059     return NULL;
01060   /* x = 2^e * m, hence
01061      y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
01062        = round (2^s * 5^n * m).  */
01063   s = e + n;
01064   extra_zeroes = 0;
01065   /* Factor out a common power of 10 if possible.  */
01066   if (s > 0 && n > 0)
01067     {
01068       extra_zeroes = (s < n ? s : n);
01069       s -= extra_zeroes;
01070       n -= extra_zeroes;
01071     }
01072   /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
01073      Before converting to decimal, we need to compute
01074      z = round (2^s * 5^n * m).  */
01075   /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
01076      sign.  2.322 is slightly larger than log(5)/log(2).  */
01077   abs_n = (n >= 0 ? n : -n);
01078   abs_s = (s >= 0 ? s : -s);
01079   pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
01080                                     + abs_s / GMP_LIMB_BITS + 1)
01081                                    * sizeof (mp_limb_t));
01082   if (pow5_ptr == NULL)
01083     {
01084       free (memory);
01085       return NULL;
01086     }
01087   /* Initialize with 1.  */
01088   pow5_ptr[0] = 1;
01089   pow5_len = 1;
01090   /* Multiply with 5^|n|.  */
01091   if (abs_n > 0)
01092     {
01093       static mp_limb_t const small_pow5[13 + 1] =
01094         {
01095           1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
01096           48828125, 244140625, 1220703125
01097         };
01098       unsigned int n13;
01099       for (n13 = 0; n13 <= abs_n; n13 += 13)
01100         {
01101           mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
01102           size_t j;
01103           mp_twolimb_t carry = 0;
01104           for (j = 0; j < pow5_len; j++)
01105             {
01106               mp_limb_t digit2 = pow5_ptr[j];
01107               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
01108               pow5_ptr[j] = (mp_limb_t) carry;
01109               carry = carry >> GMP_LIMB_BITS;
01110             }
01111           if (carry > 0)
01112             pow5_ptr[pow5_len++] = (mp_limb_t) carry;
01113         }
01114     }
01115   s_limbs = abs_s / GMP_LIMB_BITS;
01116   s_bits = abs_s % GMP_LIMB_BITS;
01117   if (n >= 0 ? s >= 0 : s <= 0)
01118     {
01119       /* Multiply with 2^|s|.  */
01120       if (s_bits > 0)
01121         {
01122           mp_limb_t *ptr = pow5_ptr;
01123           mp_twolimb_t accu = 0;
01124           size_t count;
01125           for (count = pow5_len; count > 0; count--)
01126             {
01127               accu += (mp_twolimb_t) *ptr << s_bits;
01128               *ptr++ = (mp_limb_t) accu;
01129               accu = accu >> GMP_LIMB_BITS;
01130             }
01131           if (accu > 0)
01132             {
01133               *ptr = (mp_limb_t) accu;
01134               pow5_len++;
01135             }
01136         }
01137       if (s_limbs > 0)
01138         {
01139           size_t count;
01140           for (count = pow5_len; count > 0;)
01141             {
01142               count--;
01143               pow5_ptr[s_limbs + count] = pow5_ptr[count];
01144             }
01145           for (count = s_limbs; count > 0;)
01146             {
01147               count--;
01148               pow5_ptr[count] = 0;
01149             }
01150           pow5_len += s_limbs;
01151         }
01152       pow5.limbs = pow5_ptr;
01153       pow5.nlimbs = pow5_len;
01154       if (n >= 0)
01155         {
01156           /* Multiply m with pow5.  No division needed.  */
01157           z_memory = multiply (m, pow5, &z);
01158         }
01159       else
01160         {
01161           /* Divide m by pow5 and round.  */
01162           z_memory = divide (m, pow5, &z);
01163         }
01164     }
01165   else
01166     {
01167       pow5.limbs = pow5_ptr;
01168       pow5.nlimbs = pow5_len;
01169       if (n >= 0)
01170         {
01171           /* n >= 0, s < 0.
01172              Multiply m with pow5, then divide by 2^|s|.  */
01173           mpn_t numerator;
01174           mpn_t denominator;
01175           void *tmp_memory;
01176           tmp_memory = multiply (m, pow5, &numerator);
01177           if (tmp_memory == NULL)
01178             {
01179               free (pow5_ptr);
01180               free (memory);
01181               return NULL;
01182             }
01183           /* Construct 2^|s|.  */
01184           {
01185             mp_limb_t *ptr = pow5_ptr + pow5_len;
01186             size_t i;
01187             for (i = 0; i < s_limbs; i++)
01188               ptr[i] = 0;
01189             ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
01190             denominator.limbs = ptr;
01191             denominator.nlimbs = s_limbs + 1;
01192           }
01193           z_memory = divide (numerator, denominator, &z);
01194           free (tmp_memory);
01195         }
01196       else
01197         {
01198           /* n < 0, s > 0.
01199              Multiply m with 2^s, then divide by pow5.  */
01200           mpn_t numerator;
01201           mp_limb_t *num_ptr;
01202           num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
01203                                           * sizeof (mp_limb_t));
01204           if (num_ptr == NULL)
01205             {
01206               free (pow5_ptr);
01207               free (memory);
01208               return NULL;
01209             }
01210           {
01211             mp_limb_t *destptr = num_ptr;
01212             {
01213               size_t i;
01214               for (i = 0; i < s_limbs; i++)
01215                 *destptr++ = 0;
01216             }
01217             if (s_bits > 0)
01218               {
01219                 const mp_limb_t *sourceptr = m.limbs;
01220                 mp_twolimb_t accu = 0;
01221                 size_t count;
01222                 for (count = m.nlimbs; count > 0; count--)
01223                   {
01224                     accu += (mp_twolimb_t) *sourceptr++ << s_bits;
01225                     *destptr++ = (mp_limb_t) accu;
01226                     accu = accu >> GMP_LIMB_BITS;
01227                   }
01228                 if (accu > 0)
01229                   *destptr++ = (mp_limb_t) accu;
01230               }
01231             else
01232               {
01233                 const mp_limb_t *sourceptr = m.limbs;
01234                 size_t count;
01235                 for (count = m.nlimbs; count > 0; count--)
01236                   *destptr++ = *sourceptr++;
01237               }
01238             numerator.limbs = num_ptr;
01239             numerator.nlimbs = destptr - num_ptr;
01240           }
01241           z_memory = divide (numerator, pow5, &z);
01242           free (num_ptr);
01243         }
01244     }
01245   free (pow5_ptr);
01246   free (memory);
01247 
01248   /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
01249 
01250   if (z_memory == NULL)
01251     return NULL;
01252   digits = convert_to_decimal (z, extra_zeroes);
01253   free (z_memory);
01254   return digits;
01255 }
01256 
01257 # if NEED_PRINTF_LONG_DOUBLE
01258 
01259 /* Assuming x is finite and >= 0, and n is an integer:
01260    Returns the decimal representation of round (x * 10^n).
01261    Return the allocated memory - containing the decimal digits in low-to-high
01262    order, terminated with a NUL character - in case of success, NULL in case
01263    of memory allocation failure.  */
01264 static char *
01265 scale10_round_decimal_long_double (long double x, int n)
01266 {
01267   int e IF_LINT(= 0);
01268   mpn_t m;
01269   void *memory = decode_long_double (x, &e, &m);
01270   return scale10_round_decimal_decoded (e, m, memory, n);
01271 }
01272 
01273 # endif
01274 
01275 # if NEED_PRINTF_DOUBLE
01276 
01277 /* Assuming x is finite and >= 0, and n is an integer:
01278    Returns the decimal representation of round (x * 10^n).
01279    Return the allocated memory - containing the decimal digits in low-to-high
01280    order, terminated with a NUL character - in case of success, NULL in case
01281    of memory allocation failure.  */
01282 static char *
01283 scale10_round_decimal_double (double x, int n)
01284 {
01285   int e IF_LINT(= 0);
01286   mpn_t m;
01287   void *memory = decode_double (x, &e, &m);
01288   return scale10_round_decimal_decoded (e, m, memory, n);
01289 }
01290 
01291 # endif
01292 
01293 # if NEED_PRINTF_LONG_DOUBLE
01294 
01295 /* Assuming x is finite and > 0:
01296    Return an approximation for n with 10^n <= x < 10^(n+1).
01297    The approximation is usually the right n, but may be off by 1 sometimes.  */
01298 static int
01299 floorlog10l (long double x)
01300 {
01301   int exp;
01302   long double y;
01303   double z;
01304   double l;
01305 
01306   /* Split into exponential part and mantissa.  */
01307   y = frexpl (x, &exp);
01308   if (!(y >= 0.0L && y < 1.0L))
01309     abort ();
01310   if (y == 0.0L)
01311     return INT_MIN;
01312   if (y < 0.5L)
01313     {
01314       while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
01315         {
01316           y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
01317           exp -= GMP_LIMB_BITS;
01318         }
01319       if (y < (1.0L / (1 << 16)))
01320         {
01321           y *= 1.0L * (1 << 16);
01322           exp -= 16;
01323         }
01324       if (y < (1.0L / (1 << 8)))
01325         {
01326           y *= 1.0L * (1 << 8);
01327           exp -= 8;
01328         }
01329       if (y < (1.0L / (1 << 4)))
01330         {
01331           y *= 1.0L * (1 << 4);
01332           exp -= 4;
01333         }
01334       if (y < (1.0L / (1 << 2)))
01335         {
01336           y *= 1.0L * (1 << 2);
01337           exp -= 2;
01338         }
01339       if (y < (1.0L / (1 << 1)))
01340         {
01341           y *= 1.0L * (1 << 1);
01342           exp -= 1;
01343         }
01344     }
01345   if (!(y >= 0.5L && y < 1.0L))
01346     abort ();
01347   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
01348   l = exp;
01349   z = y;
01350   if (z < 0.70710678118654752444)
01351     {
01352       z *= 1.4142135623730950488;
01353       l -= 0.5;
01354     }
01355   if (z < 0.8408964152537145431)
01356     {
01357       z *= 1.1892071150027210667;
01358       l -= 0.25;
01359     }
01360   if (z < 0.91700404320467123175)
01361     {
01362       z *= 1.0905077326652576592;
01363       l -= 0.125;
01364     }
01365   if (z < 0.9576032806985736469)
01366     {
01367       z *= 1.0442737824274138403;
01368       l -= 0.0625;
01369     }
01370   /* Now 0.95 <= z <= 1.01.  */
01371   z = 1 - z;
01372   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
01373      Four terms are enough to get an approximation with error < 10^-7.  */
01374   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
01375   /* Finally multiply with log(2)/log(10), yields an approximation for
01376      log10(x).  */
01377   l *= 0.30102999566398119523;
01378   /* Round down to the next integer.  */
01379   return (int) l + (l < 0 ? -1 : 0);
01380 }
01381 
01382 # endif
01383 
01384 # if NEED_PRINTF_DOUBLE
01385 
01386 /* Assuming x is finite and > 0:
01387    Return an approximation for n with 10^n <= x < 10^(n+1).
01388    The approximation is usually the right n, but may be off by 1 sometimes.  */
01389 static int
01390 floorlog10 (double x)
01391 {
01392   int exp;
01393   double y;
01394   double z;
01395   double l;
01396 
01397   /* Split into exponential part and mantissa.  */
01398   y = frexp (x, &exp);
01399   if (!(y >= 0.0 && y < 1.0))
01400     abort ();
01401   if (y == 0.0)
01402     return INT_MIN;
01403   if (y < 0.5)
01404     {
01405       while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
01406         {
01407           y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
01408           exp -= GMP_LIMB_BITS;
01409         }
01410       if (y < (1.0 / (1 << 16)))
01411         {
01412           y *= 1.0 * (1 << 16);
01413           exp -= 16;
01414         }
01415       if (y < (1.0 / (1 << 8)))
01416         {
01417           y *= 1.0 * (1 << 8);
01418           exp -= 8;
01419         }
01420       if (y < (1.0 / (1 << 4)))
01421         {
01422           y *= 1.0 * (1 << 4);
01423           exp -= 4;
01424         }
01425       if (y < (1.0 / (1 << 2)))
01426         {
01427           y *= 1.0 * (1 << 2);
01428           exp -= 2;
01429         }
01430       if (y < (1.0 / (1 << 1)))
01431         {
01432           y *= 1.0 * (1 << 1);
01433           exp -= 1;
01434         }
01435     }
01436   if (!(y >= 0.5 && y < 1.0))
01437     abort ();
01438   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
01439   l = exp;
01440   z = y;
01441   if (z < 0.70710678118654752444)
01442     {
01443       z *= 1.4142135623730950488;
01444       l -= 0.5;
01445     }
01446   if (z < 0.8408964152537145431)
01447     {
01448       z *= 1.1892071150027210667;
01449       l -= 0.25;
01450     }
01451   if (z < 0.91700404320467123175)
01452     {
01453       z *= 1.0905077326652576592;
01454       l -= 0.125;
01455     }
01456   if (z < 0.9576032806985736469)
01457     {
01458       z *= 1.0442737824274138403;
01459       l -= 0.0625;
01460     }
01461   /* Now 0.95 <= z <= 1.01.  */
01462   z = 1 - z;
01463   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
01464      Four terms are enough to get an approximation with error < 10^-7.  */
01465   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
01466   /* Finally multiply with log(2)/log(10), yields an approximation for
01467      log10(x).  */
01468   l *= 0.30102999566398119523;
01469   /* Round down to the next integer.  */
01470   return (int) l + (l < 0 ? -1 : 0);
01471 }
01472 
01473 # endif
01474 
01475 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
01476    a single '1' digit.  */
01477 static int
01478 is_borderline (const char *digits, size_t precision)
01479 {
01480   for (; precision > 0; precision--, digits++)
01481     if (*digits != '0')
01482       return 0;
01483   if (*digits != '1')
01484     return 0;
01485   digits++;
01486   return *digits == '\0';
01487 }
01488 
01489 #endif
01490 
01491 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
01492 
01493 /* Use a different function name, to make it possible that the 'wchar_t'
01494    parametrization and the 'char' parametrization get compiled in the same
01495    translation unit.  */
01496 # if WIDE_CHAR_VERSION
01497 #  define MAX_ROOM_NEEDED wmax_room_needed
01498 # else
01499 #  define MAX_ROOM_NEEDED max_room_needed
01500 # endif
01501 
01502 /* Returns the number of TCHAR_T units needed as temporary space for the result
01503    of sprintf or SNPRINTF of a single conversion directive.  */
01504 static inline size_t
01505 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
01506                  arg_type type, int flags, size_t width, int has_precision,
01507                  size_t precision, int pad_ourselves)
01508 {
01509   size_t tmp_length;
01510 
01511   switch (conversion)
01512     {
01513     case 'd': case 'i': case 'u':
01514 # if HAVE_LONG_LONG_INT
01515       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
01516         tmp_length =
01517           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
01518                           * 0.30103 /* binary -> decimal */
01519                          )
01520           + 1; /* turn floor into ceil */
01521       else
01522 # endif
01523       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
01524         tmp_length =
01525           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
01526                           * 0.30103 /* binary -> decimal */
01527                          )
01528           + 1; /* turn floor into ceil */
01529       else
01530         tmp_length =
01531           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
01532                           * 0.30103 /* binary -> decimal */
01533                          )
01534           + 1; /* turn floor into ceil */
01535       if (tmp_length < precision)
01536         tmp_length = precision;
01537       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
01538       tmp_length = xsum (tmp_length, tmp_length);
01539       /* Add 1, to account for a leading sign.  */
01540       tmp_length = xsum (tmp_length, 1);
01541       break;
01542 
01543     case 'o':
01544 # if HAVE_LONG_LONG_INT
01545       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
01546         tmp_length =
01547           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
01548                           * 0.333334 /* binary -> octal */
01549                          )
01550           + 1; /* turn floor into ceil */
01551       else
01552 # endif
01553       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
01554         tmp_length =
01555           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
01556                           * 0.333334 /* binary -> octal */
01557                          )
01558           + 1; /* turn floor into ceil */
01559       else
01560         tmp_length =
01561           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
01562                           * 0.333334 /* binary -> octal */
01563                          )
01564           + 1; /* turn floor into ceil */
01565       if (tmp_length < precision)
01566         tmp_length = precision;
01567       /* Add 1, to account for a leading sign.  */
01568       tmp_length = xsum (tmp_length, 1);
01569       break;
01570 
01571     case 'x': case 'X':
01572 # if HAVE_LONG_LONG_INT
01573       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
01574         tmp_length =
01575           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
01576                           * 0.25 /* binary -> hexadecimal */
01577                          )
01578           + 1; /* turn floor into ceil */
01579       else
01580 # endif
01581       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
01582         tmp_length =
01583           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
01584                           * 0.25 /* binary -> hexadecimal */
01585                          )
01586           + 1; /* turn floor into ceil */
01587       else
01588         tmp_length =
01589           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
01590                           * 0.25 /* binary -> hexadecimal */
01591                          )
01592           + 1; /* turn floor into ceil */
01593       if (tmp_length < precision)
01594         tmp_length = precision;
01595       /* Add 2, to account for a leading sign or alternate form.  */
01596       tmp_length = xsum (tmp_length, 2);
01597       break;
01598 
01599     case 'f': case 'F':
01600       if (type == TYPE_LONGDOUBLE)
01601         tmp_length =
01602           (unsigned int) (LDBL_MAX_EXP
01603                           * 0.30103 /* binary -> decimal */
01604                           * 2 /* estimate for FLAG_GROUP */
01605                          )
01606           + 1 /* turn floor into ceil */
01607           + 10; /* sign, decimal point etc. */
01608       else
01609         tmp_length =
01610           (unsigned int) (DBL_MAX_EXP
01611                           * 0.30103 /* binary -> decimal */
01612                           * 2 /* estimate for FLAG_GROUP */
01613                          )
01614           + 1 /* turn floor into ceil */
01615           + 10; /* sign, decimal point etc. */
01616       tmp_length = xsum (tmp_length, precision);
01617       break;
01618 
01619     case 'e': case 'E': case 'g': case 'G':
01620       tmp_length =
01621         12; /* sign, decimal point, exponent etc. */
01622       tmp_length = xsum (tmp_length, precision);
01623       break;
01624 
01625     case 'a': case 'A':
01626       if (type == TYPE_LONGDOUBLE)
01627         tmp_length =
01628           (unsigned int) (LDBL_DIG
01629                           * 0.831 /* decimal -> hexadecimal */
01630                          )
01631           + 1; /* turn floor into ceil */
01632       else
01633         tmp_length =
01634           (unsigned int) (DBL_DIG
01635                           * 0.831 /* decimal -> hexadecimal */
01636                          )
01637           + 1; /* turn floor into ceil */
01638       if (tmp_length < precision)
01639         tmp_length = precision;
01640       /* Account for sign, decimal point etc. */
01641       tmp_length = xsum (tmp_length, 12);
01642       break;
01643 
01644     case 'c':
01645 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
01646       if (type == TYPE_WIDE_CHAR)
01647         tmp_length = MB_CUR_MAX;
01648       else
01649 # endif
01650         tmp_length = 1;
01651       break;
01652 
01653     case 's':
01654 # if HAVE_WCHAR_T
01655       if (type == TYPE_WIDE_STRING)
01656         {
01657 #  if WIDE_CHAR_VERSION
01658           /* ISO C says about %ls in fwprintf:
01659                "If the precision is not specified or is greater than the size
01660                 of the array, the array shall contain a null wide character."
01661              So if there is a precision, we must not use wcslen.  */
01662           const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
01663 
01664           if (has_precision)
01665             tmp_length = local_wcsnlen (arg, precision);
01666           else
01667             tmp_length = local_wcslen (arg);
01668 #  else
01669           /* ISO C says about %ls in fprintf:
01670                "If a precision is specified, no more than that many bytes are
01671                 written (including shift sequences, if any), and the array
01672                 shall contain a null wide character if, to equal the multibyte
01673                 character sequence length given by the precision, the function
01674                 would need to access a wide character one past the end of the
01675                 array."
01676              So if there is a precision, we must not use wcslen.  */
01677           /* This case has already been handled separately in VASNPRINTF.  */
01678           abort ();
01679 #  endif
01680         }
01681       else
01682 # endif
01683         {
01684 # if WIDE_CHAR_VERSION
01685           /* ISO C says about %s in fwprintf:
01686                "If the precision is not specified or is greater than the size
01687                 of the converted array, the converted array shall contain a
01688                 null wide character."
01689              So if there is a precision, we must not use strlen.  */
01690           /* This case has already been handled separately in VASNPRINTF.  */
01691           abort ();
01692 # else
01693           /* ISO C says about %s in fprintf:
01694                "If the precision is not specified or greater than the size of
01695                 the array, the array shall contain a null character."
01696              So if there is a precision, we must not use strlen.  */
01697           const char *arg = ap->arg[arg_index].a.a_string;
01698 
01699           if (has_precision)
01700             tmp_length = local_strnlen (arg, precision);
01701           else
01702             tmp_length = strlen (arg);
01703 # endif
01704         }
01705       break;
01706 
01707     case 'p':
01708       tmp_length =
01709         (unsigned int) (sizeof (void *) * CHAR_BIT
01710                         * 0.25 /* binary -> hexadecimal */
01711                        )
01712           + 1 /* turn floor into ceil */
01713           + 2; /* account for leading 0x */
01714       break;
01715 
01716     default:
01717       abort ();
01718     }
01719 
01720   if (!pad_ourselves)
01721     {
01722 # if ENABLE_UNISTDIO
01723       /* Padding considers the number of characters, therefore the number of
01724          elements after padding may be
01725            > max (tmp_length, width)
01726          but is certainly
01727            <= tmp_length + width.  */
01728       tmp_length = xsum (tmp_length, width);
01729 # else
01730       /* Padding considers the number of elements, says POSIX.  */
01731       if (tmp_length < width)
01732         tmp_length = width;
01733 # endif
01734     }
01735 
01736   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
01737 
01738   return tmp_length;
01739 }
01740 
01741 #endif
01742 
01743 DCHAR_T *
01744 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
01745             const FCHAR_T *format, va_list args)
01746 {
01747   DIRECTIVES d;
01748   arguments a;
01749 
01750   if (PRINTF_PARSE (format, &d, &a) < 0)
01751     /* errno is already set.  */
01752     return NULL;
01753 
01754 #define CLEANUP() \
01755   free (d.dir);                                                         \
01756   if (a.arg)                                                            \
01757     free (a.arg);
01758 
01759   if (PRINTF_FETCHARGS (args, &a) < 0)
01760     {
01761       CLEANUP ();
01762       errno = EINVAL;
01763       return NULL;
01764     }
01765 
01766   {
01767     size_t buf_neededlength;
01768     TCHAR_T *buf;
01769     TCHAR_T *buf_malloced;
01770     const FCHAR_T *cp;
01771     size_t i;
01772     DIRECTIVE *dp;
01773     /* Output string accumulator.  */
01774     DCHAR_T *result;
01775     size_t allocated;
01776     size_t length;
01777 
01778     /* Allocate a small buffer that will hold a directive passed to
01779        sprintf or snprintf.  */
01780     buf_neededlength =
01781       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
01782 #if HAVE_ALLOCA
01783     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
01784       {
01785         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
01786         buf_malloced = NULL;
01787       }
01788     else
01789 #endif
01790       {
01791         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
01792         if (size_overflow_p (buf_memsize))
01793           goto out_of_memory_1;
01794         buf = (TCHAR_T *) malloc (buf_memsize);
01795         if (buf == NULL)
01796           goto out_of_memory_1;
01797         buf_malloced = buf;
01798       }
01799 
01800     if (resultbuf != NULL)
01801       {
01802         result = resultbuf;
01803         allocated = *lengthp;
01804       }
01805     else
01806       {
01807         result = NULL;
01808         allocated = 0;
01809       }
01810     length = 0;
01811     /* Invariants:
01812        result is either == resultbuf or == NULL or malloc-allocated.
01813        If length > 0, then result != NULL.  */
01814 
01815     /* Ensures that allocated >= needed.  Aborts through a jump to
01816        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
01817 #define ENSURE_ALLOCATION(needed) \
01818     if ((needed) > allocated)                                                \
01819       {                                                                      \
01820         size_t memory_size;                                                  \
01821         DCHAR_T *memory;                                                     \
01822                                                                              \
01823         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
01824         if ((needed) > allocated)                                            \
01825           allocated = (needed);                                              \
01826         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
01827         if (size_overflow_p (memory_size))                                   \
01828           goto out_of_memory;                                                \
01829         if (result == resultbuf || result == NULL)                           \
01830           memory = (DCHAR_T *) malloc (memory_size);                         \
01831         else                                                                 \
01832           memory = (DCHAR_T *) realloc (result, memory_size);                \
01833         if (memory == NULL)                                                  \
01834           goto out_of_memory;                                                \
01835         if (result == resultbuf && length > 0)                               \
01836           DCHAR_CPY (memory, result, length);                                \
01837         result = memory;                                                     \
01838       }
01839 
01840     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
01841       {
01842         if (cp != dp->dir_start)
01843           {
01844             size_t n = dp->dir_start - cp;
01845             size_t augmented_length = xsum (length, n);
01846 
01847             ENSURE_ALLOCATION (augmented_length);
01848             /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
01849                need that the format string contains only ASCII characters
01850                if FCHAR_T and DCHAR_T are not the same type.  */
01851             if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
01852               {
01853                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
01854                 length = augmented_length;
01855               }
01856             else
01857               {
01858                 do
01859                   result[length++] = (unsigned char) *cp++;
01860                 while (--n > 0);
01861               }
01862           }
01863         if (i == d.count)
01864           break;
01865 
01866         /* Execute a single directive.  */
01867         if (dp->conversion == '%')
01868           {
01869             size_t augmented_length;
01870 
01871             if (!(dp->arg_index == ARG_NONE))
01872               abort ();
01873             augmented_length = xsum (length, 1);
01874             ENSURE_ALLOCATION (augmented_length);
01875             result[length] = '%';
01876             length = augmented_length;
01877           }
01878         else
01879           {
01880             if (!(dp->arg_index != ARG_NONE))
01881               abort ();
01882 
01883             if (dp->conversion == 'n')
01884               {
01885                 switch (a.arg[dp->arg_index].type)
01886                   {
01887                   case TYPE_COUNT_SCHAR_POINTER:
01888                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
01889                     break;
01890                   case TYPE_COUNT_SHORT_POINTER:
01891                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
01892                     break;
01893                   case TYPE_COUNT_INT_POINTER:
01894                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
01895                     break;
01896                   case TYPE_COUNT_LONGINT_POINTER:
01897                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
01898                     break;
01899 #if HAVE_LONG_LONG_INT
01900                   case TYPE_COUNT_LONGLONGINT_POINTER:
01901                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
01902                     break;
01903 #endif
01904                   default:
01905                     abort ();
01906                   }
01907               }
01908 #if ENABLE_UNISTDIO
01909             /* The unistdio extensions.  */
01910             else if (dp->conversion == 'U')
01911               {
01912                 arg_type type = a.arg[dp->arg_index].type;
01913                 int flags = dp->flags;
01914                 int has_width;
01915                 size_t width;
01916                 int has_precision;
01917                 size_t precision;
01918 
01919                 has_width = 0;
01920                 width = 0;
01921                 if (dp->width_start != dp->width_end)
01922                   {
01923                     if (dp->width_arg_index != ARG_NONE)
01924                       {
01925                         int arg;
01926 
01927                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
01928                           abort ();
01929                         arg = a.arg[dp->width_arg_index].a.a_int;
01930                         if (arg < 0)
01931                           {
01932                             /* "A negative field width is taken as a '-' flag
01933                                 followed by a positive field width."  */
01934                             flags |= FLAG_LEFT;
01935                             width = (unsigned int) (-arg);
01936                           }
01937                         else
01938                           width = arg;
01939                       }
01940                     else
01941                       {
01942                         const FCHAR_T *digitp = dp->width_start;
01943 
01944                         do
01945                           width = xsum (xtimes (width, 10), *digitp++ - '0');
01946                         while (digitp != dp->width_end);
01947                       }
01948                     has_width = 1;
01949                   }
01950 
01951                 has_precision = 0;
01952                 precision = 0;
01953                 if (dp->precision_start != dp->precision_end)
01954                   {
01955                     if (dp->precision_arg_index != ARG_NONE)
01956                       {
01957                         int arg;
01958 
01959                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
01960                           abort ();
01961                         arg = a.arg[dp->precision_arg_index].a.a_int;
01962                         /* "A negative precision is taken as if the precision
01963                             were omitted."  */
01964                         if (arg >= 0)
01965                           {
01966                             precision = arg;
01967                             has_precision = 1;
01968                           }
01969                       }
01970                     else
01971                       {
01972                         const FCHAR_T *digitp = dp->precision_start + 1;
01973 
01974                         precision = 0;
01975                         while (digitp != dp->precision_end)
01976                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
01977                         has_precision = 1;
01978                       }
01979                   }
01980 
01981                 switch (type)
01982                   {
01983                   case TYPE_U8_STRING:
01984                     {
01985                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
01986                       const uint8_t *arg_end;
01987                       size_t characters;
01988 
01989                       if (has_precision)
01990                         {
01991                           /* Use only PRECISION characters, from the left.  */
01992                           arg_end = arg;
01993                           characters = 0;
01994                           for (; precision > 0; precision--)
01995                             {
01996                               int count = u8_strmblen (arg_end);
01997                               if (count == 0)
01998                                 break;
01999                               if (count < 0)
02000                                 {
02001                                   if (!(result == resultbuf || result == NULL))
02002                                     free (result);
02003                                   if (buf_malloced != NULL)
02004                                     free (buf_malloced);
02005                                   CLEANUP ();
02006                                   errno = EILSEQ;
02007                                   return NULL;
02008                                 }
02009                               arg_end += count;
02010                               characters++;
02011                             }
02012                         }
02013                       else if (has_width)
02014                         {
02015                           /* Use the entire string, and count the number of
02016                              characters.  */
02017                           arg_end = arg;
02018                           characters = 0;
02019                           for (;;)
02020                             {
02021                               int count = u8_strmblen (arg_end);
02022                               if (count == 0)
02023                                 break;
02024                               if (count < 0)
02025                                 {
02026                                   if (!(result == resultbuf || result == NULL))
02027                                     free (result);
02028                                   if (buf_malloced != NULL)
02029                                     free (buf_malloced);
02030                                   CLEANUP ();
02031                                   errno = EILSEQ;
02032                                   return NULL;
02033                                 }
02034                               arg_end += count;
02035                               characters++;
02036                             }
02037                         }
02038                       else
02039                         {
02040                           /* Use the entire string.  */
02041                           arg_end = arg + u8_strlen (arg);
02042                           /* The number of characters doesn't matter.  */
02043                           characters = 0;
02044                         }
02045 
02046                       if (has_width && width > characters
02047                           && !(dp->flags & FLAG_LEFT))
02048                         {
02049                           size_t n = width - characters;
02050                           ENSURE_ALLOCATION (xsum (length, n));
02051                           DCHAR_SET (result + length, ' ', n);
02052                           length += n;
02053                         }
02054 
02055 # if DCHAR_IS_UINT8_T
02056                       {
02057                         size_t n = arg_end - arg;
02058                         ENSURE_ALLOCATION (xsum (length, n));
02059                         DCHAR_CPY (result + length, arg, n);
02060                         length += n;
02061                       }
02062 # else
02063                       { /* Convert.  */
02064                         DCHAR_T *converted = result + length;
02065                         size_t converted_len = allocated - length;
02066 #  if DCHAR_IS_TCHAR
02067                         /* Convert from UTF-8 to locale encoding.  */
02068                         converted =
02069                           u8_conv_to_encoding (locale_charset (),
02070                                                iconveh_question_mark,
02071                                                arg, arg_end - arg, NULL,
02072                                                converted, &converted_len);
02073 #  else
02074                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
02075                         converted =
02076                           U8_TO_DCHAR (arg, arg_end - arg,
02077                                        converted, &converted_len);
02078 #  endif
02079                         if (converted == NULL)
02080                           {
02081                             int saved_errno = errno;
02082                             if (!(result == resultbuf || result == NULL))
02083                               free (result);
02084                             if (buf_malloced != NULL)
02085                               free (buf_malloced);
02086                             CLEANUP ();
02087                             errno = saved_errno;
02088                             return NULL;
02089                           }
02090                         if (converted != result + length)
02091                           {
02092                             ENSURE_ALLOCATION (xsum (length, converted_len));
02093                             DCHAR_CPY (result + length, converted, converted_len);
02094                             free (converted);
02095                           }
02096                         length += converted_len;
02097                       }
02098 # endif
02099 
02100                       if (has_width && width > characters
02101                           && (dp->flags & FLAG_LEFT))
02102                         {
02103                           size_t n = width - characters;
02104                           ENSURE_ALLOCATION (xsum (length, n));
02105                           DCHAR_SET (result + length, ' ', n);
02106                           length += n;
02107                         }
02108                     }
02109                     break;
02110 
02111                   case TYPE_U16_STRING:
02112                     {
02113                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
02114                       const uint16_t *arg_end;
02115                       size_t characters;
02116 
02117                       if (has_precision)
02118                         {
02119                           /* Use only PRECISION characters, from the left.  */
02120                           arg_end = arg;
02121                           characters = 0;
02122                           for (; precision > 0; precision--)
02123                             {
02124                               int count = u16_strmblen (arg_end);
02125                               if (count == 0)
02126                                 break;
02127                               if (count < 0)
02128                                 {
02129                                   if (!(result == resultbuf || result == NULL))
02130                                     free (result);
02131                                   if (buf_malloced != NULL)
02132                                     free (buf_malloced);
02133                                   CLEANUP ();
02134                                   errno = EILSEQ;
02135                                   return NULL;
02136                                 }
02137                               arg_end += count;
02138                               characters++;
02139                             }
02140                         }
02141                       else if (has_width)
02142                         {
02143                           /* Use the entire string, and count the number of
02144                              characters.  */
02145                           arg_end = arg;
02146                           characters = 0;
02147                           for (;;)
02148                             {
02149                               int count = u16_strmblen (arg_end);
02150                               if (count == 0)
02151                                 break;
02152                               if (count < 0)
02153                                 {
02154                                   if (!(result == resultbuf || result == NULL))
02155                                     free (result);
02156                                   if (buf_malloced != NULL)
02157                                     free (buf_malloced);
02158                                   CLEANUP ();
02159                                   errno = EILSEQ;
02160                                   return NULL;
02161                                 }
02162                               arg_end += count;
02163                               characters++;
02164                             }
02165                         }
02166                       else
02167                         {
02168                           /* Use the entire string.  */
02169                           arg_end = arg + u16_strlen (arg);
02170                           /* The number of characters doesn't matter.  */
02171                           characters = 0;
02172                         }
02173 
02174                       if (has_width && width > characters
02175                           && !(dp->flags & FLAG_LEFT))
02176                         {
02177                           size_t n = width - characters;
02178                           ENSURE_ALLOCATION (xsum (length, n));
02179                           DCHAR_SET (result + length, ' ', n);
02180                           length += n;
02181                         }
02182 
02183 # if DCHAR_IS_UINT16_T
02184                       {
02185                         size_t n = arg_end - arg;
02186                         ENSURE_ALLOCATION (xsum (length, n));
02187                         DCHAR_CPY (result + length, arg, n);
02188                         length += n;
02189                       }
02190 # else
02191                       { /* Convert.  */
02192                         DCHAR_T *converted = result + length;
02193                         size_t converted_len = allocated - length;
02194 #  if DCHAR_IS_TCHAR
02195                         /* Convert from UTF-16 to locale encoding.  */
02196                         converted =
02197                           u16_conv_to_encoding (locale_charset (),
02198                                                 iconveh_question_mark,
02199                                                 arg, arg_end - arg, NULL,
02200                                                 converted, &converted_len);
02201 #  else
02202                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
02203                         converted =
02204                           U16_TO_DCHAR (arg, arg_end - arg,
02205                                         converted, &converted_len);
02206 #  endif
02207                         if (converted == NULL)
02208                           {
02209                             int saved_errno = errno;
02210                             if (!(result == resultbuf || result == NULL))
02211                               free (result);
02212                             if (buf_malloced != NULL)
02213                               free (buf_malloced);
02214                             CLEANUP ();
02215                             errno = saved_errno;
02216                             return NULL;
02217                           }
02218                         if (converted != result + length)
02219                           {
02220                             ENSURE_ALLOCATION (xsum (length, converted_len));
02221                             DCHAR_CPY (result + length, converted, converted_len);
02222                             free (converted);
02223                           }
02224                         length += converted_len;
02225                       }
02226 # endif
02227 
02228                       if (has_width && width > characters
02229                           && (dp->flags & FLAG_LEFT))
02230                         {
02231                           size_t n = width - characters;
02232                           ENSURE_ALLOCATION (xsum (length, n));
02233                           DCHAR_SET (result + length, ' ', n);
02234                           length += n;
02235                         }
02236                     }
02237                     break;
02238 
02239                   case TYPE_U32_STRING:
02240                     {
02241                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
02242                       const uint32_t *arg_end;
02243                       size_t characters;
02244 
02245                       if (has_precision)
02246                         {
02247                           /* Use only PRECISION characters, from the left.  */
02248                           arg_end = arg;
02249                           characters = 0;
02250                           for (; precision > 0; precision--)
02251                             {
02252                               int count = u32_strmblen (arg_end);
02253                               if (count == 0)
02254                                 break;
02255                               if (count < 0)
02256                                 {
02257                                   if (!(result == resultbuf || result == NULL))
02258                                     free (result);
02259                                   if (buf_malloced != NULL)
02260                                     free (buf_malloced);
02261                                   CLEANUP ();
02262                                   errno = EILSEQ;
02263                                   return NULL;
02264                                 }
02265                               arg_end += count;
02266                               characters++;
02267                             }
02268                         }
02269                       else if (has_width)
02270                         {
02271                           /* Use the entire string, and count the number of
02272                              characters.  */
02273                           arg_end = arg;
02274                           characters = 0;
02275                           for (;;)
02276                             {
02277                               int count = u32_strmblen (arg_end);
02278                               if (count == 0)
02279                                 break;
02280                               if (count < 0)
02281                                 {
02282                                   if (!(result == resultbuf || result == NULL))
02283                                     free (result);
02284                                   if (buf_malloced != NULL)
02285                                     free (buf_malloced);
02286                                   CLEANUP ();
02287                                   errno = EILSEQ;
02288                                   return NULL;
02289                                 }
02290                               arg_end += count;
02291                               characters++;
02292                             }
02293                         }
02294                       else
02295                         {
02296                           /* Use the entire string.  */
02297                           arg_end = arg + u32_strlen (arg);
02298                           /* The number of characters doesn't matter.  */
02299                           characters = 0;
02300                         }
02301 
02302                       if (has_width && width > characters
02303                           && !(dp->flags & FLAG_LEFT))
02304                         {
02305                           size_t n = width - characters;
02306                           ENSURE_ALLOCATION (xsum (length, n));
02307                           DCHAR_SET (result + length, ' ', n);
02308                           length += n;
02309                         }
02310 
02311 # if DCHAR_IS_UINT32_T
02312                       {
02313                         size_t n = arg_end - arg;
02314                         ENSURE_ALLOCATION (xsum (length, n));
02315                         DCHAR_CPY (result + length, arg, n);
02316                         length += n;
02317                       }
02318 # else
02319                       { /* Convert.  */
02320                         DCHAR_T *converted = result + length;
02321                         size_t converted_len = allocated - length;
02322 #  if DCHAR_IS_TCHAR
02323                         /* Convert from UTF-32 to locale encoding.  */
02324                         converted =
02325                           u32_conv_to_encoding (locale_charset (),
02326                                                 iconveh_question_mark,
02327                                                 arg, arg_end - arg, NULL,
02328                                                 converted, &converted_len);
02329 #  else
02330                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
02331                         converted =
02332                           U32_TO_DCHAR (arg, arg_end - arg,
02333                                         converted, &converted_len);
02334 #  endif
02335                         if (converted == NULL)
02336                           {
02337                             int saved_errno = errno;
02338                             if (!(result == resultbuf || result == NULL))
02339                               free (result);
02340                             if (buf_malloced != NULL)
02341                               free (buf_malloced);
02342                             CLEANUP ();
02343                             errno = saved_errno;
02344                             return NULL;
02345                           }
02346                         if (converted != result + length)
02347                           {
02348                             ENSURE_ALLOCATION (xsum (length, converted_len));
02349                             DCHAR_CPY (result + length, converted, converted_len);
02350                             free (converted);
02351                           }
02352                         length += converted_len;
02353                       }
02354 # endif
02355 
02356                       if (has_width && width > characters
02357                           && (dp->flags & FLAG_LEFT))
02358                         {
02359                           size_t n = width - characters;
02360                           ENSURE_ALLOCATION (xsum (length, n));
02361                           DCHAR_SET (result + length, ' ', n);
02362                           length += n;
02363                         }
02364                     }
02365                     break;
02366 
02367                   default:
02368                     abort ();
02369                   }
02370               }
02371 #endif
02372 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
02373             else if (dp->conversion == 's'
02374 # if WIDE_CHAR_VERSION
02375                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
02376 # else
02377                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
02378 # endif
02379                     )
02380               {
02381                 /* The normal handling of the 's' directive below requires
02382                    allocating a temporary buffer.  The determination of its
02383                    length (tmp_length), in the case when a precision is
02384                    specified, below requires a conversion between a char[]
02385                    string and a wchar_t[] wide string.  It could be done, but
02386                    we have no guarantee that the implementation of sprintf will
02387                    use the exactly same algorithm.  Without this guarantee, it
02388                    is possible to have buffer overrun bugs.  In order to avoid
02389                    such bugs, we implement the entire processing of the 's'
02390                    directive ourselves.  */
02391                 int flags = dp->flags;
02392                 int has_width;
02393                 size_t width;
02394                 int has_precision;
02395                 size_t precision;
02396 
02397                 has_width = 0;
02398                 width = 0;
02399                 if (dp->width_start != dp->width_end)
02400                   {
02401                     if (dp->width_arg_index != ARG_NONE)
02402                       {
02403                         int arg;
02404 
02405                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
02406                           abort ();
02407                         arg = a.arg[dp->width_arg_index].a.a_int;
02408                         if (arg < 0)
02409                           {
02410                             /* "A negative field width is taken as a '-' flag
02411                                 followed by a positive field width."  */
02412                             flags |= FLAG_LEFT;
02413                             width = (unsigned int) (-arg);
02414                           }
02415                         else
02416                           width = arg;
02417                       }
02418                     else
02419                       {
02420                         const FCHAR_T *digitp = dp->width_start;
02421 
02422                         do
02423                           width = xsum (xtimes (width, 10), *digitp++ - '0');
02424                         while (digitp != dp->width_end);
02425                       }
02426                     has_width = 1;
02427                   }
02428 
02429                 has_precision = 0;
02430                 precision = 6;
02431                 if (dp->precision_start != dp->precision_end)
02432                   {
02433                     if (dp->precision_arg_index != ARG_NONE)
02434                       {
02435                         int arg;
02436 
02437                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
02438                           abort ();
02439                         arg = a.arg[dp->precision_arg_index].a.a_int;
02440                         /* "A negative precision is taken as if the precision
02441                             were omitted."  */
02442                         if (arg >= 0)
02443                           {
02444                             precision = arg;
02445                             has_precision = 1;
02446                           }
02447                       }
02448                     else
02449                       {
02450                         const FCHAR_T *digitp = dp->precision_start + 1;
02451 
02452                         precision = 0;
02453                         while (digitp != dp->precision_end)
02454                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
02455                         has_precision = 1;
02456                       }
02457                   }
02458 
02459 # if WIDE_CHAR_VERSION
02460                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
02461                 {
02462                   const char *arg = a.arg[dp->arg_index].a.a_string;
02463                   const char *arg_end;
02464                   size_t characters;
02465 
02466                   if (has_precision)
02467                     {
02468                       /* Use only as many bytes as needed to produce PRECISION
02469                          wide characters, from the left.  */
02470 #  if HAVE_MBRTOWC
02471                       mbstate_t state;
02472                       memset (&state, '\0', sizeof (mbstate_t));
02473 #  endif
02474                       arg_end = arg;
02475                       characters = 0;
02476                       for (; precision > 0; precision--)
02477                         {
02478                           int count;
02479 #  if HAVE_MBRTOWC
02480                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
02481 #  else
02482                           count = mblen (arg_end, MB_CUR_MAX);
02483 #  endif
02484                           if (count == 0)
02485                             /* Found the terminating NUL.  */
02486                             break;
02487                           if (count < 0)
02488                             {
02489                               /* Invalid or incomplete multibyte character.  */
02490                               if (!(result == resultbuf || result == NULL))
02491                                 free (result);
02492                               if (buf_malloced != NULL)
02493                                 free (buf_malloced);
02494                               CLEANUP ();
02495                               errno = EILSEQ;
02496                               return NULL;
02497                             }
02498                           arg_end += count;
02499                           characters++;
02500                         }
02501                     }
02502                   else if (has_width)
02503                     {
02504                       /* Use the entire string, and count the number of wide
02505                          characters.  */
02506 #  if HAVE_MBRTOWC
02507                       mbstate_t state;
02508                       memset (&state, '\0', sizeof (mbstate_t));
02509 #  endif
02510                       arg_end = arg;
02511                       characters = 0;
02512                       for (;;)
02513                         {
02514                           int count;
02515 #  if HAVE_MBRTOWC
02516                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
02517 #  else
02518                           count = mblen (arg_end, MB_CUR_MAX);
02519 #  endif
02520                           if (count == 0)
02521                             /* Found the terminating NUL.  */
02522                             break;
02523                           if (count < 0)
02524                             {
02525                               /* Invalid or incomplete multibyte character.  */
02526                               if (!(result == resultbuf || result == NULL))
02527                                 free (result);
02528                               if (buf_malloced != NULL)
02529                                 free (buf_malloced);
02530                               CLEANUP ();
02531                               errno = EILSEQ;
02532                               return NULL;
02533                             }
02534                           arg_end += count;
02535                           characters++;
02536                         }
02537                     }
02538                   else
02539                     {
02540                       /* Use the entire string.  */
02541                       arg_end = arg + strlen (arg);
02542                       /* The number of characters doesn't matter.  */
02543                       characters = 0;
02544                     }
02545 
02546                   if (has_width && width > characters
02547                       && !(dp->flags & FLAG_LEFT))
02548                     {
02549                       size_t n = width - characters;
02550                       ENSURE_ALLOCATION (xsum (length, n));
02551                       DCHAR_SET (result + length, ' ', n);
02552                       length += n;
02553                     }
02554 
02555                   if (has_precision || has_width)
02556                     {
02557                       /* We know the number of wide characters in advance.  */
02558                       size_t remaining;
02559 #  if HAVE_MBRTOWC
02560                       mbstate_t state;
02561                       memset (&state, '\0', sizeof (mbstate_t));
02562 #  endif
02563                       ENSURE_ALLOCATION (xsum (length, characters));
02564                       for (remaining = characters; remaining > 0; remaining--)
02565                         {
02566                           wchar_t wc;
02567                           int count;
02568 #  if HAVE_MBRTOWC
02569                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
02570 #  else
02571                           count = mbtowc (&wc, arg, arg_end - arg);
02572 #  endif
02573                           if (count <= 0)
02574                             /* mbrtowc not consistent with mbrlen, or mbtowc
02575                                not consistent with mblen.  */
02576                             abort ();
02577                           result[length++] = wc;
02578                           arg += count;
02579                         }
02580                       if (!(arg == arg_end))
02581                         abort ();
02582                     }
02583                   else
02584                     {
02585 #  if HAVE_MBRTOWC
02586                       mbstate_t state;
02587                       memset (&state, '\0', sizeof (mbstate_t));
02588 #  endif
02589                       while (arg < arg_end)
02590                         {
02591                           wchar_t wc;
02592                           int count;
02593 #  if HAVE_MBRTOWC
02594                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
02595 #  else
02596                           count = mbtowc (&wc, arg, arg_end - arg);
02597 #  endif
02598                           if (count <= 0)
02599                             /* mbrtowc not consistent with mbrlen, or mbtowc
02600                                not consistent with mblen.  */
02601                             abort ();
02602                           ENSURE_ALLOCATION (xsum (length, 1));
02603                           result[length++] = wc;
02604                           arg += count;
02605                         }
02606                     }
02607 
02608                   if (has_width && width > characters
02609                       && (dp->flags & FLAG_LEFT))
02610                     {
02611                       size_t n = width - characters;
02612                       ENSURE_ALLOCATION (xsum (length, n));
02613                       DCHAR_SET (result + length, ' ', n);
02614                       length += n;
02615                     }
02616                 }
02617 # else
02618                 /* %ls in vasnprintf.  See the specification of fprintf.  */
02619                 {
02620                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
02621                   const wchar_t *arg_end;
02622                   size_t characters;
02623 #  if !DCHAR_IS_TCHAR
02624                   /* This code assumes that TCHAR_T is 'char'.  */
02625                   typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1];
02626                   TCHAR_T *tmpsrc;
02627                   DCHAR_T *tmpdst;
02628                   size_t tmpdst_len;
02629 #  endif
02630                   size_t w;
02631 
02632                   if (has_precision)
02633                     {
02634                       /* Use only as many wide characters as needed to produce
02635                          at most PRECISION bytes, from the left.  */
02636 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02637                       mbstate_t state;
02638                       memset (&state, '\0', sizeof (mbstate_t));
02639 #  endif
02640                       arg_end = arg;
02641                       characters = 0;
02642                       while (precision > 0)
02643                         {
02644                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
02645                           int count;
02646 
02647                           if (*arg_end == 0)
02648                             /* Found the terminating null wide character.  */
02649                             break;
02650 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02651                           count = wcrtomb (cbuf, *arg_end, &state);
02652 #  else
02653                           count = wctomb (cbuf, *arg_end);
02654 #  endif
02655                           if (count < 0)
02656                             {
02657                               /* Cannot convert.  */
02658                               if (!(result == resultbuf || result == NULL))
02659                                 free (result);
02660                               if (buf_malloced != NULL)
02661                                 free (buf_malloced);
02662                               CLEANUP ();
02663                               errno = EILSEQ;
02664                               return NULL;
02665                             }
02666                           if (precision < count)
02667                             break;
02668                           arg_end++;
02669                           characters += count;
02670                           precision -= count;
02671                         }
02672                     }
02673 #  if DCHAR_IS_TCHAR
02674                   else if (has_width)
02675 #  else
02676                   else
02677 #  endif
02678                     {
02679                       /* Use the entire string, and count the number of
02680                          bytes.  */
02681 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02682                       mbstate_t state;
02683                       memset (&state, '\0', sizeof (mbstate_t));
02684 #  endif
02685                       arg_end = arg;
02686                       characters = 0;
02687                       for (;;)
02688                         {
02689                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
02690                           int count;
02691 
02692                           if (*arg_end == 0)
02693                             /* Found the terminating null wide character.  */
02694                             break;
02695 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02696                           count = wcrtomb (cbuf, *arg_end, &state);
02697 #  else
02698                           count = wctomb (cbuf, *arg_end);
02699 #  endif
02700                           if (count < 0)
02701                             {
02702                               /* Cannot convert.  */
02703                               if (!(result == resultbuf || result == NULL))
02704                                 free (result);
02705                               if (buf_malloced != NULL)
02706                                 free (buf_malloced);
02707                               CLEANUP ();
02708                               errno = EILSEQ;
02709                               return NULL;
02710                             }
02711                           arg_end++;
02712                           characters += count;
02713                         }
02714                     }
02715 #  if DCHAR_IS_TCHAR
02716                   else
02717                     {
02718                       /* Use the entire string.  */
02719                       arg_end = arg + local_wcslen (arg);
02720                       /* The number of bytes doesn't matter.  */
02721                       characters = 0;
02722                     }
02723 #  endif
02724 
02725 #  if !DCHAR_IS_TCHAR
02726                   /* Convert the string into a piece of temporary memory.  */
02727                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
02728                   if (tmpsrc == NULL)
02729                     goto out_of_memory;
02730                   {
02731                     TCHAR_T *tmpptr = tmpsrc;
02732                     size_t remaining;
02733 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02734                     mbstate_t state;
02735                     memset (&state, '\0', sizeof (mbstate_t));
02736 #   endif
02737                     for (remaining = characters; remaining > 0; )
02738                       {
02739                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
02740                         int count;
02741 
02742                         if (*arg == 0)
02743                           abort ();
02744 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02745                         count = wcrtomb (cbuf, *arg, &state);
02746 #   else
02747                         count = wctomb (cbuf, *arg);
02748 #   endif
02749                         if (count <= 0)
02750                           /* Inconsistency.  */
02751                           abort ();
02752                         memcpy (tmpptr, cbuf, count);
02753                         tmpptr += count;
02754                         arg++;
02755                         remaining -= count;
02756                       }
02757                     if (!(arg == arg_end))
02758                       abort ();
02759                   }
02760 
02761                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
02762                   tmpdst =
02763                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
02764                                               iconveh_question_mark,
02765                                               tmpsrc, characters,
02766                                               NULL,
02767                                               NULL, &tmpdst_len);
02768                   if (tmpdst == NULL)
02769                     {
02770                       int saved_errno = errno;
02771                       free (tmpsrc);
02772                       if (!(result == resultbuf || result == NULL))
02773                         free (result);
02774                       if (buf_malloced != NULL)
02775                         free (buf_malloced);
02776                       CLEANUP ();
02777                       errno = saved_errno;
02778                       return NULL;
02779                     }
02780                   free (tmpsrc);
02781 #  endif
02782 
02783                   if (has_width)
02784                     {
02785 #  if ENABLE_UNISTDIO
02786                       /* Outside POSIX, it's preferrable to compare the width
02787                          against the number of _characters_ of the converted
02788                          value.  */
02789                       w = DCHAR_MBSNLEN (result + length, characters);
02790 #  else
02791                       /* The width is compared against the number of _bytes_
02792                          of the converted value, says POSIX.  */
02793                       w = characters;
02794 #  endif
02795                     }
02796                   else
02797                     /* w doesn't matter.  */
02798                     w = 0;
02799 
02800                   if (has_width && width > w
02801                       && !(dp->flags & FLAG_LEFT))
02802                     {
02803                       size_t n = width - w;
02804                       ENSURE_ALLOCATION (xsum (length, n));
02805                       DCHAR_SET (result + length, ' ', n);
02806                       length += n;
02807                     }
02808 
02809 #  if DCHAR_IS_TCHAR
02810                   if (has_precision || has_width)
02811                     {
02812                       /* We know the number of bytes in advance.  */
02813                       size_t remaining;
02814 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02815                       mbstate_t state;
02816                       memset (&state, '\0', sizeof (mbstate_t));
02817 #   endif
02818                       ENSURE_ALLOCATION (xsum (length, characters));
02819                       for (remaining = characters; remaining > 0; )
02820                         {
02821                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
02822                           int count;
02823 
02824                           if (*arg == 0)
02825                             abort ();
02826 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02827                           count = wcrtomb (cbuf, *arg, &state);
02828 #   else
02829                           count = wctomb (cbuf, *arg);
02830 #   endif
02831                           if (count <= 0)
02832                             /* Inconsistency.  */
02833                             abort ();
02834                           memcpy (result + length, cbuf, count);
02835                           length += count;
02836                           arg++;
02837                           remaining -= count;
02838                         }
02839                       if (!(arg == arg_end))
02840                         abort ();
02841                     }
02842                   else
02843                     {
02844 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02845                       mbstate_t state;
02846                       memset (&state, '\0', sizeof (mbstate_t));
02847 #   endif
02848                       while (arg < arg_end)
02849                         {
02850                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
02851                           int count;
02852 
02853                           if (*arg == 0)
02854                             abort ();
02855 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
02856                           count = wcrtomb (cbuf, *arg, &state);
02857 #   else
02858                           count = wctomb (cbuf, *arg);
02859 #   endif
02860                           if (count <= 0)
02861                             {
02862                               /* Cannot convert.  */
02863                               if (!(result == resultbuf || result == NULL))
02864                                 free (result);
02865                               if (buf_malloced != NULL)
02866                                 free (buf_malloced);
02867                               CLEANUP ();
02868                               errno = EILSEQ;
02869                               return NULL;
02870                             }
02871                           ENSURE_ALLOCATION (xsum (length, count));
02872                           memcpy (result + length, cbuf, count);
02873                           length += count;
02874                           arg++;
02875                         }
02876                     }
02877 #  else
02878                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
02879                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
02880                   free (tmpdst);
02881                   length += tmpdst_len;
02882 #  endif
02883 
02884                   if (has_width && width > w
02885                       && (dp->flags & FLAG_LEFT))
02886                     {
02887                       size_t n = width - w;
02888                       ENSURE_ALLOCATION (xsum (length, n));
02889                       DCHAR_SET (result + length, ' ', n);
02890                       length += n;
02891                     }
02892                 }
02893 # endif
02894               }
02895 #endif
02896 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
02897             else if ((dp->conversion == 'a' || dp->conversion == 'A')
02898 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
02899                      && (0
02900 #  if NEED_PRINTF_DOUBLE
02901                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
02902 #  endif
02903 #  if NEED_PRINTF_LONG_DOUBLE
02904                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
02905 #  endif
02906                         )
02907 # endif
02908                     )
02909               {
02910                 arg_type type = a.arg[dp->arg_index].type;
02911                 int flags = dp->flags;
02912                 int has_width;
02913                 size_t width;
02914                 int has_precision;
02915                 size_t precision;
02916                 size_t tmp_length;
02917                 DCHAR_T tmpbuf[700];
02918                 DCHAR_T *tmp;
02919                 DCHAR_T *pad_ptr;
02920                 DCHAR_T *p;
02921 
02922                 has_width = 0;
02923                 width = 0;
02924                 if (dp->width_start != dp->width_end)
02925                   {
02926                     if (dp->width_arg_index != ARG_NONE)
02927                       {
02928                         int arg;
02929 
02930                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
02931                           abort ();
02932                         arg = a.arg[dp->width_arg_index].a.a_int;
02933                         if (arg < 0)
02934                           {
02935                             /* "A negative field width is taken as a '-' flag
02936                                 followed by a positive field width."  */
02937                             flags |= FLAG_LEFT;
02938                             width = (unsigned int) (-arg);
02939                           }
02940                         else
02941                           width = arg;
02942                       }
02943                     else
02944                       {
02945                         const FCHAR_T *digitp = dp->width_start;
02946 
02947                         do
02948                           width = xsum (xtimes (width, 10), *digitp++ - '0');
02949                         while (digitp != dp->width_end);
02950                       }
02951                     has_width = 1;
02952                   }
02953 
02954                 has_precision = 0;
02955                 precision = 0;
02956                 if (dp->precision_start != dp->precision_end)
02957                   {
02958                     if (dp->precision_arg_index != ARG_NONE)
02959                       {
02960                         int arg;
02961 
02962                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
02963                           abort ();
02964                         arg = a.arg[dp->precision_arg_index].a.a_int;
02965                         /* "A negative precision is taken as if the precision
02966                             were omitted."  */
02967                         if (arg >= 0)
02968                           {
02969                             precision = arg;
02970                             has_precision = 1;
02971                           }
02972                       }
02973                     else
02974                       {
02975                         const FCHAR_T *digitp = dp->precision_start + 1;
02976 
02977                         precision = 0;
02978                         while (digitp != dp->precision_end)
02979                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
02980                         has_precision = 1;
02981                       }
02982                   }
02983 
02984                 /* Allocate a temporary buffer of sufficient size.  */
02985                 if (type == TYPE_LONGDOUBLE)
02986                   tmp_length =
02987                     (unsigned int) ((LDBL_DIG + 1)
02988                                     * 0.831 /* decimal -> hexadecimal */
02989                                    )
02990                     + 1; /* turn floor into ceil */
02991                 else
02992                   tmp_length =
02993                     (unsigned int) ((DBL_DIG + 1)
02994                                     * 0.831 /* decimal -> hexadecimal */
02995                                    )
02996                     + 1; /* turn floor into ceil */
02997                 if (tmp_length < precision)
02998                   tmp_length = precision;
02999                 /* Account for sign, decimal point etc. */
03000                 tmp_length = xsum (tmp_length, 12);
03001 
03002                 if (tmp_length < width)
03003                   tmp_length = width;
03004 
03005                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
03006 
03007                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
03008                   tmp = tmpbuf;
03009                 else
03010                   {
03011                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
03012 
03013                     if (size_overflow_p (tmp_memsize))
03014                       /* Overflow, would lead to out of memory.  */
03015                       goto out_of_memory;
03016                     tmp = (DCHAR_T *) malloc (tmp_memsize);
03017                     if (tmp == NULL)
03018                       /* Out of memory.  */
03019                       goto out_of_memory;
03020                   }
03021 
03022                 pad_ptr = NULL;
03023                 p = tmp;
03024                 if (type == TYPE_LONGDOUBLE)
03025                   {
03026 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
03027                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
03028 
03029                     if (isnanl (arg))
03030                       {
03031                         if (dp->conversion == 'A')
03032                           {
03033                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
03034                           }
03035                         else
03036                           {
03037                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
03038                           }
03039                       }
03040                     else
03041                       {
03042                         int sign = 0;
03043                         DECL_LONG_DOUBLE_ROUNDING
03044 
03045                         BEGIN_LONG_DOUBLE_ROUNDING ();
03046 
03047                         if (signbit (arg)) /* arg < 0.0L or negative zero */
03048                           {
03049                             sign = -1;
03050                             arg = -arg;
03051                           }
03052 
03053                         if (sign < 0)
03054                           *p++ = '-';
03055                         else if (flags & FLAG_SHOWSIGN)
03056                           *p++ = '+';
03057                         else if (flags & FLAG_SPACE)
03058                           *p++ = ' ';
03059 
03060                         if (arg > 0.0L && arg + arg == arg)
03061                           {
03062                             if (dp->conversion == 'A')
03063                               {
03064                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
03065                               }
03066                             else
03067                               {
03068                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
03069                               }
03070                           }
03071                         else
03072                           {
03073                             int exponent;
03074                             long double mantissa;
03075 
03076                             if (arg > 0.0L)
03077                               mantissa = printf_frexpl (arg, &exponent);
03078                             else
03079                               {
03080                                 exponent = 0;
03081                                 mantissa = 0.0L;
03082                               }
03083 
03084                             if (has_precision
03085                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
03086                               {
03087                                 /* Round the mantissa.  */
03088                                 long double tail = mantissa;
03089                                 size_t q;
03090 
03091                                 for (q = precision; ; q--)
03092                                   {
03093                                     int digit = (int) tail;
03094                                     tail -= digit;
03095                                     if (q == 0)
03096                                       {
03097                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
03098                                           tail = 1 - tail;
03099                                         else
03100                                           tail = - tail;
03101                                         break;
03102                                       }
03103                                     tail *= 16.0L;
03104                                   }
03105                                 if (tail != 0.0L)
03106                                   for (q = precision; q > 0; q--)
03107                                     tail *= 0.0625L;
03108                                 mantissa += tail;
03109                               }
03110 
03111                             *p++ = '0';
03112                             *p++ = dp->conversion - 'A' + 'X';
03113                             pad_ptr = p;
03114                             {
03115                               int digit;
03116 
03117                               digit = (int) mantissa;
03118                               mantissa -= digit;
03119                               *p++ = '0' + digit;
03120                               if ((flags & FLAG_ALT)
03121                                   || mantissa > 0.0L || precision > 0)
03122                                 {
03123                                   *p++ = decimal_point_char ();
03124                                   /* This loop terminates because we assume
03125                                      that FLT_RADIX is a power of 2.  */
03126                                   while (mantissa > 0.0L)
03127                                     {
03128                                       mantissa *= 16.0L;
03129                                       digit = (int) mantissa;
03130                                       mantissa -= digit;
03131                                       *p++ = digit
03132                                              + (digit < 10
03133                                                 ? '0'
03134                                                 : dp->conversion - 10);
03135                                       if (precision > 0)
03136                                         precision--;
03137                                     }
03138                                   while (precision > 0)
03139                                     {
03140                                       *p++ = '0';
03141                                       precision--;
03142                                     }
03143                                 }
03144                               }
03145                               *p++ = dp->conversion - 'A' + 'P';
03146 #  if WIDE_CHAR_VERSION
03147                               {
03148                                 static const wchar_t decimal_format[] =
03149                                   { '%', '+', 'd', '\0' };
03150                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
03151                               }
03152                               while (*p != '\0')
03153                                 p++;
03154 #  else
03155                               if (sizeof (DCHAR_T) == 1)
03156                                 {
03157                                   sprintf ((char *) p, "%+d", exponent);
03158                                   while (*p != '\0')
03159                                     p++;
03160                                 }
03161                               else
03162                                 {
03163                                   char expbuf[6 + 1];
03164                                   const char *ep;
03165                                   sprintf (expbuf, "%+d", exponent);
03166                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
03167                                     p++;
03168                                 }
03169 #  endif
03170                           }
03171 
03172                         END_LONG_DOUBLE_ROUNDING ();
03173                       }
03174 # else
03175                     abort ();
03176 # endif
03177                   }
03178                 else
03179                   {
03180 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
03181                     double arg = a.arg[dp->arg_index].a.a_double;
03182 
03183                     if (isnand (arg))
03184                       {
03185                         if (dp->conversion == 'A')
03186                           {
03187                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
03188                           }
03189                         else
03190                           {
03191                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
03192                           }
03193                       }
03194                     else
03195                       {
03196                         int sign = 0;
03197 
03198                         if (signbit (arg)) /* arg < 0.0 or negative zero */
03199                           {
03200                             sign = -1;
03201                             arg = -arg;
03202                           }
03203 
03204                         if (sign < 0)
03205                           *p++ = '-';
03206                         else if (flags & FLAG_SHOWSIGN)
03207                           *p++ = '+';
03208                         else if (flags & FLAG_SPACE)
03209                           *p++ = ' ';
03210 
03211                         if (arg > 0.0 && arg + arg == arg)
03212                           {
03213                             if (dp->conversion == 'A')
03214                               {
03215                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
03216                               }
03217                             else
03218                               {
03219                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
03220                               }
03221                           }
03222                         else
03223                           {
03224                             int exponent;
03225                             double mantissa;
03226 
03227                             if (arg > 0.0)
03228                               mantissa = printf_frexp (arg, &exponent);
03229                             else
03230                               {
03231                                 exponent = 0;
03232                                 mantissa = 0.0;
03233                               }
03234 
03235                             if (has_precision
03236                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
03237                               {
03238                                 /* Round the mantissa.  */
03239                                 double tail = mantissa;
03240                                 size_t q;
03241 
03242                                 for (q = precision; ; q--)
03243                                   {
03244                                     int digit = (int) tail;
03245                                     tail -= digit;
03246                                     if (q == 0)
03247                                       {
03248                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
03249                                           tail = 1 - tail;
03250                                         else
03251                                           tail = - tail;
03252                                         break;
03253                                       }
03254                                     tail *= 16.0;
03255                                   }
03256                                 if (tail != 0.0)
03257                                   for (q = precision; q > 0; q--)
03258                                     tail *= 0.0625;
03259                                 mantissa += tail;
03260                               }
03261 
03262                             *p++ = '0';
03263                             *p++ = dp->conversion - 'A' + 'X';
03264                             pad_ptr = p;
03265                             {
03266                               int digit;
03267 
03268                               digit = (int) mantissa;
03269                               mantissa -= digit;
03270                               *p++ = '0' + digit;
03271                               if ((flags & FLAG_ALT)
03272                                   || mantissa > 0.0 || precision > 0)
03273                                 {
03274                                   *p++ = decimal_point_char ();
03275                                   /* This loop terminates because we assume
03276                                      that FLT_RADIX is a power of 2.  */
03277                                   while (mantissa > 0.0)
03278                                     {
03279                                       mantissa *= 16.0;
03280                                       digit = (int) mantissa;
03281                                       mantissa -= digit;
03282                                       *p++ = digit
03283                                              + (digit < 10
03284                                                 ? '0'
03285                                                 : dp->conversion - 10);
03286                                       if (precision > 0)
03287                                         precision--;
03288                                     }
03289                                   while (precision > 0)
03290                                     {
03291                                       *p++ = '0';
03292                                       precision--;
03293                                     }
03294                                 }
03295                               }
03296                               *p++ = dp->conversion - 'A' + 'P';
03297 #  if WIDE_CHAR_VERSION
03298                               {
03299                                 static const wchar_t decimal_format[] =
03300                                   { '%', '+', 'd', '\0' };
03301                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
03302                               }
03303                               while (*p != '\0')
03304                                 p++;
03305 #  else
03306                               if (sizeof (DCHAR_T) == 1)
03307                                 {
03308                                   sprintf ((char *) p, "%+d", exponent);
03309                                   while (*p != '\0')
03310                                     p++;
03311                                 }
03312                               else
03313                                 {
03314                                   char expbuf[6 + 1];
03315                                   const char *ep;
03316                                   sprintf (expbuf, "%+d", exponent);
03317                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
03318                                     p++;
03319                                 }
03320 #  endif
03321                           }
03322                       }
03323 # else
03324                     abort ();
03325 # endif
03326                   }
03327                 /* The generated string now extends from tmp to p, with the
03328                    zero padding insertion point being at pad_ptr.  */
03329                 if (has_width && p - tmp < width)
03330                   {
03331                     size_t pad = width - (p - tmp);
03332                     DCHAR_T *end = p + pad;
03333 
03334                     if (flags & FLAG_LEFT)
03335                       {
03336                         /* Pad with spaces on the right.  */
03337                         for (; pad > 0; pad--)
03338                           *p++ = ' ';
03339                       }
03340                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
03341                       {
03342                         /* Pad with zeroes.  */
03343                         DCHAR_T *q = end;
03344 
03345                         while (p > pad_ptr)
03346                           *--q = *--p;
03347                         for (; pad > 0; pad--)
03348                           *p++ = '0';
03349                       }
03350                     else
03351                       {
03352                         /* Pad with spaces on the left.  */
03353                         DCHAR_T *q = end;
03354 
03355                         while (p > tmp)
03356                           *--q = *--p;
03357                         for (; pad > 0; pad--)
03358                           *p++ = ' ';
03359                       }
03360 
03361                     p = end;
03362                   }
03363 
03364                 {
03365                   size_t count = p - tmp;
03366 
03367                   if (count >= tmp_length)
03368                     /* tmp_length was incorrectly calculated - fix the
03369                        code above!  */
03370                     abort ();
03371 
03372                   /* Make room for the result.  */
03373                   if (count >= allocated - length)
03374                     {
03375                       size_t n = xsum (length, count);
03376 
03377                       ENSURE_ALLOCATION (n);
03378                     }
03379 
03380                   /* Append the result.  */
03381                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
03382                   if (tmp != tmpbuf)
03383                     free (tmp);
03384                   length += count;
03385                 }
03386               }
03387 #endif
03388 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
03389             else if ((dp->conversion == 'f' || dp->conversion == 'F'
03390                       || dp->conversion == 'e' || dp->conversion == 'E'
03391                       || dp->conversion == 'g' || dp->conversion == 'G'
03392                       || dp->conversion == 'a' || dp->conversion == 'A')
03393                      && (0
03394 # if NEED_PRINTF_DOUBLE
03395                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
03396 # elif NEED_PRINTF_INFINITE_DOUBLE
03397                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
03398                              /* The systems (mingw) which produce wrong output
03399                                 for Inf, -Inf, and NaN also do so for -0.0.
03400                                 Therefore we treat this case here as well.  */
03401                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
03402 # endif
03403 # if NEED_PRINTF_LONG_DOUBLE
03404                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
03405 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
03406                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
03407                              /* Some systems produce wrong output for Inf,
03408                                 -Inf, and NaN.  Some systems in this category
03409                                 (IRIX 5.3) also do so for -0.0.  Therefore we
03410                                 treat this case here as well.  */
03411                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
03412 # endif
03413                         ))
03414               {
03415 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
03416                 arg_type type = a.arg[dp->arg_index].type;
03417 # endif
03418                 int flags = dp->flags;
03419                 int has_width;
03420                 size_t width;
03421                 int has_precision;
03422                 size_t precision;
03423                 size_t tmp_length;
03424                 DCHAR_T tmpbuf[700];
03425                 DCHAR_T *tmp;
03426                 DCHAR_T *pad_ptr;
03427                 DCHAR_T *p;
03428 
03429                 has_width = 0;
03430                 width = 0;
03431                 if (dp->width_start != dp->width_end)
03432                   {
03433                     if (dp->width_arg_index != ARG_NONE)
03434                       {
03435                         int arg;
03436 
03437                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
03438                           abort ();
03439                         arg = a.arg[dp->width_arg_index].a.a_int;
03440                         if (arg < 0)
03441                           {
03442                             /* "A negative field width is taken as a '-' flag
03443                                 followed by a positive field width."  */
03444                             flags |= FLAG_LEFT;
03445                             width = (unsigned int) (-arg);
03446                           }
03447                         else
03448                           width = arg;
03449                       }
03450                     else
03451                       {
03452                         const FCHAR_T *digitp = dp->width_start;
03453 
03454                         do
03455                           width = xsum (xtimes (width, 10), *digitp++ - '0');
03456                         while (digitp != dp->width_end);
03457                       }
03458                     has_width = 1;
03459                   }
03460 
03461                 has_precision = 0;
03462                 precision = 0;
03463                 if (dp->precision_start != dp->precision_end)
03464                   {
03465                     if (dp->precision_arg_index != ARG_NONE)
03466                       {
03467                         int arg;
03468 
03469                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
03470                           abort ();
03471                         arg = a.arg[dp->precision_arg_index].a.a_int;
03472                         /* "A negative precision is taken as if the precision
03473                             were omitted."  */
03474                         if (arg >= 0)
03475                           {
03476                             precision = arg;
03477                             has_precision = 1;
03478                           }
03479                       }
03480                     else
03481                       {
03482                         const FCHAR_T *digitp = dp->precision_start + 1;
03483 
03484                         precision = 0;
03485                         while (digitp != dp->precision_end)
03486                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
03487                         has_precision = 1;
03488                       }
03489                   }
03490 
03491                 /* POSIX specifies the default precision to be 6 for %f, %F,
03492                    %e, %E, but not for %g, %G.  Implementations appear to use
03493                    the same default precision also for %g, %G.  But for %a, %A,
03494                    the default precision is 0.  */
03495                 if (!has_precision)
03496                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
03497                     precision = 6;
03498 
03499                 /* Allocate a temporary buffer of sufficient size.  */
03500 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
03501                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
03502 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
03503                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
03504 # elif NEED_PRINTF_LONG_DOUBLE
03505                 tmp_length = LDBL_DIG + 1;
03506 # elif NEED_PRINTF_DOUBLE
03507                 tmp_length = DBL_DIG + 1;
03508 # else
03509                 tmp_length = 0;
03510 # endif
03511                 if (tmp_length < precision)
03512                   tmp_length = precision;
03513 # if NEED_PRINTF_LONG_DOUBLE
03514 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
03515                 if (type == TYPE_LONGDOUBLE)
03516 #  endif
03517                   if (dp->conversion == 'f' || dp->conversion == 'F')
03518                     {
03519                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
03520                       if (!(isnanl (arg) || arg + arg == arg))
03521                         {
03522                           /* arg is finite and nonzero.  */
03523                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
03524                           if (exponent >= 0 && tmp_length < exponent + precision)
03525                             tmp_length = exponent + precision;
03526                         }
03527                     }
03528 # endif
03529 # if NEED_PRINTF_DOUBLE
03530 #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
03531                 if (type == TYPE_DOUBLE)
03532 #  endif
03533                   if (dp->conversion == 'f' || dp->conversion == 'F')
03534                     {
03535                       double arg = a.arg[dp->arg_index].a.a_double;
03536                       if (!(isnand (arg) || arg + arg == arg))
03537                         {
03538                           /* arg is finite and nonzero.  */
03539                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
03540                           if (exponent >= 0 && tmp_length < exponent + precision)
03541                             tmp_length = exponent + precision;
03542                         }
03543                     }
03544 # endif
03545                 /* Account for sign, decimal point etc. */
03546                 tmp_length = xsum (tmp_length, 12);
03547 
03548                 if (tmp_length < width)
03549                   tmp_length = width;
03550 
03551                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
03552 
03553                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
03554                   tmp = tmpbuf;
03555                 else
03556                   {
03557                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
03558 
03559                     if (size_overflow_p (tmp_memsize))
03560                       /* Overflow, would lead to out of memory.  */
03561                       goto out_of_memory;
03562                     tmp = (DCHAR_T *) malloc (tmp_memsize);
03563                     if (tmp == NULL)
03564                       /* Out of memory.  */
03565                       goto out_of_memory;
03566                   }
03567 
03568                 pad_ptr = NULL;
03569                 p = tmp;
03570 
03571 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
03572 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
03573                 if (type == TYPE_LONGDOUBLE)
03574 #  endif
03575                   {
03576                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
03577 
03578                     if (isnanl (arg))
03579                       {
03580                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
03581                           {
03582                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
03583                           }
03584                         else
03585                           {
03586                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
03587                           }
03588                       }
03589                     else
03590                       {
03591                         int sign = 0;
03592                         DECL_LONG_DOUBLE_ROUNDING
03593 
03594                         BEGIN_LONG_DOUBLE_ROUNDING ();
03595 
03596                         if (signbit (arg)) /* arg < 0.0L or negative zero */
03597                           {
03598                             sign = -1;
03599                             arg = -arg;
03600                           }
03601 
03602                         if (sign < 0)
03603                           *p++ = '-';
03604                         else if (flags & FLAG_SHOWSIGN)
03605                           *p++ = '+';
03606                         else if (flags & FLAG_SPACE)
03607                           *p++ = ' ';
03608 
03609                         if (arg > 0.0L && arg + arg == arg)
03610                           {
03611                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
03612                               {
03613                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
03614                               }
03615                             else
03616                               {
03617                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
03618                               }
03619                           }
03620                         else
03621                           {
03622 #  if NEED_PRINTF_LONG_DOUBLE
03623                             pad_ptr = p;
03624 
03625                             if (dp->conversion == 'f' || dp->conversion == 'F')
03626                               {
03627                                 char *digits;
03628                                 size_t ndigits;
03629 
03630                                 digits =
03631                                   scale10_round_decimal_long_double (arg, precision);
03632                                 if (digits == NULL)
03633                                   {
03634                                     END_LONG_DOUBLE_ROUNDING ();
03635                                     goto out_of_memory;
03636                                   }
03637                                 ndigits = strlen (digits);
03638 
03639                                 if (ndigits > precision)
03640                                   do
03641                                     {
03642                                       --ndigits;
03643                                       *p++ = digits[ndigits];
03644                                     }
03645                                   while (ndigits > precision);
03646                                 else
03647                                   *p++ = '0';
03648                                 /* Here ndigits <= precision.  */
03649                                 if ((flags & FLAG_ALT) || precision > 0)
03650                                   {
03651                                     *p++ = decimal_point_char ();
03652                                     for (; precision > ndigits; precision--)
03653                                       *p++ = '0';
03654                                     while (ndigits > 0)
03655                                       {
03656                                         --ndigits;
03657                                         *p++ = digits[ndigits];
03658                                       }
03659                                   }
03660 
03661                                 free (digits);
03662                               }
03663                             else if (dp->conversion == 'e' || dp->conversion == 'E')
03664                               {
03665                                 int exponent;
03666 
03667                                 if (arg == 0.0L)
03668                                   {
03669                                     exponent = 0;
03670                                     *p++ = '0';
03671                                     if ((flags & FLAG_ALT) || precision > 0)
03672                                       {
03673                                         *p++ = decimal_point_char ();
03674                                         for (; precision > 0; precision--)
03675                                           *p++ = '0';
03676                                       }
03677                                   }
03678                                 else
03679                                   {
03680                                     /* arg > 0.0L.  */
03681                                     int adjusted;
03682                                     char *digits;
03683                                     size_t ndigits;
03684 
03685                                     exponent = floorlog10l (arg);
03686                                     adjusted = 0;
03687                                     for (;;)
03688                                       {
03689                                         digits =
03690                                           scale10_round_decimal_long_double (arg,
03691                                                                              (int)precision - exponent);
03692                                         if (digits == NULL)
03693                                           {
03694                                             END_LONG_DOUBLE_ROUNDING ();
03695                                             goto out_of_memory;
03696                                           }
03697                                         ndigits = strlen (digits);
03698 
03699                                         if (ndigits == precision + 1)
03700                                           break;
03701                                         if (ndigits < precision
03702                                             || ndigits > precision + 2)
03703                                           /* The exponent was not guessed
03704                                              precisely enough.  */
03705                                           abort ();
03706                                         if (adjusted)
03707                                           /* None of two values of exponent is
03708                                              the right one.  Prevent an endless
03709                                              loop.  */
03710                                           abort ();
03711                                         free (digits);
03712                                         if (ndigits == precision)
03713                                           exponent -= 1;
03714                                         else
03715                                           exponent += 1;
03716                                         adjusted = 1;
03717                                       }
03718                                     /* Here ndigits = precision+1.  */
03719                                     if (is_borderline (digits, precision))
03720                                       {
03721                                         /* Maybe the exponent guess was too high
03722                                            and a smaller exponent can be reached
03723                                            by turning a 10...0 into 9...9x.  */
03724                                         char *digits2 =
03725                                           scale10_round_decimal_long_double (arg,
03726                                                                              (int)precision - exponent + 1);
03727                                         if (digits2 == NULL)
03728                                           {
03729                                             free (digits);
03730                                             END_LONG_DOUBLE_ROUNDING ();
03731                                             goto out_of_memory;
03732                                           }
03733                                         if (strlen (digits2) == precision + 1)
03734                                           {
03735                                             free (digits);
03736                                             digits = digits2;
03737                                             exponent -= 1;
03738                                           }
03739                                         else
03740                                           free (digits2);
03741                                       }
03742                                     /* Here ndigits = precision+1.  */
03743 
03744                                     *p++ = digits[--ndigits];
03745                                     if ((flags & FLAG_ALT) || precision > 0)
03746                                       {
03747                                         *p++ = decimal_point_char ();
03748                                         while (ndigits > 0)
03749                                           {
03750                                             --ndigits;
03751                                             *p++ = digits[ndigits];
03752                                           }
03753                                       }
03754 
03755                                     free (digits);
03756                                   }
03757 
03758                                 *p++ = dp->conversion; /* 'e' or 'E' */
03759 #   if WIDE_CHAR_VERSION
03760                                 {
03761                                   static const wchar_t decimal_format[] =
03762                                     { '%', '+', '.', '2', 'd', '\0' };
03763                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
03764                                 }
03765                                 while (*p != '\0')
03766                                   p++;
03767 #   else
03768                                 if (sizeof (DCHAR_T) == 1)
03769                                   {
03770                                     sprintf ((char *) p, "%+.2d", exponent);
03771                                     while (*p != '\0')
03772                                       p++;
03773                                   }
03774                                 else
03775                                   {
03776                                     char expbuf[6 + 1];
03777                                     const char *ep;
03778                                     sprintf (expbuf, "%+.2d", exponent);
03779                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
03780                                       p++;
03781                                   }
03782 #   endif
03783                               }
03784                             else if (dp->conversion == 'g' || dp->conversion == 'G')
03785                               {
03786                                 if (precision == 0)
03787                                   precision = 1;
03788                                 /* precision >= 1.  */
03789 
03790                                 if (arg == 0.0L)
03791                                   /* The exponent is 0, >= -4, < precision.
03792                                      Use fixed-point notation.  */
03793                                   {
03794                                     size_t ndigits = precision;
03795                                     /* Number of trailing zeroes that have to be
03796                                        dropped.  */
03797                                     size_t nzeroes =
03798                                       (flags & FLAG_ALT ? 0 : precision - 1);
03799 
03800                                     --ndigits;
03801                                     *p++ = '0';
03802                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
03803                                       {
03804                                         *p++ = decimal_point_char ();
03805                                         while (ndigits > nzeroes)
03806                                           {
03807                                             --ndigits;
03808                                             *p++ = '0';
03809                                           }
03810                                       }
03811                                   }
03812                                 else
03813                                   {
03814                                     /* arg > 0.0L.  */
03815                                     int exponent;
03816                                     int adjusted;
03817                                     char *digits;
03818                                     size_t ndigits;
03819                                     size_t nzeroes;
03820 
03821                                     exponent = floorlog10l (arg);
03822                                     adjusted = 0;
03823                                     for (;;)
03824                                       {
03825                                         digits =
03826                                           scale10_round_decimal_long_double (arg,
03827                                                                              (int)(precision - 1) - exponent);
03828                                         if (digits == NULL)
03829                                           {
03830                                             END_LONG_DOUBLE_ROUNDING ();
03831                                             goto out_of_memory;
03832                                           }
03833                                         ndigits = strlen (digits);
03834 
03835                                         if (ndigits == precision)
03836                                           break;
03837                                         if (ndigits < precision - 1
03838                                             || ndigits > precision + 1)
03839                                           /* The exponent was not guessed
03840                                              precisely enough.  */
03841                                           abort ();
03842                                         if (adjusted)
03843                                           /* None of two values of exponent is
03844                                              the right one.  Prevent an endless
03845                                              loop.  */
03846                                           abort ();
03847                                         free (digits);
03848                                         if (ndigits < precision)
03849                                           exponent -= 1;
03850                                         else
03851                                           exponent += 1;
03852                                         adjusted = 1;
03853                                       }
03854                                     /* Here ndigits = precision.  */
03855                                     if (is_borderline (digits, precision - 1))
03856                                       {
03857                                         /* Maybe the exponent guess was too high
03858                                            and a smaller exponent can be reached
03859                                            by turning a 10...0 into 9...9x.  */
03860                                         char *digits2 =
03861                                           scale10_round_decimal_long_double (arg,
03862                                                                              (int)(precision - 1) - exponent + 1);
03863                                         if (digits2 == NULL)
03864                                           {
03865                                             free (digits);
03866                                             END_LONG_DOUBLE_ROUNDING ();
03867                                             goto out_of_memory;
03868                                           }
03869                                         if (strlen (digits2) == precision)
03870                                           {
03871                                             free (digits);
03872                                             digits = digits2;
03873                                             exponent -= 1;
03874                                           }
03875                                         else
03876                                           free (digits2);
03877                                       }
03878                                     /* Here ndigits = precision.  */
03879 
03880                                     /* Determine the number of trailing zeroes
03881                                        that have to be dropped.  */
03882                                     nzeroes = 0;
03883                                     if ((flags & FLAG_ALT) == 0)
03884                                       while (nzeroes < ndigits
03885                                              && digits[nzeroes] == '0')
03886                                         nzeroes++;
03887 
03888                                     /* The exponent is now determined.  */
03889                                     if (exponent >= -4
03890                                         && exponent < (long)precision)
03891                                       {
03892                                         /* Fixed-point notation:
03893                                            max(exponent,0)+1 digits, then the
03894                                            decimal point, then the remaining
03895                                            digits without trailing zeroes.  */
03896                                         if (exponent >= 0)
03897                                           {
03898                                             size_t count = exponent + 1;
03899                                             /* Note: count <= precision = ndigits.  */
03900                                             for (; count > 0; count--)
03901                                               *p++ = digits[--ndigits];
03902                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
03903                                               {
03904                                                 *p++ = decimal_point_char ();
03905                                                 while (ndigits > nzeroes)
03906                                                   {
03907                                                     --ndigits;
03908                                                     *p++ = digits[ndigits];
03909                                                   }
03910                                               }
03911                                           }
03912                                         else
03913                                           {
03914                                             size_t count = -exponent - 1;
03915                                             *p++ = '0';
03916                                             *p++ = decimal_point_char ();
03917                                             for (; count > 0; count--)
03918                                               *p++ = '0';
03919                                             while (ndigits > nzeroes)
03920                                               {
03921                                                 --ndigits;
03922                                                 *p++ = digits[ndigits];
03923                                               }
03924                                           }
03925                                       }
03926                                     else
03927                                       {
03928                                         /* Exponential notation.  */
03929                                         *p++ = digits[--ndigits];
03930                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
03931                                           {
03932                                             *p++ = decimal_point_char ();
03933                                             while (ndigits > nzeroes)
03934                                               {
03935                                                 --ndigits;
03936                                                 *p++ = digits[ndigits];
03937                                               }
03938                                           }
03939                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
03940 #   if WIDE_CHAR_VERSION
03941                                         {
03942                                           static const wchar_t decimal_format[] =
03943                                             { '%', '+', '.', '2', 'd', '\0' };
03944                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
03945                                         }
03946                                         while (*p != '\0')
03947                                           p++;
03948 #   else
03949                                         if (sizeof (DCHAR_T) == 1)
03950                                           {
03951                                             sprintf ((char *) p, "%+.2d", exponent);
03952                                             while (*p != '\0')
03953                                               p++;
03954                                           }
03955                                         else
03956                                           {
03957                                             char expbuf[6 + 1];
03958                                             const char *ep;
03959                                             sprintf (expbuf, "%+.2d", exponent);
03960                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
03961                                               p++;
03962                                           }
03963 #   endif
03964                                       }
03965 
03966                                     free (digits);
03967                                   }
03968                               }
03969                             else
03970                               abort ();
03971 #  else
03972                             /* arg is finite.  */
03973                             if (!(arg == 0.0L))
03974                               abort ();
03975 
03976                             pad_ptr = p;
03977 
03978                             if (dp->conversion == 'f' || dp->conversion == 'F')
03979                               {
03980                                 *p++ = '0';
03981                                 if ((flags & FLAG_ALT) || precision > 0)
03982                                   {
03983                                     *p++ = decimal_point_char ();
03984                                     for (; precision > 0; precision--)
03985                                       *p++ = '0';
03986                                   }
03987                               }
03988                             else if (dp->conversion == 'e' || dp->conversion == 'E')
03989                               {
03990                                 *p++ = '0';
03991                                 if ((flags & FLAG_ALT) || precision > 0)
03992                                   {
03993                                     *p++ = decimal_point_char ();
03994                                     for (; precision > 0; precision--)
03995                                       *p++ = '0';
03996                                   }
03997                                 *p++ = dp->conversion; /* 'e' or 'E' */
03998                                 *p++ = '+';
03999                                 *p++ = '0';
04000                                 *p++ = '0';
04001                               }
04002                             else if (dp->conversion == 'g' || dp->conversion == 'G')
04003                               {
04004                                 *p++ = '0';
04005                                 if (flags & FLAG_ALT)
04006                                   {
04007                                     size_t ndigits =
04008                                       (precision > 0 ? precision - 1 : 0);
04009                                     *p++ = decimal_point_char ();
04010                                     for (; ndigits > 0; --ndigits)
04011                                       *p++ = '0';
04012                                   }
04013                               }
04014                             else if (dp->conversion == 'a' || dp->conversion == 'A')
04015                               {
04016                                 *p++ = '0';
04017                                 *p++ = dp->conversion - 'A' + 'X';
04018                                 pad_ptr = p;
04019                                 *p++ = '0';
04020                                 if ((flags & FLAG_ALT) || precision > 0)
04021                                   {
04022                                     *p++ = decimal_point_char ();
04023                                     for (; precision > 0; precision--)
04024                                       *p++ = '0';
04025                                   }
04026                                 *p++ = dp->conversion - 'A' + 'P';
04027                                 *p++ = '+';
04028                                 *p++ = '0';
04029                               }
04030                             else
04031                               abort ();
04032 #  endif
04033                           }
04034 
04035                         END_LONG_DOUBLE_ROUNDING ();
04036                       }
04037                   }
04038 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
04039                 else
04040 #  endif
04041 # endif
04042 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
04043                   {
04044                     double arg = a.arg[dp->arg_index].a.a_double;
04045 
04046                     if (isnand (arg))
04047                       {
04048                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
04049                           {
04050                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
04051                           }
04052                         else
04053                           {
04054                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
04055                           }
04056                       }
04057                     else
04058                       {
04059                         int sign = 0;
04060 
04061                         if (signbit (arg)) /* arg < 0.0 or negative zero */
04062                           {
04063                             sign = -1;
04064                             arg = -arg;
04065                           }
04066 
04067                         if (sign < 0)
04068                           *p++ = '-';
04069                         else if (flags & FLAG_SHOWSIGN)
04070                           *p++ = '+';
04071                         else if (flags & FLAG_SPACE)
04072                           *p++ = ' ';
04073 
04074                         if (arg > 0.0 && arg + arg == arg)
04075                           {
04076                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
04077                               {
04078                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
04079                               }
04080                             else
04081                               {
04082                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
04083                               }
04084                           }
04085                         else
04086                           {
04087 #  if NEED_PRINTF_DOUBLE
04088                             pad_ptr = p;
04089 
04090                             if (dp->conversion == 'f' || dp->conversion == 'F')
04091                               {
04092                                 char *digits;
04093                                 size_t ndigits;
04094 
04095                                 digits =
04096                                   scale10_round_decimal_double (arg, precision);
04097                                 if (digits == NULL)
04098                                   goto out_of_memory;
04099                                 ndigits = strlen (digits);
04100 
04101                                 if (ndigits > precision)
04102                                   do
04103                                     {
04104                                       --ndigits;
04105                                       *p++ = digits[ndigits];
04106                                     }
04107                                   while (ndigits > precision);
04108                                 else
04109                                   *p++ = '0';
04110                                 /* Here ndigits <= precision.  */
04111                                 if ((flags & FLAG_ALT) || precision > 0)
04112                                   {
04113                                     *p++ = decimal_point_char ();
04114                                     for (; precision > ndigits; precision--)
04115                                       *p++ = '0';
04116                                     while (ndigits > 0)
04117                                       {
04118                                         --ndigits;
04119                                         *p++ = digits[ndigits];
04120                                       }
04121                                   }
04122 
04123                                 free (digits);
04124                               }
04125                             else if (dp->conversion == 'e' || dp->conversion == 'E')
04126                               {
04127                                 int exponent;
04128 
04129                                 if (arg == 0.0)
04130                                   {
04131                                     exponent = 0;
04132                                     *p++ = '0';
04133                                     if ((flags & FLAG_ALT) || precision > 0)
04134                                       {
04135                                         *p++ = decimal_point_char ();
04136                                         for (; precision > 0; precision--)
04137                                           *p++ = '0';
04138                                       }
04139                                   }
04140                                 else
04141                                   {
04142                                     /* arg > 0.0.  */
04143                                     int adjusted;
04144                                     char *digits;
04145                                     size_t ndigits;
04146 
04147                                     exponent = floorlog10 (arg);
04148                                     adjusted = 0;
04149                                     for (;;)
04150                                       {
04151                                         digits =
04152                                           scale10_round_decimal_double (arg,
04153                                                                         (int)precision - exponent);
04154                                         if (digits == NULL)
04155                                           goto out_of_memory;
04156                                         ndigits = strlen (digits);
04157 
04158                                         if (ndigits == precision + 1)
04159                                           break;
04160                                         if (ndigits < precision
04161                                             || ndigits > precision + 2)
04162                                           /* The exponent was not guessed
04163                                              precisely enough.  */
04164                                           abort ();
04165                                         if (adjusted)
04166                                           /* None of two values of exponent is
04167                                              the right one.  Prevent an endless
04168                                              loop.  */
04169                                           abort ();
04170                                         free (digits);
04171                                         if (ndigits == precision)
04172                                           exponent -= 1;
04173                                         else
04174                                           exponent += 1;
04175                                         adjusted = 1;
04176                                       }
04177                                     /* Here ndigits = precision+1.  */
04178                                     if (is_borderline (digits, precision))
04179                                       {
04180                                         /* Maybe the exponent guess was too high
04181                                            and a smaller exponent can be reached
04182                                            by turning a 10...0 into 9...9x.  */
04183                                         char *digits2 =
04184                                           scale10_round_decimal_double (arg,
04185                                                                         (int)precision - exponent + 1);
04186                                         if (digits2 == NULL)
04187                                           {
04188                                             free (digits);
04189                                             goto out_of_memory;
04190                                           }
04191                                         if (strlen (digits2) == precision + 1)
04192                                           {
04193                                             free (digits);
04194                                             digits = digits2;
04195                                             exponent -= 1;
04196                                           }
04197                                         else
04198                                           free (digits2);
04199                                       }
04200                                     /* Here ndigits = precision+1.  */
04201 
04202                                     *p++ = digits[--ndigits];
04203                                     if ((flags & FLAG_ALT) || precision > 0)
04204                                       {
04205                                         *p++ = decimal_point_char ();
04206                                         while (ndigits > 0)
04207                                           {
04208                                             --ndigits;
04209                                             *p++ = digits[ndigits];
04210                                           }
04211                                       }
04212 
04213                                     free (digits);
04214                                   }
04215 
04216                                 *p++ = dp->conversion; /* 'e' or 'E' */
04217 #   if WIDE_CHAR_VERSION
04218                                 {
04219                                   static const wchar_t decimal_format[] =
04220                                     /* Produce the same number of exponent digits
04221                                        as the native printf implementation.  */
04222 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
04223                                     { '%', '+', '.', '3', 'd', '\0' };
04224 #    else
04225                                     { '%', '+', '.', '2', 'd', '\0' };
04226 #    endif
04227                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
04228                                 }
04229                                 while (*p != '\0')
04230                                   p++;
04231 #   else
04232                                 {
04233                                   static const char decimal_format[] =
04234                                     /* Produce the same number of exponent digits
04235                                        as the native printf implementation.  */
04236 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
04237                                     "%+.3d";
04238 #    else
04239                                     "%+.2d";
04240 #    endif
04241                                   if (sizeof (DCHAR_T) == 1)
04242                                     {
04243                                       sprintf ((char *) p, decimal_format, exponent);
04244                                       while (*p != '\0')
04245                                         p++;
04246                                     }
04247                                   else
04248                                     {
04249                                       char expbuf[6 + 1];
04250                                       const char *ep;
04251                                       sprintf (expbuf, decimal_format, exponent);
04252                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
04253                                         p++;
04254                                     }
04255                                 }
04256 #   endif
04257                               }
04258                             else if (dp->conversion == 'g' || dp->conversion == 'G')
04259                               {
04260                                 if (precision == 0)
04261                                   precision = 1;
04262                                 /* precision >= 1.  */
04263 
04264                                 if (arg == 0.0)
04265                                   /* The exponent is 0, >= -4, < precision.
04266                                      Use fixed-point notation.  */
04267                                   {
04268                                     size_t ndigits = precision;
04269                                     /* Number of trailing zeroes that have to be
04270                                        dropped.  */
04271                                     size_t nzeroes =
04272                                       (flags & FLAG_ALT ? 0 : precision - 1);
04273 
04274                                     --ndigits;
04275                                     *p++ = '0';
04276                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
04277                                       {
04278                                         *p++ = decimal_point_char ();
04279                                         while (ndigits > nzeroes)
04280                                           {
04281                                             --ndigits;
04282                                             *p++ = '0';
04283                                           }
04284                                       }
04285                                   }
04286                                 else
04287                                   {
04288                                     /* arg > 0.0.  */
04289                                     int exponent;
04290                                     int adjusted;
04291                                     char *digits;
04292                                     size_t ndigits;
04293                                     size_t nzeroes;
04294 
04295                                     exponent = floorlog10 (arg);
04296                                     adjusted = 0;
04297                                     for (;;)
04298                                       {
04299                                         digits =
04300                                           scale10_round_decimal_double (arg,
04301                                                                         (int)(precision - 1) - exponent);
04302                                         if (digits == NULL)
04303                                           goto out_of_memory;
04304                                         ndigits = strlen (digits);
04305 
04306                                         if (ndigits == precision)
04307                                           break;
04308                                         if (ndigits < precision - 1
04309                                             || ndigits > precision + 1)
04310                                           /* The exponent was not guessed
04311                                              precisely enough.  */
04312                                           abort ();
04313                                         if (adjusted)
04314                                           /* None of two values of exponent is
04315                                              the right one.  Prevent an endless
04316                                              loop.  */
04317                                           abort ();
04318                                         free (digits);
04319                                         if (ndigits < precision)
04320                                           exponent -= 1;
04321                                         else
04322                                           exponent += 1;
04323                                         adjusted = 1;
04324                                       }
04325                                     /* Here ndigits = precision.  */
04326                                     if (is_borderline (digits, precision - 1))
04327                                       {
04328                                         /* Maybe the exponent guess was too high
04329                                            and a smaller exponent can be reached
04330                                            by turning a 10...0 into 9...9x.  */
04331                                         char *digits2 =
04332                                           scale10_round_decimal_double (arg,
04333                                                                         (int)(precision - 1) - exponent + 1);
04334                                         if (digits2 == NULL)
04335                                           {
04336                                             free (digits);
04337                                             goto out_of_memory;
04338                                           }
04339                                         if (strlen (digits2) == precision)
04340                                           {
04341                                             free (digits);
04342                                             digits = digits2;
04343                                             exponent -= 1;
04344                                           }
04345                                         else
04346                                           free (digits2);
04347                                       }
04348                                     /* Here ndigits = precision.  */
04349 
04350                                     /* Determine the number of trailing zeroes
04351                                        that have to be dropped.  */
04352                                     nzeroes = 0;
04353                                     if ((flags & FLAG_ALT) == 0)
04354                                       while (nzeroes < ndigits
04355                                              && digits[nzeroes] == '0')
04356                                         nzeroes++;
04357 
04358                                     /* The exponent is now determined.  */
04359                                     if (exponent >= -4
04360                                         && exponent < (long)precision)
04361                                       {
04362                                         /* Fixed-point notation:
04363                                            max(exponent,0)+1 digits, then the
04364                                            decimal point, then the remaining
04365                                            digits without trailing zeroes.  */
04366                                         if (exponent >= 0)
04367                                           {
04368                                             size_t count = exponent + 1;
04369                                             /* Note: count <= precision = ndigits.  */
04370                                             for (; count > 0; count--)
04371                                               *p++ = digits[--ndigits];
04372                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
04373                                               {
04374                                                 *p++ = decimal_point_char ();
04375                                                 while (ndigits > nzeroes)
04376                                                   {
04377                                                     --ndigits;
04378                                                     *p++ = digits[ndigits];
04379                                                   }
04380                                               }
04381                                           }
04382                                         else
04383                                           {
04384                                             size_t count = -exponent - 1;
04385                                             *p++ = '0';
04386                                             *p++ = decimal_point_char ();
04387                                             for (; count > 0; count--)
04388                                               *p++ = '0';
04389                                             while (ndigits > nzeroes)
04390                                               {
04391                                                 --ndigits;
04392                                                 *p++ = digits[ndigits];
04393                                               }
04394                                           }
04395                                       }
04396                                     else
04397                                       {
04398                                         /* Exponential notation.  */
04399                                         *p++ = digits[--ndigits];
04400                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
04401                                           {
04402                                             *p++ = decimal_point_char ();
04403                                             while (ndigits > nzeroes)
04404                                               {
04405                                                 --ndigits;
04406                                                 *p++ = digits[ndigits];
04407                                               }
04408                                           }
04409                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
04410 #   if WIDE_CHAR_VERSION
04411                                         {
04412                                           static const wchar_t decimal_format[] =
04413                                             /* Produce the same number of exponent digits
04414                                                as the native printf implementation.  */
04415 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
04416                                             { '%', '+', '.', '3', 'd', '\0' };
04417 #    else
04418                                             { '%', '+', '.', '2', 'd', '\0' };
04419 #    endif
04420                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
04421                                         }
04422                                         while (*p != '\0')
04423                                           p++;
04424 #   else
04425                                         {
04426                                           static const char decimal_format[] =
04427                                             /* Produce the same number of exponent digits
04428                                                as the native printf implementation.  */
04429 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
04430                                             "%+.3d";
04431 #    else
04432                                             "%+.2d";
04433 #    endif
04434                                           if (sizeof (DCHAR_T) == 1)
04435                                             {
04436                                               sprintf ((char *) p, decimal_format, exponent);
04437                                               while (*p != '\0')
04438                                                 p++;
04439                                             }
04440                                           else
04441                                             {
04442                                               char expbuf[6 + 1];
04443                                               const char *ep;
04444                                               sprintf (expbuf, decimal_format, exponent);
04445                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
04446                                                 p++;
04447                                             }
04448                                         }
04449 #   endif
04450                                       }
04451 
04452                                     free (digits);
04453                                   }
04454                               }
04455                             else
04456                               abort ();
04457 #  else
04458                             /* arg is finite.  */
04459                             if (!(arg == 0.0))
04460                               abort ();
04461 
04462                             pad_ptr = p;
04463 
04464                             if (dp->conversion == 'f' || dp->conversion == 'F')
04465                               {
04466                                 *p++ = '0';
04467                                 if ((flags & FLAG_ALT) || precision > 0)
04468                                   {
04469                                     *p++ = decimal_point_char ();
04470                                     for (; precision > 0; precision--)
04471                                       *p++ = '0';
04472                                   }
04473                               }
04474                             else if (dp->conversion == 'e' || dp->conversion == 'E')
04475                               {
04476                                 *p++ = '0';
04477                                 if ((flags & FLAG_ALT) || precision > 0)
04478                                   {
04479                                     *p++ = decimal_point_char ();
04480                                     for (; precision > 0; precision--)
04481                                       *p++ = '0';
04482                                   }
04483                                 *p++ = dp->conversion; /* 'e' or 'E' */
04484                                 *p++ = '+';
04485                                 /* Produce the same number of exponent digits as
04486                                    the native printf implementation.  */
04487 #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
04488                                 *p++ = '0';
04489 #   endif
04490                                 *p++ = '0';
04491                                 *p++ = '0';
04492                               }
04493                             else if (dp->conversion == 'g' || dp->conversion == 'G')
04494                               {
04495                                 *p++ = '0';
04496                                 if (flags & FLAG_ALT)
04497                                   {
04498                                     size_t ndigits =
04499                                       (precision > 0 ? precision - 1 : 0);
04500                                     *p++ = decimal_point_char ();
04501                                     for (; ndigits > 0; --ndigits)
04502                                       *p++ = '0';
04503                                   }
04504                               }
04505                             else
04506                               abort ();
04507 #  endif
04508                           }
04509                       }
04510                   }
04511 # endif
04512 
04513                 /* The generated string now extends from tmp to p, with the
04514                    zero padding insertion point being at pad_ptr.  */
04515                 if (has_width && p - tmp < width)
04516                   {
04517                     size_t pad = width - (p - tmp);
04518                     DCHAR_T *end = p + pad;
04519 
04520                     if (flags & FLAG_LEFT)
04521                       {
04522                         /* Pad with spaces on the right.  */
04523                         for (; pad > 0; pad--)
04524                           *p++ = ' ';
04525                       }
04526                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
04527                       {
04528                         /* Pad with zeroes.  */
04529                         DCHAR_T *q = end;
04530 
04531                         while (p > pad_ptr)
04532                           *--q = *--p;
04533                         for (; pad > 0; pad--)
04534                           *p++ = '0';
04535                       }
04536                     else
04537                       {
04538                         /* Pad with spaces on the left.  */
04539                         DCHAR_T *q = end;
04540 
04541                         while (p > tmp)
04542                           *--q = *--p;
04543                         for (; pad > 0; pad--)
04544                           *p++ = ' ';
04545                       }
04546 
04547                     p = end;
04548                   }
04549 
04550                 {
04551                   size_t count = p - tmp;
04552 
04553                   if (count >= tmp_length)
04554                     /* tmp_length was incorrectly calculated - fix the
04555                        code above!  */
04556                     abort ();
04557 
04558                   /* Make room for the result.  */
04559                   if (count >= allocated - length)
04560                     {
04561                       size_t n = xsum (length, count);
04562 
04563                       ENSURE_ALLOCATION (n);
04564                     }
04565 
04566                   /* Append the result.  */
04567                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
04568                   if (tmp != tmpbuf)
04569                     free (tmp);
04570                   length += count;
04571                 }
04572               }
04573 #endif
04574             else
04575               {
04576                 arg_type type = a.arg[dp->arg_index].type;
04577                 int flags = dp->flags;
04578 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
04579                 int has_width;
04580                 size_t width;
04581 #endif
04582 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
04583                 int has_precision;
04584                 size_t precision;
04585 #endif
04586 #if NEED_PRINTF_UNBOUNDED_PRECISION
04587                 int prec_ourselves;
04588 #else
04589 #               define prec_ourselves 0
04590 #endif
04591 #if NEED_PRINTF_FLAG_LEFTADJUST
04592 #               define pad_ourselves 1
04593 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
04594                 int pad_ourselves;
04595 #else
04596 #               define pad_ourselves 0
04597 #endif
04598                 TCHAR_T *fbp;
04599                 unsigned int prefix_count;
04600                 int prefixes[2] IF_LINT (= { 0 });
04601 #if !USE_SNPRINTF
04602                 size_t tmp_length;
04603                 TCHAR_T tmpbuf[700];
04604                 TCHAR_T *tmp;
04605 #endif
04606 
04607 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
04608                 has_width = 0;
04609                 width = 0;
04610                 if (dp->width_start != dp->width_end)
04611                   {
04612                     if (dp->width_arg_index != ARG_NONE)
04613                       {
04614                         int arg;
04615 
04616                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
04617                           abort ();
04618                         arg = a.arg[dp->width_arg_index].a.a_int;
04619                         if (arg < 0)
04620                           {
04621                             /* "A negative field width is taken as a '-' flag
04622                                 followed by a positive field width."  */
04623                             flags |= FLAG_LEFT;
04624                             width = (unsigned int) (-arg);
04625                           }
04626                         else
04627                           width = arg;
04628                       }
04629                     else
04630                       {
04631                         const FCHAR_T *digitp = dp->width_start;
04632 
04633                         do
04634                           width = xsum (xtimes (width, 10), *digitp++ - '0');
04635                         while (digitp != dp->width_end);
04636                       }
04637                     has_width = 1;
04638                   }
04639 #endif
04640 
04641 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
04642                 has_precision = 0;
04643                 precision = 6;
04644                 if (dp->precision_start != dp->precision_end)
04645                   {
04646                     if (dp->precision_arg_index != ARG_NONE)
04647                       {
04648                         int arg;
04649 
04650                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
04651                           abort ();
04652                         arg = a.arg[dp->precision_arg_index].a.a_int;
04653                         /* "A negative precision is taken as if the precision
04654                             were omitted."  */
04655                         if (arg >= 0)
04656                           {
04657                             precision = arg;
04658                             has_precision = 1;
04659                           }
04660                       }
04661                     else
04662                       {
04663                         const FCHAR_T *digitp = dp->precision_start + 1;
04664 
04665                         precision = 0;
04666                         while (digitp != dp->precision_end)
04667                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
04668                         has_precision = 1;
04669                       }
04670                   }
04671 #endif
04672 
04673                 /* Decide whether to handle the precision ourselves.  */
04674 #if NEED_PRINTF_UNBOUNDED_PRECISION
04675                 switch (dp->conversion)
04676                   {
04677                   case 'd': case 'i': case 'u':
04678                   case 'o':
04679                   case 'x': case 'X': case 'p':
04680                     prec_ourselves = has_precision && (precision > 0);
04681                     break;
04682                   default:
04683                     prec_ourselves = 0;
04684                     break;
04685                   }
04686 #endif
04687 
04688                 /* Decide whether to perform the padding ourselves.  */
04689 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
04690                 switch (dp->conversion)
04691                   {
04692 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
04693                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
04694                      to perform the padding after this conversion.  Functions
04695                      with unistdio extensions perform the padding based on
04696                      character count rather than element count.  */
04697                   case 'c': case 's':
04698 # endif
04699 # if NEED_PRINTF_FLAG_ZERO
04700                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
04701                   case 'a': case 'A':
04702 # endif
04703                     pad_ourselves = 1;
04704                     break;
04705                   default:
04706                     pad_ourselves = prec_ourselves;
04707                     break;
04708                   }
04709 #endif
04710 
04711 #if !USE_SNPRINTF
04712                 /* Allocate a temporary buffer of sufficient size for calling
04713                    sprintf.  */
04714                 tmp_length =
04715                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
04716                                    flags, width, has_precision, precision,
04717                                    pad_ourselves);
04718 
04719                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
04720                   tmp = tmpbuf;
04721                 else
04722                   {
04723                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
04724 
04725                     if (size_overflow_p (tmp_memsize))
04726                       /* Overflow, would lead to out of memory.  */
04727                       goto out_of_memory;
04728                     tmp = (TCHAR_T *) malloc (tmp_memsize);
04729                     if (tmp == NULL)
04730                       /* Out of memory.  */
04731                       goto out_of_memory;
04732                   }
04733 #endif
04734 
04735                 /* Construct the format string for calling snprintf or
04736                    sprintf.  */
04737                 fbp = buf;
04738                 *fbp++ = '%';
04739 #if NEED_PRINTF_FLAG_GROUPING
04740                 /* The underlying implementation doesn't support the ' flag.
04741                    Produce no grouping characters in this case; this is
04742                    acceptable because the grouping is locale dependent.  */
04743 #else
04744                 if (flags & FLAG_GROUP)
04745                   *fbp++ = '\'';
04746 #endif
04747                 if (flags & FLAG_LEFT)
04748                   *fbp++ = '-';
04749                 if (flags & FLAG_SHOWSIGN)
04750                   *fbp++ = '+';
04751                 if (flags & FLAG_SPACE)
04752                   *fbp++ = ' ';
04753                 if (flags & FLAG_ALT)
04754                   *fbp++ = '#';
04755                 if (!pad_ourselves)
04756                   {
04757                     if (flags & FLAG_ZERO)
04758                       *fbp++ = '0';
04759                     if (dp->width_start != dp->width_end)
04760                       {
04761                         size_t n = dp->width_end - dp->width_start;
04762                         /* The width specification is known to consist only
04763                            of standard ASCII characters.  */
04764                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
04765                           {
04766                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
04767                             fbp += n;
04768                           }
04769                         else
04770                           {
04771                             const FCHAR_T *mp = dp->width_start;
04772                             do
04773                               *fbp++ = (unsigned char) *mp++;
04774                             while (--n > 0);
04775                           }
04776                       }
04777                   }
04778                 if (!prec_ourselves)
04779                   {
04780                     if (dp->precision_start != dp->precision_end)
04781                       {
04782                         size_t n = dp->precision_end - dp->precision_start;
04783                         /* The precision specification is known to consist only
04784                            of standard ASCII characters.  */
04785                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
04786                           {
04787                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
04788                             fbp += n;
04789                           }
04790                         else
04791                           {
04792                             const FCHAR_T *mp = dp->precision_start;
04793                             do
04794                               *fbp++ = (unsigned char) *mp++;
04795                             while (--n > 0);
04796                           }
04797                       }
04798                   }
04799 
04800                 switch (type)
04801                   {
04802 #if HAVE_LONG_LONG_INT
04803                   case TYPE_LONGLONGINT:
04804                   case TYPE_ULONGLONGINT:
04805 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
04806                     *fbp++ = 'I';
04807                     *fbp++ = '6';
04808                     *fbp++ = '4';
04809                     break;
04810 # else
04811                     *fbp++ = 'l';
04812                     /*FALLTHROUGH*/
04813 # endif
04814 #endif
04815                   case TYPE_LONGINT:
04816                   case TYPE_ULONGINT:
04817 #if HAVE_WINT_T
04818                   case TYPE_WIDE_CHAR:
04819 #endif
04820 #if HAVE_WCHAR_T
04821                   case TYPE_WIDE_STRING:
04822 #endif
04823                     *fbp++ = 'l';
04824                     break;
04825                   case TYPE_LONGDOUBLE:
04826                     *fbp++ = 'L';
04827                     break;
04828                   default:
04829                     break;
04830                   }
04831 #if NEED_PRINTF_DIRECTIVE_F
04832                 if (dp->conversion == 'F')
04833                   *fbp = 'f';
04834                 else
04835 #endif
04836                   *fbp = dp->conversion;
04837 #if USE_SNPRINTF
04838 # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
04839                 fbp[1] = '%';
04840                 fbp[2] = 'n';
04841                 fbp[3] = '\0';
04842 # else
04843                 /* On glibc2 systems from glibc >= 2.3 - probably also older
04844                    ones - we know that snprintf's returns value conforms to
04845                    ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
04846                    Therefore we can avoid using %n in this situation.
04847                    On glibc2 systems from 2004-10-18 or newer, the use of %n
04848                    in format strings in writable memory may crash the program
04849                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
04850                    in this situation.  */
04851                 /* On native Win32 systems (such as mingw), we can avoid using
04852                    %n because:
04853                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
04854                        snprintf does not write more than the specified number
04855                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
04856                        '4', '5', '6' into buf, not '4', '5', '\0'.)
04857                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
04858                        allows us to recognize the case of an insufficient
04859                        buffer size: it returns -1 in this case.
04860                    On native Win32 systems (such as mingw) where the OS is
04861                    Windows Vista, the use of %n in format strings by default
04862                    crashes the program. See
04863                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
04864                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
04865                    So we should avoid %n in this situation.  */
04866                 fbp[1] = '\0';
04867 # endif
04868 #else
04869                 fbp[1] = '\0';
04870 #endif
04871 
04872                 /* Construct the arguments for calling snprintf or sprintf.  */
04873                 prefix_count = 0;
04874                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
04875                   {
04876                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
04877                       abort ();
04878                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
04879                   }
04880                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
04881                   {
04882                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
04883                       abort ();
04884                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
04885                   }
04886 
04887 #if USE_SNPRINTF
04888                 /* The SNPRINTF result is appended after result[0..length].
04889                    The latter is an array of DCHAR_T; SNPRINTF appends an
04890                    array of TCHAR_T to it.  This is possible because
04891                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
04892                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
04893 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
04894                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
04895                    where an snprintf() with maxlen==1 acts like sprintf().  */
04896                 ENSURE_ALLOCATION (xsum (length,
04897                                          (2 + TCHARS_PER_DCHAR - 1)
04898                                          / TCHARS_PER_DCHAR));
04899                 /* Prepare checking whether snprintf returns the count
04900                    via %n.  */
04901                 *(TCHAR_T *) (result + length) = '\0';
04902 #endif
04903 
04904                 for (;;)
04905                   {
04906                     int count = -1;
04907 
04908 #if USE_SNPRINTF
04909                     int retcount = 0;
04910                     size_t maxlen = allocated - length;
04911                     /* SNPRINTF can fail if its second argument is
04912                        > INT_MAX.  */
04913                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
04914                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
04915                     maxlen = maxlen * TCHARS_PER_DCHAR;
04916 # define SNPRINTF_BUF(arg) \
04917                     switch (prefix_count)                                   \
04918                       {                                                     \
04919                       case 0:                                               \
04920                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
04921                                              maxlen, buf,                   \
04922                                              arg, &count);                  \
04923                         break;                                              \
04924                       case 1:                                               \
04925                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
04926                                              maxlen, buf,                   \
04927                                              prefixes[0], arg, &count);     \
04928                         break;                                              \
04929                       case 2:                                               \
04930                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
04931                                              maxlen, buf,                   \
04932                                              prefixes[0], prefixes[1], arg, \
04933                                              &count);                       \
04934                         break;                                              \
04935                       default:                                              \
04936                         abort ();                                           \
04937                       }
04938 #else
04939 # define SNPRINTF_BUF(arg) \
04940                     switch (prefix_count)                                   \
04941                       {                                                     \
04942                       case 0:                                               \
04943                         count = sprintf (tmp, buf, arg);                    \
04944                         break;                                              \
04945                       case 1:                                               \
04946                         count = sprintf (tmp, buf, prefixes[0], arg);       \
04947                         break;                                              \
04948                       case 2:                                               \
04949                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
04950                                          arg);                              \
04951                         break;                                              \
04952                       default:                                              \
04953                         abort ();                                           \
04954                       }
04955 #endif
04956 
04957                     errno = 0;
04958                     switch (type)
04959                       {
04960                       case TYPE_SCHAR:
04961                         {
04962                           int arg = a.arg[dp->arg_index].a.a_schar;
04963                           SNPRINTF_BUF (arg);
04964                         }
04965                         break;
04966                       case TYPE_UCHAR:
04967                         {
04968                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
04969                           SNPRINTF_BUF (arg);
04970                         }
04971                         break;
04972                       case TYPE_SHORT:
04973                         {
04974                           int arg = a.arg[dp->arg_index].a.a_short;
04975                           SNPRINTF_BUF (arg);
04976                         }
04977                         break;
04978                       case TYPE_USHORT:
04979                         {
04980                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
04981                           SNPRINTF_BUF (arg);
04982                         }
04983                         break;
04984                       case TYPE_INT:
04985                         {
04986                           int arg = a.arg[dp->arg_index].a.a_int;
04987                           SNPRINTF_BUF (arg);
04988                         }
04989                         break;
04990                       case TYPE_UINT:
04991                         {
04992                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
04993                           SNPRINTF_BUF (arg);
04994                         }
04995                         break;
04996                       case TYPE_LONGINT:
04997                         {
04998                           long int arg = a.arg[dp->arg_index].a.a_longint;
04999                           SNPRINTF_BUF (arg);
05000                         }
05001                         break;
05002                       case TYPE_ULONGINT:
05003                         {
05004                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
05005                           SNPRINTF_BUF (arg);
05006                         }
05007                         break;
05008 #if HAVE_LONG_LONG_INT
05009                       case TYPE_LONGLONGINT:
05010                         {
05011                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
05012                           SNPRINTF_BUF (arg);
05013                         }
05014                         break;
05015                       case TYPE_ULONGLONGINT:
05016                         {
05017                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
05018                           SNPRINTF_BUF (arg);
05019                         }
05020                         break;
05021 #endif
05022                       case TYPE_DOUBLE:
05023                         {
05024                           double arg = a.arg[dp->arg_index].a.a_double;
05025                           SNPRINTF_BUF (arg);
05026                         }
05027                         break;
05028                       case TYPE_LONGDOUBLE:
05029                         {
05030                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
05031                           SNPRINTF_BUF (arg);
05032                         }
05033                         break;
05034                       case TYPE_CHAR:
05035                         {
05036                           int arg = a.arg[dp->arg_index].a.a_char;
05037                           SNPRINTF_BUF (arg);
05038                         }
05039                         break;
05040 #if HAVE_WINT_T
05041                       case TYPE_WIDE_CHAR:
05042                         {
05043                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
05044                           SNPRINTF_BUF (arg);
05045                         }
05046                         break;
05047 #endif
05048                       case TYPE_STRING:
05049                         {
05050                           const char *arg = a.arg[dp->arg_index].a.a_string;
05051                           SNPRINTF_BUF (arg);
05052                         }
05053                         break;
05054 #if HAVE_WCHAR_T
05055                       case TYPE_WIDE_STRING:
05056                         {
05057                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
05058                           SNPRINTF_BUF (arg);
05059                         }
05060                         break;
05061 #endif
05062                       case TYPE_POINTER:
05063                         {
05064                           void *arg = a.arg[dp->arg_index].a.a_pointer;
05065                           SNPRINTF_BUF (arg);
05066                         }
05067                         break;
05068                       default:
05069                         abort ();
05070                       }
05071 
05072 #if USE_SNPRINTF
05073                     /* Portability: Not all implementations of snprintf()
05074                        are ISO C 99 compliant.  Determine the number of
05075                        bytes that snprintf() has produced or would have
05076                        produced.  */
05077                     if (count >= 0)
05078                       {
05079                         /* Verify that snprintf() has NUL-terminated its
05080                            result.  */
05081                         if (count < maxlen
05082                             && ((TCHAR_T *) (result + length)) [count] != '\0')
05083                           abort ();
05084                         /* Portability hack.  */
05085                         if (retcount > count)
05086                           count = retcount;
05087                       }
05088                     else
05089                       {
05090                         /* snprintf() doesn't understand the '%n'
05091                            directive.  */
05092                         if (fbp[1] != '\0')
05093                           {
05094                             /* Don't use the '%n' directive; instead, look
05095                                at the snprintf() return value.  */
05096                             fbp[1] = '\0';
05097                             continue;
05098                           }
05099                         else
05100                           {
05101                             /* Look at the snprintf() return value.  */
05102                             if (retcount < 0)
05103                               {
05104 # if !HAVE_SNPRINTF_RETVAL_C99
05105                                 /* HP-UX 10.20 snprintf() is doubly deficient:
05106                                    It doesn't understand the '%n' directive,
05107                                    *and* it returns -1 (rather than the length
05108                                    that would have been required) when the
05109                                    buffer is too small.
05110                                    But a failure at this point can also come
05111                                    from other reasons than a too small buffer,
05112                                    such as an invalid wide string argument to
05113                                    the %ls directive, or possibly an invalid
05114                                    floating-point argument.  */
05115                                 size_t tmp_length =
05116                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
05117                                                    dp->conversion, type, flags,
05118                                                    width, has_precision,
05119                                                    precision, pad_ourselves);
05120 
05121                                 if (maxlen < tmp_length)
05122                                   {
05123                                     /* Make more room.  But try to do through
05124                                        this reallocation only once.  */
05125                                     size_t bigger_need =
05126                                       xsum (length,
05127                                             xsum (tmp_length,
05128                                                   TCHARS_PER_DCHAR - 1)
05129                                             / TCHARS_PER_DCHAR);
05130                                     /* And always grow proportionally.
05131                                        (There may be several arguments, each
05132                                        needing a little more room than the
05133                                        previous one.)  */
05134                                     size_t bigger_need2 =
05135                                       xsum (xtimes (allocated, 2), 12);
05136                                     if (bigger_need < bigger_need2)
05137                                       bigger_need = bigger_need2;
05138                                     ENSURE_ALLOCATION (bigger_need);
05139                                     continue;
05140                                   }
05141 # endif
05142                               }
05143                             else
05144                               count = retcount;
05145                           }
05146                       }
05147 #endif
05148 
05149                     /* Attempt to handle failure.  */
05150                     if (count < 0)
05151                       {
05152                         /* SNPRINTF or sprintf failed.  Save and use the errno
05153                            that it has set, if any.  */
05154                         int saved_errno = errno;
05155 
05156                         if (!(result == resultbuf || result == NULL))
05157                           free (result);
05158                         if (buf_malloced != NULL)
05159                           free (buf_malloced);
05160                         CLEANUP ();
05161                         errno =
05162                           (saved_errno != 0
05163                            ? saved_errno
05164                            : (dp->conversion == 'c' || dp->conversion == 's'
05165                               ? EILSEQ
05166                               : EINVAL));
05167                         return NULL;
05168                       }
05169 
05170 #if USE_SNPRINTF
05171                     /* Handle overflow of the allocated buffer.
05172                        If such an overflow occurs, a C99 compliant snprintf()
05173                        returns a count >= maxlen.  However, a non-compliant
05174                        snprintf() function returns only count = maxlen - 1.  To
05175                        cover both cases, test whether count >= maxlen - 1.  */
05176                     if ((unsigned int) count + 1 >= maxlen)
05177                       {
05178                         /* If maxlen already has attained its allowed maximum,
05179                            allocating more memory will not increase maxlen.
05180                            Instead of looping, bail out.  */
05181                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
05182                           goto overflow;
05183                         else
05184                           {
05185                             /* Need at least (count + 1) * sizeof (TCHAR_T)
05186                                bytes.  (The +1 is for the trailing NUL.)
05187                                But ask for (count + 2) * sizeof (TCHAR_T)
05188                                bytes, so that in the next round, we likely get
05189                                  maxlen > (unsigned int) count + 1
05190                                and so we don't get here again.
05191                                And allocate proportionally, to avoid looping
05192                                eternally if snprintf() reports a too small
05193                                count.  */
05194                             size_t n =
05195                               xmax (xsum (length,
05196                                           ((unsigned int) count + 2
05197                                            + TCHARS_PER_DCHAR - 1)
05198                                           / TCHARS_PER_DCHAR),
05199                                     xtimes (allocated, 2));
05200 
05201                             ENSURE_ALLOCATION (n);
05202                             continue;
05203                           }
05204                       }
05205 #endif
05206 
05207 #if NEED_PRINTF_UNBOUNDED_PRECISION
05208                     if (prec_ourselves)
05209                       {
05210                         /* Handle the precision.  */
05211                         TCHAR_T *prec_ptr =
05212 # if USE_SNPRINTF
05213                           (TCHAR_T *) (result + length);
05214 # else
05215                           tmp;
05216 # endif
05217                         size_t prefix_count;
05218                         size_t move;
05219 
05220                         prefix_count = 0;
05221                         /* Put the additional zeroes after the sign.  */
05222                         if (count >= 1
05223                             && (*prec_ptr == '-' || *prec_ptr == '+'
05224                                 || *prec_ptr == ' '))
05225                           prefix_count = 1;
05226                         /* Put the additional zeroes after the 0x prefix if
05227                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
05228                         else if (count >= 2
05229                                  && prec_ptr[0] == '0'
05230                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
05231                           prefix_count = 2;
05232 
05233                         move = count - prefix_count;
05234                         if (precision > move)
05235                           {
05236                             /* Insert zeroes.  */
05237                             size_t insert = precision - move;
05238                             TCHAR_T *prec_end;
05239 
05240 # if USE_SNPRINTF
05241                             size_t n =
05242                               xsum (length,
05243                                     (count + insert + TCHARS_PER_DCHAR - 1)
05244                                     / TCHARS_PER_DCHAR);
05245                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
05246                             ENSURE_ALLOCATION (n);
05247                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
05248                             prec_ptr = (TCHAR_T *) (result + length);
05249 # endif
05250 
05251                             prec_end = prec_ptr + count;
05252                             prec_ptr += prefix_count;
05253 
05254                             while (prec_end > prec_ptr)
05255                               {
05256                                 prec_end--;
05257                                 prec_end[insert] = prec_end[0];
05258                               }
05259 
05260                             prec_end += insert;
05261                             do
05262                               *--prec_end = '0';
05263                             while (prec_end > prec_ptr);
05264 
05265                             count += insert;
05266                           }
05267                       }
05268 #endif
05269 
05270 #if !USE_SNPRINTF
05271                     if (count >= tmp_length)
05272                       /* tmp_length was incorrectly calculated - fix the
05273                          code above!  */
05274                       abort ();
05275 #endif
05276 
05277 #if !DCHAR_IS_TCHAR
05278                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
05279                     if (dp->conversion == 'c' || dp->conversion == 's')
05280                       {
05281                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
05282                            TYPE_WIDE_STRING.
05283                            The result string is not certainly ASCII.  */
05284                         const TCHAR_T *tmpsrc;
05285                         DCHAR_T *tmpdst;
05286                         size_t tmpdst_len;
05287                         /* This code assumes that TCHAR_T is 'char'.  */
05288                         typedef int TCHAR_T_verify
05289                                     [2 * (sizeof (TCHAR_T) == 1) - 1];
05290 # if USE_SNPRINTF
05291                         tmpsrc = (TCHAR_T *) (result + length);
05292 # else
05293                         tmpsrc = tmp;
05294 # endif
05295                         tmpdst =
05296                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
05297                                                     iconveh_question_mark,
05298                                                     tmpsrc, count,
05299                                                     NULL,
05300                                                     NULL, &tmpdst_len);
05301                         if (tmpdst == NULL)
05302                           {
05303                             int saved_errno = errno;
05304                             if (!(result == resultbuf || result == NULL))
05305                               free (result);
05306                             if (buf_malloced != NULL)
05307                               free (buf_malloced);
05308                             CLEANUP ();
05309                             errno = saved_errno;
05310                             return NULL;
05311                           }
05312                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
05313                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
05314                         free (tmpdst);
05315                         count = tmpdst_len;
05316                       }
05317                     else
05318                       {
05319                         /* The result string is ASCII.
05320                            Simple 1:1 conversion.  */
05321 # if USE_SNPRINTF
05322                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
05323                            no-op conversion, in-place on the array starting
05324                            at (result + length).  */
05325                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
05326 # endif
05327                           {
05328                             const TCHAR_T *tmpsrc;
05329                             DCHAR_T *tmpdst;
05330                             size_t n;
05331 
05332 # if USE_SNPRINTF
05333                             if (result == resultbuf)
05334                               {
05335                                 tmpsrc = (TCHAR_T *) (result + length);
05336                                 /* ENSURE_ALLOCATION will not move tmpsrc
05337                                    (because it's part of resultbuf).  */
05338                                 ENSURE_ALLOCATION (xsum (length, count));
05339                               }
05340                             else
05341                               {
05342                                 /* ENSURE_ALLOCATION will move the array
05343                                    (because it uses realloc().  */
05344                                 ENSURE_ALLOCATION (xsum (length, count));
05345                                 tmpsrc = (TCHAR_T *) (result + length);
05346                               }
05347 # else
05348                             tmpsrc = tmp;
05349                             ENSURE_ALLOCATION (xsum (length, count));
05350 # endif
05351                             tmpdst = result + length;
05352                             /* Copy backwards, because of overlapping.  */
05353                             tmpsrc += count;
05354                             tmpdst += count;
05355                             for (n = count; n > 0; n--)
05356                               *--tmpdst = (unsigned char) *--tmpsrc;
05357                           }
05358                       }
05359 #endif
05360 
05361 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
05362                     /* Make room for the result.  */
05363                     if (count > allocated - length)
05364                       {
05365                         /* Need at least count elements.  But allocate
05366                            proportionally.  */
05367                         size_t n =
05368                           xmax (xsum (length, count), xtimes (allocated, 2));
05369 
05370                         ENSURE_ALLOCATION (n);
05371                       }
05372 #endif
05373 
05374                     /* Here count <= allocated - length.  */
05375 
05376                     /* Perform padding.  */
05377 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
05378                     if (pad_ourselves && has_width)
05379                       {
05380                         size_t w;
05381 # if ENABLE_UNISTDIO
05382                         /* Outside POSIX, it's preferrable to compare the width
05383                            against the number of _characters_ of the converted
05384                            value.  */
05385                         w = DCHAR_MBSNLEN (result + length, count);
05386 # else
05387                         /* The width is compared against the number of _bytes_
05388                            of the converted value, says POSIX.  */
05389                         w = count;
05390 # endif
05391                         if (w < width)
05392                           {
05393                             size_t pad = width - w;
05394 
05395                             /* Make room for the result.  */
05396                             if (xsum (count, pad) > allocated - length)
05397                               {
05398                                 /* Need at least count + pad elements.  But
05399                                    allocate proportionally.  */
05400                                 size_t n =
05401                                   xmax (xsum3 (length, count, pad),
05402                                         xtimes (allocated, 2));
05403 
05404 # if USE_SNPRINTF
05405                                 length += count;
05406                                 ENSURE_ALLOCATION (n);
05407                                 length -= count;
05408 # else
05409                                 ENSURE_ALLOCATION (n);
05410 # endif
05411                               }
05412                             /* Here count + pad <= allocated - length.  */
05413 
05414                             {
05415 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
05416                               DCHAR_T * const rp = result + length;
05417 # else
05418                               DCHAR_T * const rp = tmp;
05419 # endif
05420                               DCHAR_T *p = rp + count;
05421                               DCHAR_T *end = p + pad;
05422                               DCHAR_T *pad_ptr;
05423 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
05424                               if (dp->conversion == 'c'
05425                                   || dp->conversion == 's')
05426                                 /* No zero-padding for string directives.  */
05427                                 pad_ptr = NULL;
05428                               else
05429 # endif
05430                                 {
05431                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
05432                                   /* No zero-padding of "inf" and "nan".  */
05433                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
05434                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
05435                                     pad_ptr = NULL;
05436                                 }
05437                               /* The generated string now extends from rp to p,
05438                                  with the zero padding insertion point being at
05439                                  pad_ptr.  */
05440 
05441                               count = count + pad; /* = end - rp */
05442 
05443                               if (flags & FLAG_LEFT)
05444                                 {
05445                                   /* Pad with spaces on the right.  */
05446                                   for (; pad > 0; pad--)
05447                                     *p++ = ' ';
05448                                 }
05449                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
05450                                 {
05451                                   /* Pad with zeroes.  */
05452                                   DCHAR_T *q = end;
05453 
05454                                   while (p > pad_ptr)
05455                                     *--q = *--p;
05456                                   for (; pad > 0; pad--)
05457                                     *p++ = '0';
05458                                 }
05459                               else
05460                                 {
05461                                   /* Pad with spaces on the left.  */
05462                                   DCHAR_T *q = end;
05463 
05464                                   while (p > rp)
05465                                     *--q = *--p;
05466                                   for (; pad > 0; pad--)
05467                                     *p++ = ' ';
05468                                 }
05469                             }
05470                           }
05471                       }
05472 #endif
05473 
05474                     /* Here still count <= allocated - length.  */
05475 
05476 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
05477                     /* The snprintf() result did fit.  */
05478 #else
05479                     /* Append the sprintf() result.  */
05480                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
05481 #endif
05482 #if !USE_SNPRINTF
05483                     if (tmp != tmpbuf)
05484                       free (tmp);
05485 #endif
05486 
05487 #if NEED_PRINTF_DIRECTIVE_F
05488                     if (dp->conversion == 'F')
05489                       {
05490                         /* Convert the %f result to upper case for %F.  */
05491                         DCHAR_T *rp = result + length;
05492                         size_t rc;
05493                         for (rc = count; rc > 0; rc--, rp++)
05494                           if (*rp >= 'a' && *rp <= 'z')
05495                             *rp = *rp - 'a' + 'A';
05496                       }
05497 #endif
05498 
05499                     length += count;
05500                     break;
05501                   }
05502 #undef pad_ourselves
05503 #undef prec_ourselves
05504               }
05505           }
05506       }
05507 
05508     /* Add the final NUL.  */
05509     ENSURE_ALLOCATION (xsum (length, 1));
05510     result[length] = '\0';
05511 
05512     if (result != resultbuf && length + 1 < allocated)
05513       {
05514         /* Shrink the allocated memory if possible.  */
05515         DCHAR_T *memory;
05516 
05517         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
05518         if (memory != NULL)
05519           result = memory;
05520       }
05521 
05522     if (buf_malloced != NULL)
05523       free (buf_malloced);
05524     CLEANUP ();
05525     *lengthp = length;
05526     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
05527        says that snprintf() fails with errno = EOVERFLOW in this case, but
05528        that's only because snprintf() returns an 'int'.  This function does
05529        not have this limitation.  */
05530     return result;
05531 
05532 #if USE_SNPRINTF
05533   overflow:
05534     if (!(result == resultbuf || result == NULL))
05535       free (result);
05536     if (buf_malloced != NULL)
05537       free (buf_malloced);
05538     CLEANUP ();
05539     errno = EOVERFLOW;
05540     return NULL;
05541 #endif
05542 
05543   out_of_memory:
05544     if (!(result == resultbuf || result == NULL))
05545       free (result);
05546     if (buf_malloced != NULL)
05547       free (buf_malloced);
05548   out_of_memory_1:
05549     CLEANUP ();
05550     errno = ENOMEM;
05551     return NULL;
05552   }
05553 }
05554 
05555 #undef MAX_ROOM_NEEDED
05556 #undef TCHARS_PER_DCHAR
05557 #undef SNPRINTF
05558 #undef USE_SNPRINTF
05559 #undef DCHAR_SET
05560 #undef DCHAR_CPY
05561 #undef PRINTF_PARSE
05562 #undef DIRECTIVES
05563 #undef DIRECTIVE
05564 #undef DCHAR_IS_TCHAR
05565 #undef TCHAR_T
05566 #undef DCHAR_T
05567 #undef FCHAR_T
05568 #undef VASNPRINTF