~ubuntu-branches/ubuntu/natty/gnutls26/natty

« back to all changes in this revision

Viewing changes to gl/vasnprintf.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Metzler
  • Date: 2009-08-14 19:14:29 UTC
  • mfrom: (1.1.7 upstream) (12.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090814191429-6hovzz3oaqq101rm
Tags: 2.8.3-1
* New upstream version.
  + Stops hardcoding a hard dependency on the versions of gcrypt and tasn it
    was built against. Closes: #540449
  + Fixes CVE-2009-2730, a vulnerability related to NUL bytes in X.509
    certificate name fields. Closes: #541439        GNUTLS-SA-2009-4
    http://lists.gnu.org/archive/html/help-gnutls/2009-08/msg00011.html
* Drop 15_chainverify_expiredcert.diff, included upstream.
* Urgency high, since 541439 applies to testing, too.

Show diffs side-by-side

added added

removed removed

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