~ubuntu-branches/ubuntu/precise/sitecopy/precise

« back to all changes in this revision

Viewing changes to intl/vasnprintf.c

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2008-07-22 07:31:05 UTC
  • mfrom: (1.1.4 upstream) (4.1.7 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080722073105-cbqs1hnc2wvqejfd
Tags: 1:0.16.6-1
* New upstream release
  - fix a crash with progress bar enabled; Closes: #486378
* debian/control
  - set myself as maintainer, Kartik as uploader
  - set Vcs-{Browser,Git} fields
  - bump Standards-Version to 3.8.0
    + debian/README.source added
  - added DM-Upload-Allowed flag
* debian/patches/05_libneon27_transition.dpatch
  - removed since merged upstream
* debian/copyrightdebian/copyright
  - updated upstream email and copyright years
* debian/patches/10_bts410703_preserve_storage_files_sigint.dpatch
  - added to preserve storage files if SIGINT (Ctrl+C) is sent to sitecopy;
    thanks to Andreas Henriksson for the patch; Closes: #410703

Show diffs side-by-side

added added

removed removed

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