Coverage Report

Created: 2025-06-22 06:29

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