Coverage Report

Created: 2026-03-12 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gettext/gettext-tools/libgettextpo/vasnprintf.c
Line
Count
Source
1
/* vsprintf with automatic memory allocation.
2
   Copyright (C) 1999, 2002-2026 Free Software Foundation, Inc.
3
4
   This file is free software: you can redistribute it and/or modify
5
   it under the terms of the GNU Lesser General Public License as
6
   published by the Free Software Foundation; either version 2.1 of the
7
   License, or (at your option) any later version.
8
9
   This file 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
15
   along 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_STRLEN       strlen like function for DCHAR_T[] arrays.
33
     DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
34
     SNPRINTF           The system's snprintf (or similar) function.
35
                        This may be either snprintf or swprintf.
36
     TCHAR_T            The element type of the argument and result string
37
                        of the said SNPRINTF function.  This may be either
38
                        char or wchar_t.  The code exploits that
39
                        sizeof (TCHAR_T) | sizeof (DCHAR_T) and
40
                        alignof (TCHAR_T) <= alignof (DCHAR_T).
41
     DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
42
     DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
43
     DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
44
     DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
45
     DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.
46
     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
47
     ENABLE_WCHAR_FALLBACK  Set to 1 to avoid EILSEQ during conversion of wide
48
                        characters (wchar_t) and wide character strings
49
                        (wchar_t[]) to multibyte sequences.  The fallback is the
50
                        hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or,
51
                        if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn.
52
 */
53
54
/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
55
   This must come before <config.h> because <config.h> may include
56
   <features.h>, and once <features.h> has been included, it's too late.  */
57
#ifndef _GNU_SOURCE
58
# define _GNU_SOURCE    1
59
#endif
60
61
#ifndef VASNPRINTF
62
# include <config.h>
63
#endif
64
65
/* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's
66
   use of CHECK macros expands to code that is too complicated for gcc
67
   -fanalyzer.  Suppress the resulting bogus warnings.  */
68
#if _GL_GNUC_PREREQ (10, 0)
69
# pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
70
#endif
71
72
#include <alloca.h>
73
74
/* Specification.  */
75
#ifndef VASNPRINTF
76
# if WIDE_CHAR_VERSION
77
#  include "vasnwprintf.h"
78
# else
79
#  include "vasnprintf.h"
80
# endif
81
#endif
82
83
#include <locale.h>     /* localeconv() */
84
#include <stdint.h>     /* PTRDIFF_MAX */
85
#include <stdio.h>      /* snprintf(), sprintf() */
86
#include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
87
#include <string.h>     /* memcpy(), strlen() */
88
#include <wchar.h>      /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb(), mbszero() */
89
#include <errno.h>      /* errno */
90
#include <limits.h>     /* CHAR_BIT, INT_MAX, INT_WIDTH, LONG_WIDTH */
91
#include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP, LDBL_MANT_DIG */
92
#if HAVE_NL_LANGINFO || __GLIBC__ >= 2 || defined __CYGWIN__
93
# include <langinfo.h>
94
#endif
95
#ifndef VASNPRINTF
96
# if WIDE_CHAR_VERSION
97
#  include "wprintf-parse.h"
98
# else
99
#  include "printf-parse.h"
100
# endif
101
#endif
102
103
/* Checked size_t computations.  */
104
#include "xsize.h"
105
106
#include "attribute.h"
107
108
#if NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
109
# include <math.h>
110
# include "float+.h"
111
#endif
112
113
#if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
114
# include <math.h>
115
# include "isnand-nolibm.h"
116
#endif
117
118
#if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
119
# include <math.h>
120
# include "isnanl-nolibm.h"
121
# include "fpucw.h"
122
#endif
123
124
#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
125
# include <math.h>
126
# include "isnand-nolibm.h"
127
# include "printf-frexp.h"
128
#endif
129
130
#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
131
# include <math.h>
132
# include "isnanl-nolibm.h"
133
# include "printf-frexpl.h"
134
# include "fpucw.h"
135
#endif
136
137
#if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
138
/* Override macros from fpucw.h.  */
139
# undef DECL_LONG_DOUBLE_ROUNDING
140
# define DECL_LONG_DOUBLE_ROUNDING
141
# undef BEGIN_LONG_DOUBLE_ROUNDING
142
# define BEGIN_LONG_DOUBLE_ROUNDING()
143
# undef END_LONG_DOUBLE_ROUNDING
144
# define END_LONG_DOUBLE_ROUNDING()
145
#endif
146
147
/* Default parameters.  */
148
#ifndef VASNPRINTF
149
# if WIDE_CHAR_VERSION
150
#  define VASNPRINTF vasnwprintf
151
#  define FCHAR_T wchar_t
152
#  define DCHAR_T wchar_t
153
#  define DIRECTIVE wchar_t_directive
154
#  define DIRECTIVES wchar_t_directives
155
#  define PRINTF_PARSE wprintf_parse
156
#  define DCHAR_CPY wmemcpy
157
#  define DCHAR_SET wmemset
158
# else
159
#  define VASNPRINTF vasnprintf
160
#  define FCHAR_T char
161
50.4k
#  define DCHAR_T char
162
18.3k
#  define TCHAR_T char
163
#  define DCHAR_IS_TCHAR 1
164
9.16k
#  define DIRECTIVE char_directive
165
9.16k
#  define DIRECTIVES char_directives
166
9.16k
#  define PRINTF_PARSE printf_parse
167
18.3k
#  define DCHAR_CPY memcpy
168
0
#  define DCHAR_SET memset
169
# endif
170
#endif
171
#if WIDE_CHAR_VERSION
172
  /* DCHAR_T is wchar_t.  */
173
# if HAVE_DECL__SNWPRINTF || (HAVE_SWPRINTF && HAVE_WORKING_SWPRINTF)
174
#  define TCHAR_T wchar_t
175
#  define DCHAR_IS_TCHAR 1
176
#  define USE_SNPRINTF 1
177
#  if HAVE_DECL__SNWPRINTF
178
    /* On Windows, the function swprintf() has a different signature than
179
       on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
180
       instead.  The mingw function snwprintf() has fewer bugs than the
181
       MSVCRT function _snwprintf(), so prefer that.  */
182
#   if defined __MINGW32__
183
#    define SNPRINTF snwprintf
184
#   else
185
#    define SNPRINTF _snwprintf
186
#    define USE_MSVC__SNPRINTF 1
187
#   endif
188
#  else
189
    /* Unix.  */
190
#   define SNPRINTF swprintf
191
#  endif
192
# else
193
   /* Old platforms such as NetBSD 3.0, OpenBSD 3.8, HP-UX 11.00.  */
194
#   define TCHAR_T char
195
# endif
196
#endif
197
#ifndef DCHAR_STRLEN
198
# if WIDE_CHAR_VERSION
199
#  define DCHAR_STRLEN local_wcslen
200
# else
201
#  define DCHAR_STRLEN strlen
202
# endif
203
#endif
204
#ifndef DCHAR_MBSNLEN
205
# if WIDE_CHAR_VERSION
206
#  define DCHAR_MBSNLEN wcsnlen
207
# else
208
#  define DCHAR_MBSNLEN mbsnlen
209
# endif
210
#endif
211
#if !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR
212
  /* TCHAR_T is char.  */
213
  /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
214
     But don't use it on BeOS, since BeOS snprintf produces no output if the
215
     size argument is >= 0x3000000.
216
     Also don't use it on Linux libc5, since there snprintf with size = 1
217
     writes any output without bounds, like sprintf.  */
218
# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
219
#  define USE_SNPRINTF 1
220
# else
221
#  define USE_SNPRINTF 0
222
# endif
223
# if HAVE_DECL__SNPRINTF
224
   /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
225
      function _snprintf(), so prefer that.  */
226
#  if defined __MINGW32__
227
#   define SNPRINTF snprintf
228
    /* Here we need to call the native snprintf, not rpl_snprintf.  */
229
#   undef snprintf
230
#  else
231
    /* MSVC versions < 14 did not have snprintf, only _snprintf.  */
232
#   define SNPRINTF _snprintf
233
#   define USE_MSVC__SNPRINTF 1
234
#  endif
235
# else
236
   /* Unix.  */
237
0
#  define SNPRINTF snprintf
238
   /* Here we need to call the native snprintf, not rpl_snprintf.  */
239
#  undef snprintf
240
# endif
241
#endif
242
/* Here we need to call the native sprintf, not rpl_sprintf.  */
243
#undef sprintf
244
245
/* macOS 12's "warning: 'sprintf' is deprecated" is pointless,
246
   as sprintf is used safely here.  */
247
#if defined __APPLE__ && defined __MACH__ && _GL_GNUC_PREREQ (4, 2)
248
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
249
#endif
250
251
/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
252
   warnings in this file.  Use -Dlint to suppress them.  */
253
#if defined GCC_LINT || defined lint
254
# define IF_LINT(Code) Code
255
#else
256
# define IF_LINT(Code) /* empty */
257
#endif
258
259
/* Here we need only the most basic fields of 'struct lconv', and can
260
   therefore use the system's localeconv() function, without needing a
261
   dependency on module 'localeconv'.  */
262
#undef localeconv
263
264
/* Avoid some warnings from "gcc -Wshadow".
265
   This file doesn't use the exp() and remainder() functions.  */
266
#undef exp
267
#define exp expo
268
#undef remainder
269
#define remainder rem
270
271
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (PTRDIFF_MAX > INT_MAX)) && !WIDE_CHAR_VERSION
272
# if (HAVE_STRNLEN && !defined _AIX)
273
0
#  define local_strnlen strnlen
274
# else
275
#  ifndef local_strnlen_defined
276
#   define local_strnlen_defined 1
277
static size_t
278
local_strnlen (const char *string, size_t maxlen)
279
{
280
  const char *end = memchr (string, '\0', maxlen);
281
  return end ? (size_t) (end - string) : maxlen;
282
}
283
#  endif
284
# endif
285
#endif
286
287
#if ((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)
288
# if HAVE_WCSLEN
289
0
#  define local_wcslen wcslen
290
# else
291
   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
292
      a dependency towards this library, here is a local substitute.
293
      Define this substitute only once, even if this file is included
294
      twice in the same compilation unit.  */
295
#  ifndef local_wcslen_defined
296
#   define local_wcslen_defined 1
297
static size_t
298
local_wcslen (const wchar_t *s)
299
{
300
  const wchar_t *ptr;
301
302
  for (ptr = s; *ptr != (wchar_t) 0; ptr++)
303
    ;
304
  return ptr - s;
305
}
306
#  endif
307
# endif
308
#endif
309
310
#if (!USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION
311
# if HAVE_WCSNLEN && HAVE_DECL_WCSNLEN
312
#  define local_wcsnlen wcsnlen
313
# else
314
#  ifndef local_wcsnlen_defined
315
#   define local_wcsnlen_defined 1
316
static size_t
317
local_wcsnlen (const wchar_t *s, size_t maxlen)
318
{
319
  const wchar_t *ptr;
320
321
  for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
322
    ;
323
  return ptr - s;
324
}
325
#  endif
326
# endif
327
#endif
328
329
#if ((!USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T)) && !WIDE_CHAR_VERSION
330
# if ENABLE_WCHAR_FALLBACK
331
static size_t
332
wctomb_fallback (char *s, wchar_t wc)
333
{
334
  static char const hex[16] = "0123456789ABCDEF";
335
336
  s[0] = '\\';
337
  if (sizeof (wchar_t) > 2 && wc > 0xffff)
338
    {
339
#  if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
340
      s[1] = 'U';
341
#  else
342
      s[1] = 'W';
343
#  endif
344
      s[2] = hex[(wc & 0xf0000000U) >> 28];
345
      s[3] = hex[(wc & 0xf000000U) >> 24];
346
      s[4] = hex[(wc & 0xf00000U) >> 20];
347
      s[5] = hex[(wc & 0xf0000U) >> 16];
348
      s[6] = hex[(wc & 0xf000U) >> 12];
349
      s[7] = hex[(wc & 0xf00U) >> 8];
350
      s[8] = hex[(wc & 0xf0U) >> 4];
351
      s[9] = hex[wc & 0xfU];
352
      return 10;
353
    }
354
  else
355
    {
356
#  if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
357
      s[1] = 'u';
358
#  else
359
      s[1] = 'w';
360
#  endif
361
      s[2] = hex[(wc & 0xf000U) >> 12];
362
      s[3] = hex[(wc & 0xf00U) >> 8];
363
      s[4] = hex[(wc & 0xf0U) >> 4];
364
      s[5] = hex[wc & 0xfU];
365
      return 6;
366
    }
367
}
368
#  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
369
static size_t
370
local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
371
{
372
  size_t count = wcrtomb (s, wc, ps);
373
  if (count == (size_t)(-1))
374
    count = wctomb_fallback (s, wc);
375
  return count;
376
}
377
#  else
378
static int
379
local_wctomb (char *s, wchar_t wc)
380
{
381
  int count = wctomb (s, wc);
382
  if (count < 0)
383
    count = wctomb_fallback (s, wc);
384
  return count;
385
}
386
#   define local_wcrtomb(S, WC, PS)  local_wctomb ((S), (WC))
387
#  endif
388
# else
389
#  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
390
0
#   define local_wcrtomb(S, WC, PS)  wcrtomb ((S), (WC), (PS))
391
#  else
392
#   define local_wcrtomb(S, WC, PS)  wctomb ((S), (WC))
393
#  endif
394
# endif
395
#endif
396
397
#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) || (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
398
/* Determine the decimal-point character according to the current locale.  */
399
# ifndef decimal_point_char_defined
400
#  define decimal_point_char_defined 1
401
static char
402
decimal_point_char (void)
403
{
404
  const char *point;
405
  /* Determine it in a multithread-safe way.  We know nl_langinfo is
406
     multithread-safe on glibc systems and Mac OS X systems, but is not required
407
     to be multithread-safe by POSIX.  sprintf(), however, is multithread-safe.
408
     localeconv() is rarely multithread-safe.  */
409
#  if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
410
  point = nl_langinfo (RADIXCHAR);
411
#  elif 1
412
  char pointbuf[5];
413
  sprintf (pointbuf, "%#.0f", 1.0);
414
  point = &pointbuf[1];
415
#  else
416
  point = localeconv () -> decimal_point;
417
#  endif
418
  /* The decimal point is always a single byte: either '.' or ','.  */
419
  return (point[0] != '\0' ? point[0] : '.');
420
}
421
# endif
422
#endif
423
424
#if (!WIDE_CHAR_VERSION && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE)) || ((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR) && (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT))
425
/* Determine the thousands-separator character according to the current
426
   locale.
427
   It is a single multibyte character.
428
   In glibc: 35x ".", 90x ",", 23x U+202F, 1x U+2019, 1x U+066C, on other
429
   systems also U+00A0.  */
430
# ifndef thousands_separator_char_defined
431
#  define thousands_separator_char_defined 1
432
static const char *
433
thousands_separator_char (char stackbuf[10])
434
{
435
  /* Determine it in a multithread-safe way.
436
     We know nl_langinfo is multithread-safe on glibc systems, on Mac OS X
437
     systems, and on NetBSD, but is not required to be multithread-safe by
438
     POSIX.
439
     localeconv() is not guaranteed to be multithread-safe by POSIX either;
440
     however, on native Windows it is (cf. test-localeconv-mt).
441
     sprintf(), however, is multithread-safe.  */
442
#  if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __NetBSD__)
443
  return nl_langinfo (THOUSEP);
444
#  elif defined _WIN32 && !defined __CYGWIN__
445
  return localeconv () -> thousands_sep;
446
#  else
447
  sprintf (stackbuf, "%'.0f", 1000.0);
448
  /* Now stackbuf = "1<thousep>000".  */
449
  stackbuf[strlen (stackbuf) - 3] = '\0';
450
#   if defined __sun
451
  /* Solaris specific hack: Replace wrong result (0xC2 means U+00A0).  */
452
  if (streq (&stackbuf[1], "\302"))
453
    strcpy (&stackbuf[1], MB_CUR_MAX > 1 ? "\302\240" : "\240");
454
#   endif
455
  return &stackbuf[1];
456
#  endif
457
}
458
# endif
459
#endif
460
#if !WIDE_CHAR_VERSION && defined DCHAR_CONV_FROM_ENCODING && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE)
461
/* Determine the thousands-separator character, as a DCHAR_T[] array,
462
   according to the current locale.
463
   It is a single Unicode character.  */
464
# ifndef thousands_separator_DCHAR_defined
465
#  define thousands_separator_DCHAR_defined 1
466
static const DCHAR_T *
467
thousands_separator_DCHAR (DCHAR_T stackbuf[10])
468
{
469
  /* Determine it in a multithread-safe way.  */
470
  char tmpbuf[10];
471
  const char *tmp = thousands_separator_char (tmpbuf);
472
  if (*tmp != '\0')
473
    {
474
      /* Convert it from char[] to DCHAR_T[].  */
475
      size_t converted_len = 10;
476
      DCHAR_T *converted =
477
        DCHAR_CONV_FROM_ENCODING (locale_charset (),
478
                                  iconveh_question_mark,
479
                                  tmp, strlen (tmp) + 1,
480
                                  NULL,
481
                                  stackbuf, &converted_len);
482
      if (converted != NULL)
483
        {
484
          if (converted != stackbuf)
485
            /* It should not be so long.  */
486
            abort ();
487
          return stackbuf;
488
        }
489
    }
490
  stackbuf[0] = 0;
491
  return stackbuf;
492
}
493
# endif
494
#endif
495
/* Maximum number of 'char' in the char[] or DCHAR_T[] representation of the
496
   thousands separator.  */
497
#define THOUSEP_CHAR_MAXLEN 3
498
499
#if WIDE_CHAR_VERSION && ((NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || ((NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) && DCHAR_IS_TCHAR))
500
/* Determine the thousands-separator character, as a wide character, according
501
   to the current locale.
502
   It is a single wide character.  */
503
# ifndef thousands_separator_wchar_defined
504
#  define thousands_separator_wchar_defined 1
505
static const wchar_t *
506
thousands_separator_wchar (wchar_t stackbuf[10])
507
{
508
#  if __GLIBC__ >= 2 || defined __CYGWIN__
509
  /* On glibc, in the unibyte locale fr_FR, the *wprintf routines use U+202F
510
     as separator, which cannot be represented in the locale encoding.  */
511
  stackbuf[0] =
512
    (wchar_t) (unsigned long) nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC);
513
  stackbuf[1] = L'\0';
514
  return stackbuf;
515
#  elif defined _WIN32 && !defined __CYGWIN__
516
  const char *tmp = localeconv () -> thousands_sep;
517
  if (*tmp != '\0')
518
    {
519
      mbstate_t state;
520
      mbszero (&state);
521
      if ((int) mbrtowc (&stackbuf[0], tmp, strlen (tmp), &state) > 0)
522
        stackbuf[1] = L'\0';
523
      else
524
        stackbuf[0] = L'\0';
525
    }
526
  else
527
    stackbuf[0] = L'\0';
528
  return stackbuf;
529
#  elif defined __sun
530
  /* Use sprintf, because swprintf retrieves a wrong value for the
531
     thousands-separator wide character (e.g. (wchar_t) 0xffffffa0).  */
532
  char tmp[10];
533
  sprintf (tmp, "%'.0f", 1000.0);
534
  /* Now tmp = L"1<thousep>000".  */
535
  tmp[strlen (tmp) - 3] = '\0';
536
  /* Solaris specific hack: Replace wrong result (0xC2 means U+00A0).  */
537
  if (streq (&tmp[1], "\302"))
538
    strcpy (&tmp[1], MB_CUR_MAX > 1 ? "\302\240" : "\240");
539
  if (tmp[1] != '\0')
540
    {
541
      mbstate_t state;
542
      mbszero (&state);
543
      if ((int) mbrtowc (&stackbuf[0], &tmp[1], strlen (&tmp[1]), &state) > 0)
544
        stackbuf[1] = L'\0';
545
      else
546
        stackbuf[0] = L'\0';
547
    }
548
  else
549
    stackbuf[0] = L'\0';
550
  return stackbuf;
551
#  else
552
  swprintf (stackbuf, 10, L"%'.0f", 1000.0);
553
  /* Now stackbuf = L"1<thousep>000".  */
554
  stackbuf[local_wcslen (stackbuf) - 3] = '\0';
555
  return &stackbuf[1];
556
#  endif
557
}
558
# endif
559
#endif
560
/* Maximum number of 'wchar_t' in the wchar_t[] representation of the thousands
561
   separator.  */
562
#define THOUSEP_WCHAR_MAXLEN 1
563
564
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
565
# ifndef grouping_rule_defined
566
#  define grouping_rule_defined 1
567
/* Determine the grouping rule.
568
 * As specified in POSIX
569
 * <https://pubs.opengroup.org/onlinepubs/9799919799/functions/localeconv.html>
570
 * <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap07.html#tag_07_03_04>
571
 * it is a string whose elements are 'signed char' values, where
572
 * "Each integer specifies the number of digits in each group, with the initial
573
 *  integer defining the size of the group immediately preceding the decimal
574
 *  delimiter, and the following integers defining the preceding groups.  If
575
 *  the last integer is not -1, then the size of the previous group (if any)
576
 *  shall be repeatedly used for the remainder of the digits.  If the last
577
 *  integer is -1, then no further grouping shall be performed."
578
 * Platforms that have locales with grouping:
579
 *   glibc, FreeBSD, NetBSD, AIX, Solaris, Cygwin, Haiku.
580
 * Platforms that don't:
581
 *   musl libc, macOS, OpenBSD, Android, mingw, MSVC.
582
 * Typical grouping rules on glibc:
583
 *   136x 3     (fr_FR etc.)
584
 *   4x 4       (cmn_TW etc.)
585
 *   9x 3;2     (ta_IN etc.)
586
 *   1x 2;2;2;3 (umn_US)
587
 *   21x -1     (C etc.)
588
 */
589
static const signed char *
590
grouping_rule (void)
591
{
592
  /* We know nl_langinfo is multithread-safe on glibc systems and on Cygwin,
593
     but is not required to be multithread-safe by POSIX.
594
     localeconv() is not guaranteed to be multithread-safe by POSIX either;
595
     however, on all known systems it is (cf. test-localeconv-mt).  */
596
#  if __GLIBC__ >= 2
597
  return (const signed char *) nl_langinfo (GROUPING);
598
#  elif defined __CYGWIN__
599
  return (const signed char *) nl_langinfo (_NL_NUMERIC_GROUPING);
600
#  else
601
  return (const signed char *) localeconv () -> grouping;
602
#  endif
603
}
604
/* Determines the number of thousands-separators to be inserted in a digit
605
   sequence with ndigits digits (before the decimal point).  */
606
static size_t
607
num_thousands_separators (const signed char *grouping, size_t ndigits)
608
{
609
  const signed char *g = grouping;
610
  int h = *g;
611
  if (h <= 0 || ndigits == 0)
612
    return 0;
613
  size_t insert = 0;
614
  for (;;)
615
    {
616
      /* Invariant: here h == *g, h > 0, ndigits > 0.  */
617
      if (g[1] == 0)
618
        /* h repeats endlessly.  */
619
        return insert + (ndigits - 1) / h;
620
      /* h does not repeat.  */
621
      if (ndigits <= h)
622
        return insert;
623
      ndigits -= h;
624
      insert++;
625
      g++;
626
      h = *g;
627
      if (h < 0)
628
        /* No further grouping.  */
629
        return insert;
630
    }
631
}
632
# endif
633
#endif
634
635
#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE
636
637
/* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
638
static int
639
is_infinite_or_zero (double x)
640
{
641
  return isnand (x) || x + x == x;
642
}
643
644
#endif
645
646
#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE
647
648
/* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
649
static int
650
is_infinite_or_zerol (long double x)
651
{
652
  return isnanl (x) || x + x == x;
653
}
654
655
#endif
656
657
#if NEED_PRINTF_LONG_DOUBLE
658
659
/* Like frexpl, except that it supports even "unsupported" numbers.  */
660
# if (LDBL_MANT_DIG == 64 && (defined __ia64 || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))) && (defined __APPLE__ && defined __MACH__)
661
/* Don't assume that frexpl can handle pseudo-denormals; it does not on
662
   macOS 12/x86_64.  Therefore test for a pseudo-denormal explicitly.  */
663
664
static
665
long double safe_frexpl (long double x, int *exp)
666
{
667
  union
668
    {
669
      long double value;
670
      struct { unsigned int mant_word[2]; unsigned short sign_exp_word; } r;
671
    }
672
  u;
673
  u.value = x;
674
  if (u.r.sign_exp_word == 0 && (u.r.mant_word[1] & 0x80000000u) != 0)
675
    {
676
      /* Pseudo-Denormal.  */
677
      *exp = LDBL_MIN_EXP;
678
      u.r.sign_exp_word = 1 - LDBL_MIN_EXP;
679
      return u.value;
680
    }
681
  else
682
    return frexpl (x, exp);
683
}
684
685
# else
686
#  define safe_frexpl frexpl
687
# endif
688
689
#endif
690
691
#if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE
692
693
/* An indicator for a failed memory allocation.  */
694
# define NOMEM_PTR ((void *) (-1))
695
696
/* Converting 'long double' to decimal without rare rounding bugs requires
697
   real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
698
   (and slower) algorithms.  */
699
700
typedef unsigned int mp_limb_t;
701
# define GMP_LIMB_BITS 32
702
static_assert (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
703
704
typedef unsigned long long mp_twolimb_t;
705
# define GMP_TWOLIMB_BITS 64
706
static_assert (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
707
708
/* Representation of a bignum >= 0.  */
709
typedef struct
710
{
711
  size_t nlimbs;
712
  mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  */
713
} mpn_t;
714
715
/* Compute the product of two bignums >= 0.
716
   Return the allocated memory (possibly NULL) in case of success, NOMEM_PTR
717
   in case of memory allocation failure.  */
718
static void *
719
multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
720
{
721
  const mp_limb_t *p1;
722
  const mp_limb_t *p2;
723
  size_t len1;
724
  size_t len2;
725
726
  if (src1.nlimbs <= src2.nlimbs)
727
    {
728
      len1 = src1.nlimbs;
729
      p1 = src1.limbs;
730
      len2 = src2.nlimbs;
731
      p2 = src2.limbs;
732
    }
733
  else
734
    {
735
      len1 = src2.nlimbs;
736
      p1 = src2.limbs;
737
      len2 = src1.nlimbs;
738
      p2 = src1.limbs;
739
    }
740
  /* Now 0 <= len1 <= len2.  */
741
  if (len1 == 0)
742
    {
743
      /* src1 or src2 is zero.  */
744
      dest->nlimbs = 0;
745
      dest->limbs = NULL;
746
    }
747
  else
748
    {
749
      /* Here 1 <= len1 <= len2.  */
750
      size_t dlen;
751
      mp_limb_t *dp;
752
753
      dlen = len1 + len2;
754
      dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
755
      if (dp == NULL)
756
        return NOMEM_PTR;
757
      for (size_t k = len2; k > 0; )
758
        dp[--k] = 0;
759
      for (size_t i = 0; i < len1; i++)
760
        {
761
          mp_limb_t digit1 = p1[i];
762
          mp_twolimb_t carry = 0;
763
          for (size_t j = 0; j < len2; j++)
764
            {
765
              mp_limb_t digit2 = p2[j];
766
              carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
767
              carry += dp[i + j];
768
              dp[i + j] = (mp_limb_t) carry;
769
              carry = carry >> GMP_LIMB_BITS;
770
            }
771
          dp[i + len2] = (mp_limb_t) carry;
772
        }
773
      /* Normalise.  */
774
      while (dlen > 0 && dp[dlen - 1] == 0)
775
        dlen--;
776
      dest->nlimbs = dlen;
777
      dest->limbs = dp;
778
    }
779
  return dest->limbs;
780
}
781
782
/* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
783
   a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
784
   the remainder.
785
   Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
786
   q is incremented.
787
   Return the allocated memory (possibly NULL) in case of success, NOMEM_PTR
788
   in case of memory allocation failure.  */
789
static void *
790
divide (mpn_t a, mpn_t b, mpn_t *q)
791
{
792
  /* Algorithm:
793
     First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
794
     with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
795
     If m<n, then q:=0 and r:=a.
796
     If m>=n=1, perform a single-precision division:
797
       r:=0, j:=m,
798
       while j>0 do
799
         {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
800
               = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
801
         j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
802
       Normalise [q[m-1],...,q[0]], yields q.
803
     If m>=n>1, perform a multiple-precision division:
804
       We have a/b < beta^(m-n+1).
805
       s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
806
       Shift a and b left by s bits, copying them. r:=a.
807
       r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
808
       For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
809
         Compute q* :
810
           q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
811
           In case of overflow (q* >= beta) set q* := beta-1.
812
           Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
813
           and c3 := b[n-2] * q*.
814
           {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
815
            occurred.  Furthermore 0 <= c3 < beta^2.
816
            If there was overflow and
817
            r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
818
            the next test can be skipped.}
819
           While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
820
             Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
821
           If q* > 0:
822
             Put r := r - b * q* * beta^j. In detail:
823
               [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
824
               hence: u:=0, for i:=0 to n-1 do
825
                              u := u + q* * b[i],
826
                              r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
827
                              u:=u div beta (+ 1, if carry in subtraction)
828
                      r[n+j]:=r[n+j]-u.
829
               {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
830
                               < q* + 1 <= beta,
831
                the carry u does not overflow.}
832
             If a negative carry occurs, put q* := q* - 1
833
               and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
834
         Set q[j] := q*.
835
       Normalise [q[m-n],..,q[0]]; this yields the quotient q.
836
       Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
837
       rest r.
838
       The room for q[j] can be allocated at the memory location of r[n+j].
839
     Finally, round-to-even:
840
       Shift r left by 1 bit.
841
       If r > b or if r = b and q[0] is odd, q := q+1.
842
   */
843
  const mp_limb_t *a_ptr = a.limbs;
844
  size_t a_len = a.nlimbs;
845
  const mp_limb_t *b_ptr = b.limbs;
846
  size_t b_len = b.nlimbs;
847
  mp_limb_t *tmp_roomptr = NULL;
848
  mp_limb_t *q_ptr;
849
  size_t q_len;
850
  mp_limb_t *r_ptr;
851
  size_t r_len;
852
853
  /* Allocate room for a_len+2 digits.
854
     (Need a_len+1 digits for the real division and 1 more digit for the
855
     final rounding of q.)  */
856
  mp_limb_t *roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
857
  if (roomptr == NULL)
858
    return NOMEM_PTR;
859
860
  /* Normalise a.  */
861
  while (a_len > 0 && a_ptr[a_len - 1] == 0)
862
    a_len--;
863
864
  /* Normalise b.  */
865
  for (;;)
866
    {
867
      if (b_len == 0)
868
        /* Division by zero.  */
869
        abort ();
870
      if (b_ptr[b_len - 1] == 0)
871
        b_len--;
872
      else
873
        break;
874
    }
875
876
  /* Here m = a_len >= 0 and n = b_len > 0.  */
877
878
  if (a_len < b_len)
879
    {
880
      /* m<n: trivial case.  q=0, r := copy of a.  */
881
      r_ptr = roomptr;
882
      r_len = a_len;
883
      memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
884
      q_ptr = roomptr + a_len;
885
      q_len = 0;
886
    }
887
  else if (b_len == 1)
888
    {
889
      /* n=1: single precision division.
890
         beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
891
      r_ptr = roomptr;
892
      q_ptr = roomptr + 1;
893
      {
894
        mp_limb_t den = b_ptr[0];
895
        mp_limb_t remainder = 0;
896
        const mp_limb_t *sourceptr = a_ptr + a_len;
897
        mp_limb_t *destptr = q_ptr + a_len;
898
        for (size_t count = a_len; count > 0; count--)
899
          {
900
            mp_twolimb_t num =
901
              ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
902
            *--destptr = num / den;
903
            remainder = num % den;
904
          }
905
        /* Normalise and store r.  */
906
        if (remainder > 0)
907
          {
908
            r_ptr[0] = remainder;
909
            r_len = 1;
910
          }
911
        else
912
          r_len = 0;
913
        /* Normalise q.  */
914
        q_len = a_len;
915
        if (q_ptr[q_len - 1] == 0)
916
          q_len--;
917
      }
918
    }
919
  else
920
    {
921
      /* n>1: multiple precision division.
922
         beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
923
         beta^(m-n-1) <= a/b < beta^(m-n+1).  */
924
      /* Determine s.  */
925
      size_t s;
926
      {
927
        mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
928
        /* Determine s = GMP_LIMB_BITS - integer_length (msd).
929
           Code copied from gnulib's integer_length.c.  */
930
# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
931
     || (__clang_major__ >= 4)
932
        s = __builtin_clz (msd);
933
# else
934
#  if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
935
        if (GMP_LIMB_BITS <= DBL_MANT_BIT)
936
          {
937
            /* Use 'double' operations.
938
               Assumes an IEEE 754 'double' implementation.  */
939
#   define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
940
#   define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
941
#   define NWORDS \
942
     ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
943
            union { double value; unsigned int word[NWORDS]; } m;
944
945
            /* Use a single integer to floating-point conversion.  */
946
            m.value = msd;
947
948
            s = GMP_LIMB_BITS
949
                - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
950
                   - DBL_EXP_BIAS);
951
          }
952
        else
953
#   undef NWORDS
954
#  endif
955
          {
956
            s = 31;
957
            if (msd >= 0x10000)
958
              {
959
                msd = msd >> 16;
960
                s -= 16;
961
              }
962
            if (msd >= 0x100)
963
              {
964
                msd = msd >> 8;
965
                s -= 8;
966
              }
967
            if (msd >= 0x10)
968
              {
969
                msd = msd >> 4;
970
                s -= 4;
971
              }
972
            if (msd >= 0x4)
973
              {
974
                msd = msd >> 2;
975
                s -= 2;
976
              }
977
            if (msd >= 0x2)
978
              {
979
                msd = msd >> 1;
980
                s -= 1;
981
              }
982
          }
983
# endif
984
      }
985
      /* 0 <= s < GMP_LIMB_BITS.
986
         Copy b, shifting it left by s bits.  */
987
      if (s > 0)
988
        {
989
          tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
990
          if (tmp_roomptr == NULL)
991
            {
992
              free (roomptr);
993
              return NOMEM_PTR;
994
            }
995
          {
996
            const mp_limb_t *sourceptr = b_ptr;
997
            mp_limb_t *destptr = tmp_roomptr;
998
            mp_twolimb_t accu = 0;
999
            for (size_t count = b_len; count > 0; count--)
1000
              {
1001
                accu += (mp_twolimb_t) *sourceptr++ << s;
1002
                *destptr++ = (mp_limb_t) accu;
1003
                accu = accu >> GMP_LIMB_BITS;
1004
              }
1005
            /* accu must be zero, since that was how s was determined.  */
1006
            if (accu != 0)
1007
              abort ();
1008
          }
1009
          b_ptr = tmp_roomptr;
1010
        }
1011
      /* Copy a, shifting it left by s bits, yields r.
1012
         Memory layout:
1013
         At the beginning: r = roomptr[0..a_len],
1014
         at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
1015
      r_ptr = roomptr;
1016
      if (s == 0)
1017
        {
1018
          memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
1019
          r_ptr[a_len] = 0;
1020
        }
1021
      else
1022
        {
1023
          const mp_limb_t *sourceptr = a_ptr;
1024
          mp_limb_t *destptr = r_ptr;
1025
          mp_twolimb_t accu = 0;
1026
          for (size_t count = a_len; count > 0; count--)
1027
            {
1028
              accu += (mp_twolimb_t) *sourceptr++ << s;
1029
              *destptr++ = (mp_limb_t) accu;
1030
              accu = accu >> GMP_LIMB_BITS;
1031
            }
1032
          *destptr++ = (mp_limb_t) accu;
1033
        }
1034
      q_ptr = roomptr + b_len;
1035
      q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
1036
      {
1037
        size_t j = a_len - b_len; /* m-n */
1038
        mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
1039
        mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
1040
        mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
1041
          ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
1042
        /* Division loop, traversed m-n+1 times.
1043
           j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
1044
        for (;;)
1045
          {
1046
            mp_limb_t q_star;
1047
            mp_limb_t c1;
1048
            if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
1049
              {
1050
                /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
1051
                mp_twolimb_t num =
1052
                  ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
1053
                  | r_ptr[j + b_len - 1];
1054
                q_star = num / b_msd;
1055
                c1 = num % b_msd;
1056
              }
1057
            else
1058
              {
1059
                /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
1060
                q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
1061
                /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
1062
                   <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
1063
                   <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
1064
                        {<= beta !}.
1065
                   If yes, jump directly to the subtraction loop.
1066
                   (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
1067
                    <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
1068
                if (r_ptr[j + b_len] > b_msd
1069
                    || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
1070
                  /* r[j+n] >= b[n-1]+1 or
1071
                     r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
1072
                     carry.  */
1073
                  goto subtract;
1074
              }
1075
            /* q_star = q*,
1076
               c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
1077
            {
1078
              mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
1079
                ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
1080
              mp_twolimb_t c3 = /* b[n-2] * q* */
1081
                (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
1082
              /* While c2 < c3, increase c2 and decrease c3.
1083
                 Consider c3-c2.  While it is > 0, decrease it by
1084
                 b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
1085
                 this can happen only twice.  */
1086
              if (c3 > c2)
1087
                {
1088
                  q_star = q_star - 1; /* q* := q* - 1 */
1089
                  if (c3 - c2 > b_msdd)
1090
                    q_star = q_star - 1; /* q* := q* - 1 */
1091
                }
1092
            }
1093
            if (q_star > 0)
1094
              subtract:
1095
              {
1096
                /* Subtract r := r - b * q* * beta^j.  */
1097
                mp_limb_t cr;
1098
                {
1099
                  const mp_limb_t *sourceptr = b_ptr;
1100
                  mp_limb_t *destptr = r_ptr + j;
1101
                  mp_twolimb_t carry = 0;
1102
                  for (size_t count = b_len; count > 0; count--)
1103
                    {
1104
                      /* Here 0 <= carry <= q*.  */
1105
                      carry =
1106
                        carry
1107
                        + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
1108
                        + (mp_limb_t) ~(*destptr);
1109
                      /* Here 0 <= carry <= beta*q* + beta-1.  */
1110
                      *destptr++ = ~(mp_limb_t) carry;
1111
                      carry = carry >> GMP_LIMB_BITS; /* <= q* */
1112
                    }
1113
                  cr = (mp_limb_t) carry;
1114
                }
1115
                /* Subtract cr from r_ptr[j + b_len], then forget about
1116
                   r_ptr[j + b_len].  */
1117
                if (cr > r_ptr[j + b_len])
1118
                  {
1119
                    /* Subtraction gave a carry.  */
1120
                    q_star = q_star - 1; /* q* := q* - 1 */
1121
                    /* Add b back.  */
1122
                    {
1123
                      const mp_limb_t *sourceptr = b_ptr;
1124
                      mp_limb_t *destptr = r_ptr + j;
1125
                      mp_limb_t carry = 0;
1126
                      for (size_t count = b_len; count > 0; count--)
1127
                        {
1128
                          mp_limb_t source1 = *sourceptr++;
1129
                          mp_limb_t source2 = *destptr;
1130
                          *destptr++ = source1 + source2 + carry;
1131
                          carry =
1132
                            (carry
1133
                             ? source1 >= (mp_limb_t) ~source2
1134
                             : source1 > (mp_limb_t) ~source2);
1135
                        }
1136
                    }
1137
                    /* Forget about the carry and about r[j+n].  */
1138
                  }
1139
              }
1140
            /* q* is determined.  Store it as q[j].  */
1141
            q_ptr[j] = q_star;
1142
            if (j == 0)
1143
              break;
1144
            j--;
1145
          }
1146
      }
1147
      r_len = b_len;
1148
      /* Normalise q.  */
1149
      if (q_ptr[q_len - 1] == 0)
1150
        q_len--;
1151
# if 0 /* Not needed here, since we need r only to compare it with b/2, and
1152
          b is shifted left by s bits.  */
1153
      /* Shift r right by s bits.  */
1154
      if (s > 0)
1155
        {
1156
          mp_limb_t ptr = r_ptr + r_len;
1157
          mp_twolimb_t accu = 0;
1158
          for (size_t count = r_len; count > 0; count--)
1159
            {
1160
              accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
1161
              accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
1162
              *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
1163
            }
1164
        }
1165
# endif
1166
      /* Normalise r.  */
1167
      while (r_len > 0 && r_ptr[r_len - 1] == 0)
1168
        r_len--;
1169
    }
1170
  /* Compare r << 1 with b.  */
1171
  if (r_len > b_len)
1172
    goto increment_q;
1173
  for (size_t i = b_len;;)
1174
    {
1175
      mp_limb_t r_i =
1176
        (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
1177
        | (i < r_len ? r_ptr[i] << 1 : 0);
1178
      mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
1179
      if (r_i > b_i)
1180
        goto increment_q;
1181
      if (r_i < b_i)
1182
        goto keep_q;
1183
      if (i == 0)
1184
        break;
1185
      i--;
1186
    }
1187
  if (q_len > 0 && ((q_ptr[0] & 1) != 0))
1188
    /* q is odd.  */
1189
    increment_q:
1190
    {
1191
      for (size_t i = 0; i < q_len; i++)
1192
        if (++(q_ptr[i]) != 0)
1193
          goto keep_q;
1194
      q_ptr[q_len++] = 1;
1195
    }
1196
  keep_q:
1197
  free (tmp_roomptr);
1198
  q->limbs = q_ptr;
1199
  q->nlimbs = q_len;
1200
  return roomptr;
1201
}
1202
1203
/* Avoid pointless GCC warning "argument 1 value '18446744073709551615' exceeds
1204
   maximum object size 9223372036854775807", triggered by the use of xsum as
1205
   argument of malloc.  */
1206
# if _GL_GNUC_PREREQ (7, 0)
1207
#  pragma GCC diagnostic push
1208
#  pragma GCC diagnostic ignored "-Walloc-size-larger-than="
1209
# endif
1210
1211
/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
1212
   representation.
1213
   Destroys the contents of a.
1214
   Return the allocated memory - containing the decimal digits in low-to-high
1215
   order, terminated with a NUL character - in case of success, NULL in case
1216
   of memory allocation failure.  */
1217
static char *
1218
convert_to_decimal (mpn_t a, size_t extra_zeroes)
1219
{
1220
  mp_limb_t *a_ptr = a.limbs;
1221
  size_t a_len = a.nlimbs;
1222
  /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
1223
  size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
1224
  /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the
1225
     digits of a, followed by 1 byte for the terminating NUL.  */
1226
  char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1));
1227
  if (c_ptr != NULL)
1228
    {
1229
      char *d_ptr = c_ptr;
1230
      for (; extra_zeroes > 0; extra_zeroes--)
1231
        *d_ptr++ = '0';
1232
      while (a_len > 0)
1233
        {
1234
          /* Divide a by 10^9, in-place.  */
1235
          mp_limb_t remainder = 0;
1236
          mp_limb_t *ptr = a_ptr + a_len;
1237
          for (size_t count = a_len; count > 0; count--)
1238
            {
1239
              mp_twolimb_t num =
1240
                ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
1241
              *ptr = num / 1000000000;
1242
              remainder = num % 1000000000;
1243
            }
1244
          /* Store the remainder as 9 decimal digits.  */
1245
          for (size_t count = 9; count > 0; count--)
1246
            {
1247
              *d_ptr++ = '0' + (remainder % 10);
1248
              remainder = remainder / 10;
1249
            }
1250
          /* Normalize a.  */
1251
          if (a_ptr[a_len - 1] == 0)
1252
            a_len--;
1253
        }
1254
      /* Remove leading zeroes.  */
1255
      while (d_ptr > c_ptr && d_ptr[-1] == '0')
1256
        d_ptr--;
1257
      /* But keep at least one zero.  */
1258
      if (d_ptr == c_ptr)
1259
        *d_ptr++ = '0';
1260
      /* Terminate the string.  */
1261
      *d_ptr = '\0';
1262
    }
1263
  return c_ptr;
1264
}
1265
1266
# if _GL_GNUC_PREREQ (7, 0)
1267
#  pragma GCC diagnostic pop
1268
# endif
1269
1270
# if NEED_PRINTF_LONG_DOUBLE
1271
1272
/* Assuming x is finite and >= 0:
1273
   write x as x = 2^e * m, where m is a bignum.
1274
   Return the allocated memory in case of success, NULL in case of memory
1275
   allocation failure.  */
1276
static void *
1277
decode_long_double (long double x, int *ep, mpn_t *mp)
1278
{
1279
  /* Allocate memory for result.  */
1280
  mpn_t m;
1281
  m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
1282
  m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
1283
  if (m.limbs == NULL)
1284
    return NULL;
1285
  /* Split into exponential part and mantissa.  */
1286
  int exp;
1287
  long double y = safe_frexpl (x, &exp);
1288
  if (!(y >= 0.0L && y < 1.0L))
1289
    abort ();
1290
  /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
1291
     latter is an integer.  */
1292
  /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
1293
     I'm not sure whether it's safe to cast a 'long double' value between
1294
     2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1295
     'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1296
     doesn't matter).  */
1297
#  if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
1298
#   if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1299
    {
1300
      mp_limb_t hi, lo;
1301
      y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1302
      hi = (int) y;
1303
      y -= hi;
1304
      if (!(y >= 0.0L && y < 1.0L))
1305
        abort ();
1306
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1307
      lo = (int) y;
1308
      y -= lo;
1309
      if (!(y >= 0.0L && y < 1.0L))
1310
        abort ();
1311
      m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1312
    }
1313
#   else
1314
    {
1315
      mp_limb_t d;
1316
      y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
1317
      d = (int) y;
1318
      y -= d;
1319
      if (!(y >= 0.0L && y < 1.0L))
1320
        abort ();
1321
      m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
1322
    }
1323
#   endif
1324
#  endif
1325
  for (size_t i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1326
    {
1327
      mp_limb_t hi, lo;
1328
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1329
      hi = (int) y;
1330
      y -= hi;
1331
      if (!(y >= 0.0L && y < 1.0L))
1332
        abort ();
1333
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1334
      lo = (int) y;
1335
      y -= lo;
1336
      if (!(y >= 0.0L && y < 1.0L))
1337
        abort ();
1338
      m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1339
    }
1340
#  if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
1341
           precision.  */
1342
  if (!(y == 0.0L))
1343
    abort ();
1344
#  endif
1345
  /* Normalise.  */
1346
  while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1347
    m.nlimbs--;
1348
  *mp = m;
1349
  *ep = exp - LDBL_MANT_BIT;
1350
  return m.limbs;
1351
}
1352
1353
# endif
1354
1355
# if NEED_PRINTF_DOUBLE
1356
1357
/* Assuming x is finite and >= 0:
1358
   write x as x = 2^e * m, where m is a bignum.
1359
   Return the allocated memory in case of success, NULL in case of memory
1360
   allocation failure.  */
1361
static void *
1362
decode_double (double x, int *ep, mpn_t *mp)
1363
{
1364
  /* Allocate memory for result.  */
1365
  mpn_t m;
1366
  m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
1367
  m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
1368
  if (m.limbs == NULL)
1369
    return NULL;
1370
  /* Split into exponential part and mantissa.  */
1371
  int exp;
1372
  double y = frexp (x, &exp);
1373
  if (!(y >= 0.0 && y < 1.0))
1374
    abort ();
1375
  /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
1376
     latter is an integer.  */
1377
  /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
1378
     I'm not sure whether it's safe to cast a 'double' value between
1379
     2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1380
     'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1381
     doesn't matter).  */
1382
#  if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
1383
#   if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1384
    {
1385
      mp_limb_t hi, lo;
1386
      y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1387
      hi = (int) y;
1388
      y -= hi;
1389
      if (!(y >= 0.0 && y < 1.0))
1390
        abort ();
1391
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1392
      lo = (int) y;
1393
      y -= lo;
1394
      if (!(y >= 0.0 && y < 1.0))
1395
        abort ();
1396
      m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1397
    }
1398
#   else
1399
    {
1400
      mp_limb_t d;
1401
      y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1402
      d = (int) y;
1403
      y -= d;
1404
      if (!(y >= 0.0 && y < 1.0))
1405
        abort ();
1406
      m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1407
    }
1408
#   endif
1409
#  endif
1410
  for (size_t i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1411
    {
1412
      mp_limb_t hi, lo;
1413
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1414
      hi = (int) y;
1415
      y -= hi;
1416
      if (!(y >= 0.0 && y < 1.0))
1417
        abort ();
1418
      y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1419
      lo = (int) y;
1420
      y -= lo;
1421
      if (!(y >= 0.0 && y < 1.0))
1422
        abort ();
1423
      m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1424
    }
1425
  if (!(y == 0.0))
1426
    abort ();
1427
  /* Normalise.  */
1428
  while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1429
    m.nlimbs--;
1430
  *mp = m;
1431
  *ep = exp - DBL_MANT_BIT;
1432
  return m.limbs;
1433
}
1434
1435
# endif
1436
1437
/* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1438
   Returns the decimal representation of round (x * 10^n).
1439
   Return the allocated memory - containing the decimal digits in low-to-high
1440
   order, terminated with a NUL character - in case of success, NULL in case
1441
   of memory allocation failure.  */
1442
static char *
1443
scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1444
{
1445
  /* x = 2^e * m, hence
1446
     y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1447
       = round (2^s * 5^n * m).  */
1448
  int s = e + n;
1449
  size_t extra_zeroes = 0;
1450
  /* Factor out a common power of 10 if possible.  */
1451
  if (s > 0 && n > 0)
1452
    {
1453
      extra_zeroes = (s < n ? s : n);
1454
      s -= extra_zeroes;
1455
      n -= extra_zeroes;
1456
    }
1457
  /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1458
     Before converting to decimal, we need to compute
1459
     z = round (2^s * 5^n * m).  */
1460
  /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1461
     sign.  2.322 is slightly larger than log(5)/log(2).  */
1462
  unsigned int abs_n = (n >= 0 ? n : -n);
1463
  unsigned int abs_s = (s >= 0 ? s : -s);
1464
  mp_limb_t *pow5_ptr =
1465
    (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1466
                           + abs_s / GMP_LIMB_BITS + 1)
1467
                          * sizeof (mp_limb_t));
1468
  if (pow5_ptr == NULL)
1469
    {
1470
      free (memory);
1471
      return NULL;
1472
    }
1473
  /* Initialize with 1.  */
1474
  pow5_ptr[0] = 1;
1475
  size_t pow5_len = 1;
1476
  /* Multiply with 5^|n|.  */
1477
  if (abs_n > 0)
1478
    {
1479
      static mp_limb_t const small_pow5[13 + 1] =
1480
        {
1481
          1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1482
          48828125, 244140625, 1220703125
1483
        };
1484
      for (unsigned int n13 = 0; n13 <= abs_n; n13 += 13)
1485
        {
1486
          mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1487
          mp_twolimb_t carry = 0;
1488
          for (size_t j = 0; j < pow5_len; j++)
1489
            {
1490
              mp_limb_t digit2 = pow5_ptr[j];
1491
              carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1492
              pow5_ptr[j] = (mp_limb_t) carry;
1493
              carry = carry >> GMP_LIMB_BITS;
1494
            }
1495
          if (carry > 0)
1496
            pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1497
        }
1498
    }
1499
  unsigned int s_limbs = abs_s / GMP_LIMB_BITS;
1500
  unsigned int s_bits = abs_s % GMP_LIMB_BITS;
1501
  mpn_t pow5;
1502
  mpn_t z;
1503
  void *z_memory;
1504
  if (n >= 0 ? s >= 0 : s <= 0)
1505
    {
1506
      /* Multiply with 2^|s|.  */
1507
      if (s_bits > 0)
1508
        {
1509
          mp_limb_t *ptr = pow5_ptr;
1510
          mp_twolimb_t accu = 0;
1511
          for (size_t count = pow5_len; count > 0; count--)
1512
            {
1513
              accu += (mp_twolimb_t) *ptr << s_bits;
1514
              *ptr++ = (mp_limb_t) accu;
1515
              accu = accu >> GMP_LIMB_BITS;
1516
            }
1517
          if (accu > 0)
1518
            {
1519
              *ptr = (mp_limb_t) accu;
1520
              pow5_len++;
1521
            }
1522
        }
1523
      if (s_limbs > 0)
1524
        {
1525
          for (size_t count = pow5_len; count > 0;)
1526
            {
1527
              count--;
1528
              pow5_ptr[s_limbs + count] = pow5_ptr[count];
1529
            }
1530
          for (size_t count = s_limbs; count > 0;)
1531
            {
1532
              count--;
1533
              pow5_ptr[count] = 0;
1534
            }
1535
          pow5_len += s_limbs;
1536
        }
1537
      pow5.limbs = pow5_ptr;
1538
      pow5.nlimbs = pow5_len;
1539
      if (n >= 0)
1540
        {
1541
          /* Multiply m with pow5.  No division needed.  */
1542
          z_memory = multiply (m, pow5, &z);
1543
        }
1544
      else
1545
        {
1546
          /* Divide m by pow5 and round.  */
1547
          z_memory = divide (m, pow5, &z);
1548
        }
1549
    }
1550
  else
1551
    {
1552
      pow5.limbs = pow5_ptr;
1553
      pow5.nlimbs = pow5_len;
1554
      if (n >= 0)
1555
        {
1556
          /* n >= 0, s < 0.
1557
             Multiply m with pow5, then divide by 2^|s|.  */
1558
          mpn_t numerator;
1559
          mpn_t denominator;
1560
          void *tmp_memory;
1561
          tmp_memory = multiply (m, pow5, &numerator);
1562
          if (tmp_memory == NOMEM_PTR)
1563
            {
1564
              free (pow5_ptr);
1565
              free (memory);
1566
              return NULL;
1567
            }
1568
          /* Construct 2^|s|.  */
1569
          {
1570
            mp_limb_t *ptr = pow5_ptr + pow5_len;
1571
            for (size_t i = 0; i < s_limbs; i++)
1572
              ptr[i] = 0;
1573
            ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1574
            denominator.limbs = ptr;
1575
            denominator.nlimbs = s_limbs + 1;
1576
          }
1577
          z_memory = divide (numerator, denominator, &z);
1578
          free (tmp_memory);
1579
        }
1580
      else
1581
        {
1582
          /* n < 0, s > 0.
1583
             Multiply m with 2^s, then divide by pow5.  */
1584
          mpn_t numerator;
1585
          mp_limb_t *num_ptr;
1586
          num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1587
                                          * sizeof (mp_limb_t));
1588
          if (num_ptr == NULL)
1589
            {
1590
              free (pow5_ptr);
1591
              free (memory);
1592
              return NULL;
1593
            }
1594
          {
1595
            mp_limb_t *destptr = num_ptr;
1596
            for (size_t i = 0; i < s_limbs; i++)
1597
              *destptr++ = 0;
1598
            if (s_bits > 0)
1599
              {
1600
                const mp_limb_t *sourceptr = m.limbs;
1601
                mp_twolimb_t accu = 0;
1602
                for (size_t count = m.nlimbs; count > 0; count--)
1603
                  {
1604
                    accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1605
                    *destptr++ = (mp_limb_t) accu;
1606
                    accu = accu >> GMP_LIMB_BITS;
1607
                  }
1608
                if (accu > 0)
1609
                  *destptr++ = (mp_limb_t) accu;
1610
              }
1611
            else
1612
              {
1613
                const mp_limb_t *sourceptr = m.limbs;
1614
                for (size_t count = m.nlimbs; count > 0; count--)
1615
                  *destptr++ = *sourceptr++;
1616
              }
1617
            numerator.limbs = num_ptr;
1618
            numerator.nlimbs = destptr - num_ptr;
1619
          }
1620
          z_memory = divide (numerator, pow5, &z);
1621
          free (num_ptr);
1622
        }
1623
    }
1624
  free (pow5_ptr);
1625
  free (memory);
1626
1627
  /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
1628
1629
  if (z_memory == NOMEM_PTR)
1630
    return NULL;
1631
  char *digits = convert_to_decimal (z, extra_zeroes);
1632
  free (z_memory);
1633
  return digits;
1634
}
1635
1636
# if NEED_PRINTF_LONG_DOUBLE
1637
1638
/* Assuming x is finite and >= 0, and n is an integer:
1639
   Returns the decimal representation of round (x * 10^n).
1640
   Return the allocated memory - containing the decimal digits in low-to-high
1641
   order, terminated with a NUL character - in case of success, NULL in case
1642
   of memory allocation failure.  */
1643
static char *
1644
scale10_round_decimal_long_double (long double x, int n)
1645
{
1646
  int e;
1647
  mpn_t m;
1648
  void *memory = decode_long_double (x, &e, &m);
1649
  if (memory != NULL)
1650
    return scale10_round_decimal_decoded (e, m, memory, n);
1651
  else
1652
    return NULL;
1653
}
1654
1655
# endif
1656
1657
# if NEED_PRINTF_DOUBLE
1658
1659
/* Assuming x is finite and >= 0, and n is an integer:
1660
   Returns the decimal representation of round (x * 10^n).
1661
   Return the allocated memory - containing the decimal digits in low-to-high
1662
   order, terminated with a NUL character - in case of success, NULL in case
1663
   of memory allocation failure.  */
1664
static char *
1665
scale10_round_decimal_double (double x, int n)
1666
{
1667
  int e;
1668
  mpn_t m;
1669
  void *memory = decode_double (x, &e, &m);
1670
  if (memory != NULL)
1671
    return scale10_round_decimal_decoded (e, m, memory, n);
1672
  else
1673
    return NULL;
1674
}
1675
1676
# endif
1677
1678
# if NEED_PRINTF_LONG_DOUBLE
1679
1680
/* Assuming x is finite and > 0:
1681
   Return an approximation for n with 10^n <= x < 10^(n+1).
1682
   The approximation is usually the right n, but may be off by 1 sometimes.  */
1683
static int
1684
floorlog10l (long double x)
1685
{
1686
  /* Split into exponential part and mantissa.  */
1687
  int exp;
1688
  long double y = safe_frexpl (x, &exp);
1689
  if (!(y >= 0.0L && y < 1.0L))
1690
    abort ();
1691
  if (y == 0.0L)
1692
    return INT_MIN;
1693
  if (y < 0.5L)
1694
    {
1695
      while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1696
        {
1697
          y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1698
          exp -= GMP_LIMB_BITS;
1699
        }
1700
      if (y < (1.0L / (1 << 16)))
1701
        {
1702
          y *= 1.0L * (1 << 16);
1703
          exp -= 16;
1704
        }
1705
      if (y < (1.0L / (1 << 8)))
1706
        {
1707
          y *= 1.0L * (1 << 8);
1708
          exp -= 8;
1709
        }
1710
      if (y < (1.0L / (1 << 4)))
1711
        {
1712
          y *= 1.0L * (1 << 4);
1713
          exp -= 4;
1714
        }
1715
      if (y < (1.0L / (1 << 2)))
1716
        {
1717
          y *= 1.0L * (1 << 2);
1718
          exp -= 2;
1719
        }
1720
      if (y < (1.0L / (1 << 1)))
1721
        {
1722
          y *= 1.0L * (1 << 1);
1723
          exp -= 1;
1724
        }
1725
    }
1726
  if (!(y >= 0.5L && y < 1.0L))
1727
    abort ();
1728
  /* Compute an approximation for l = log2(x) = exp + log2(y).  */
1729
  double l = exp;
1730
  double z = y;
1731
  if (z < 0.70710678118654752444)
1732
    {
1733
      z *= 1.4142135623730950488;
1734
      l -= 0.5;
1735
    }
1736
  if (z < 0.8408964152537145431)
1737
    {
1738
      z *= 1.1892071150027210667;
1739
      l -= 0.25;
1740
    }
1741
  if (z < 0.91700404320467123175)
1742
    {
1743
      z *= 1.0905077326652576592;
1744
      l -= 0.125;
1745
    }
1746
  if (z < 0.9576032806985736469)
1747
    {
1748
      z *= 1.0442737824274138403;
1749
      l -= 0.0625;
1750
    }
1751
  /* Now 0.95 <= z <= 1.01.  */
1752
  z = 1 - z;
1753
  /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1754
     Four terms are enough to get an approximation with error < 10^-7.  */
1755
  l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1756
  /* Finally multiply with log(2)/log(10), yields an approximation for
1757
     log10(x).  */
1758
  l *= 0.30102999566398119523;
1759
  /* Round down to the next integer.  */
1760
  return (int) l + (l < 0 ? -1 : 0);
1761
}
1762
1763
# endif
1764
1765
# if NEED_PRINTF_DOUBLE
1766
1767
/* Assuming x is finite and > 0:
1768
   Return an approximation for n with 10^n <= x < 10^(n+1).
1769
   The approximation is usually the right n, but may be off by 1 sometimes.  */
1770
static int
1771
floorlog10 (double x)
1772
{
1773
  /* Split into exponential part and mantissa.  */
1774
  int exp;
1775
  double y = frexp (x, &exp);
1776
  if (!(y >= 0.0 && y < 1.0))
1777
    abort ();
1778
  if (y == 0.0)
1779
    return INT_MIN;
1780
  if (y < 0.5)
1781
    {
1782
      while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1783
        {
1784
          y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1785
          exp -= GMP_LIMB_BITS;
1786
        }
1787
      if (y < (1.0 / (1 << 16)))
1788
        {
1789
          y *= 1.0 * (1 << 16);
1790
          exp -= 16;
1791
        }
1792
      if (y < (1.0 / (1 << 8)))
1793
        {
1794
          y *= 1.0 * (1 << 8);
1795
          exp -= 8;
1796
        }
1797
      if (y < (1.0 / (1 << 4)))
1798
        {
1799
          y *= 1.0 * (1 << 4);
1800
          exp -= 4;
1801
        }
1802
      if (y < (1.0 / (1 << 2)))
1803
        {
1804
          y *= 1.0 * (1 << 2);
1805
          exp -= 2;
1806
        }
1807
      if (y < (1.0 / (1 << 1)))
1808
        {
1809
          y *= 1.0 * (1 << 1);
1810
          exp -= 1;
1811
        }
1812
    }
1813
  if (!(y >= 0.5 && y < 1.0))
1814
    abort ();
1815
  /* Compute an approximation for l = log2(x) = exp + log2(y).  */
1816
  double l = exp;
1817
  double z = y;
1818
  if (z < 0.70710678118654752444)
1819
    {
1820
      z *= 1.4142135623730950488;
1821
      l -= 0.5;
1822
    }
1823
  if (z < 0.8408964152537145431)
1824
    {
1825
      z *= 1.1892071150027210667;
1826
      l -= 0.25;
1827
    }
1828
  if (z < 0.91700404320467123175)
1829
    {
1830
      z *= 1.0905077326652576592;
1831
      l -= 0.125;
1832
    }
1833
  if (z < 0.9576032806985736469)
1834
    {
1835
      z *= 1.0442737824274138403;
1836
      l -= 0.0625;
1837
    }
1838
  /* Now 0.95 <= z <= 1.01.  */
1839
  z = 1 - z;
1840
  /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1841
     Four terms are enough to get an approximation with error < 10^-7.  */
1842
  l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1843
  /* Finally multiply with log(2)/log(10), yields an approximation for
1844
     log10(x).  */
1845
  l *= 0.30102999566398119523;
1846
  /* Round down to the next integer.  */
1847
  return (int) l + (l < 0 ? -1 : 0);
1848
}
1849
1850
# endif
1851
1852
/* Tests whether a string of digits consists of exactly PRECISION zeroes and
1853
   a single '1' digit.  */
1854
static int
1855
is_borderline (const char *digits, size_t precision)
1856
{
1857
  for (; precision > 0; precision--, digits++)
1858
    if (*digits != '0')
1859
      return 0;
1860
  if (*digits != '1')
1861
    return 0;
1862
  digits++;
1863
  return *digits == '\0';
1864
}
1865
1866
#endif
1867
1868
#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
1869
1870
/* Use a different function name, to make it possible that the 'wchar_t'
1871
   parametrization and the 'char' parametrization get compiled in the same
1872
   translation unit.  */
1873
# if WIDE_CHAR_VERSION
1874
#  define MAX_ROOM_NEEDED wmax_room_needed
1875
# else
1876
#  define MAX_ROOM_NEEDED max_room_needed
1877
# endif
1878
1879
/* Returns the number of TCHAR_T units needed as temporary space for the result
1880
   of sprintf or SNPRINTF of a single conversion directive.  */
1881
static size_t
1882
MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
1883
                 arg_type type, int flags, size_t width, int has_precision,
1884
                 size_t precision, int pad_ourselves)
1885
{
1886
  size_t tmp_length;
1887
1888
  switch (conversion)
1889
    {
1890
    case 'd': case 'i': case 'u':
1891
      switch (type)
1892
        {
1893
        default:
1894
          tmp_length =
1895
            (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1896
                            * 0.30103 /* binary -> decimal */
1897
                           )
1898
            + 1; /* turn floor into ceil */
1899
          break;
1900
        case TYPE_LONGINT:
1901
          tmp_length =
1902
            (unsigned int) (sizeof (long int) * CHAR_BIT
1903
                            * 0.30103 /* binary -> decimal */
1904
                           )
1905
            + 1; /* turn floor into ceil */
1906
          break;
1907
        case TYPE_ULONGINT:
1908
          tmp_length =
1909
            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
1910
                            * 0.30103 /* binary -> decimal */
1911
                           )
1912
            + 1; /* turn floor into ceil */
1913
          break;
1914
        case TYPE_LONGLONGINT:
1915
          tmp_length =
1916
            (unsigned int) (sizeof (long long int) * CHAR_BIT
1917
                            * 0.30103 /* binary -> decimal */
1918
                           )
1919
            + 1; /* turn floor into ceil */
1920
          break;
1921
        case TYPE_ULONGLONGINT:
1922
          tmp_length =
1923
            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
1924
                            * 0.30103 /* binary -> decimal */
1925
                           )
1926
            + 1; /* turn floor into ceil */
1927
          break;
1928
        case TYPE_INT8_T:
1929
          tmp_length =
1930
            (unsigned int) (sizeof (int8_t) * CHAR_BIT
1931
                            * 0.30103 /* binary -> decimal */
1932
                           )
1933
            + 1; /* turn floor into ceil */
1934
          break;
1935
        case TYPE_UINT8_T:
1936
          tmp_length =
1937
            (unsigned int) (sizeof (uint8_t) * CHAR_BIT
1938
                            * 0.30103 /* binary -> decimal */
1939
                           )
1940
            + 1; /* turn floor into ceil */
1941
          break;
1942
        case TYPE_INT16_T:
1943
          tmp_length =
1944
            (unsigned int) (sizeof (int16_t) * CHAR_BIT
1945
                            * 0.30103 /* binary -> decimal */
1946
                           )
1947
            + 1; /* turn floor into ceil */
1948
          break;
1949
        case TYPE_UINT16_T:
1950
          tmp_length =
1951
            (unsigned int) (sizeof (uint16_t) * CHAR_BIT
1952
                            * 0.30103 /* binary -> decimal */
1953
                           )
1954
            + 1; /* turn floor into ceil */
1955
          break;
1956
        case TYPE_INT32_T:
1957
          tmp_length =
1958
            (unsigned int) (sizeof (int32_t) * CHAR_BIT
1959
                            * 0.30103 /* binary -> decimal */
1960
                           )
1961
            + 1; /* turn floor into ceil */
1962
          break;
1963
        case TYPE_UINT32_T:
1964
          tmp_length =
1965
            (unsigned int) (sizeof (uint32_t) * CHAR_BIT
1966
                            * 0.30103 /* binary -> decimal */
1967
                           )
1968
            + 1; /* turn floor into ceil */
1969
          break;
1970
        case TYPE_INT64_T:
1971
          tmp_length =
1972
            (unsigned int) (sizeof (int64_t) * CHAR_BIT
1973
                            * 0.30103 /* binary -> decimal */
1974
                           )
1975
            + 1; /* turn floor into ceil */
1976
          break;
1977
        case TYPE_UINT64_T:
1978
          tmp_length =
1979
            (unsigned int) (sizeof (uint64_t) * CHAR_BIT
1980
                            * 0.30103 /* binary -> decimal */
1981
                           )
1982
            + 1; /* turn floor into ceil */
1983
          break;
1984
        case TYPE_INT_FAST8_T:
1985
          tmp_length =
1986
            (unsigned int) (sizeof (int_fast8_t) * CHAR_BIT
1987
                            * 0.30103 /* binary -> decimal */
1988
                           )
1989
            + 1; /* turn floor into ceil */
1990
          break;
1991
        case TYPE_UINT_FAST8_T:
1992
          tmp_length =
1993
            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
1994
                            * 0.30103 /* binary -> decimal */
1995
                           )
1996
            + 1; /* turn floor into ceil */
1997
          break;
1998
        case TYPE_INT_FAST16_T:
1999
          tmp_length =
2000
            (unsigned int) (sizeof (int_fast16_t) * CHAR_BIT
2001
                            * 0.30103 /* binary -> decimal */
2002
                           )
2003
            + 1; /* turn floor into ceil */
2004
          break;
2005
        case TYPE_UINT_FAST16_T:
2006
          tmp_length =
2007
            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
2008
                            * 0.30103 /* binary -> decimal */
2009
                           )
2010
            + 1; /* turn floor into ceil */
2011
          break;
2012
        case TYPE_INT_FAST32_T:
2013
          tmp_length =
2014
            (unsigned int) (sizeof (int_fast32_t) * CHAR_BIT
2015
                            * 0.30103 /* binary -> decimal */
2016
                           )
2017
            + 1; /* turn floor into ceil */
2018
          break;
2019
        case TYPE_UINT_FAST32_T:
2020
          tmp_length =
2021
            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
2022
                            * 0.30103 /* binary -> decimal */
2023
                           )
2024
            + 1; /* turn floor into ceil */
2025
          break;
2026
        case TYPE_INT_FAST64_T:
2027
          tmp_length =
2028
            (unsigned int) (sizeof (int_fast64_t) * CHAR_BIT
2029
                            * 0.30103 /* binary -> decimal */
2030
                           )
2031
            + 1; /* turn floor into ceil */
2032
          break;
2033
        case TYPE_UINT_FAST64_T:
2034
          tmp_length =
2035
            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
2036
                            * 0.30103 /* binary -> decimal */
2037
                           )
2038
            + 1; /* turn floor into ceil */
2039
          break;
2040
        }
2041
      if (tmp_length < precision)
2042
        tmp_length = precision;
2043
      /* Account for thousands separators.  */
2044
      if (flags & FLAG_GROUP)
2045
        {
2046
          /* A thousands separator needs to be inserted at most every 2 digits.
2047
             This is the case in the ta_IN locale.  */
2048
# if WIDE_CHAR_VERSION
2049
          tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_WCHAR_MAXLEN);
2050
# else
2051
          tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_CHAR_MAXLEN);
2052
# endif
2053
        }
2054
      /* Add 1, to account for a leading sign.  */
2055
      tmp_length = xsum (tmp_length, 1);
2056
      break;
2057
2058
    case 'b':
2059
    #if SUPPORT_GNU_PRINTF_DIRECTIVES \
2060
        || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
2061
    case 'B':
2062
    #endif
2063
      switch (type)
2064
        {
2065
        default:
2066
          tmp_length =
2067
            (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
2068
            + 1; /* turn floor into ceil */
2069
          break;
2070
        case TYPE_ULONGINT:
2071
          tmp_length =
2072
            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
2073
            + 1; /* turn floor into ceil */
2074
          break;
2075
        case TYPE_ULONGLONGINT:
2076
          tmp_length =
2077
            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
2078
            + 1; /* turn floor into ceil */
2079
          break;
2080
        case TYPE_UINT8_T:
2081
          tmp_length =
2082
            (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
2083
            + 1; /* turn floor into ceil */
2084
          break;
2085
        case TYPE_UINT16_T:
2086
          tmp_length =
2087
            (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
2088
            + 1; /* turn floor into ceil */
2089
          break;
2090
        case TYPE_UINT32_T:
2091
          tmp_length =
2092
            (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
2093
            + 1; /* turn floor into ceil */
2094
          break;
2095
        case TYPE_UINT64_T:
2096
          tmp_length =
2097
            (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
2098
            + 1; /* turn floor into ceil */
2099
          break;
2100
        case TYPE_UINT_FAST8_T:
2101
          tmp_length =
2102
            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
2103
            + 1; /* turn floor into ceil */
2104
          break;
2105
        case TYPE_UINT_FAST16_T:
2106
          tmp_length =
2107
            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
2108
            + 1; /* turn floor into ceil */
2109
          break;
2110
        case TYPE_UINT_FAST32_T:
2111
          tmp_length =
2112
            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
2113
            + 1; /* turn floor into ceil */
2114
          break;
2115
        case TYPE_UINT_FAST64_T:
2116
          tmp_length =
2117
            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
2118
            + 1; /* turn floor into ceil */
2119
          break;
2120
        }
2121
      if (tmp_length < precision)
2122
        tmp_length = precision;
2123
      /* Add 2, to account for a prefix from the alternate form.  */
2124
      tmp_length = xsum (tmp_length, 2);
2125
      break;
2126
2127
    case 'o':
2128
      switch (type)
2129
        {
2130
        default:
2131
          tmp_length =
2132
            (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2133
                            * 0.333334 /* binary -> octal */
2134
                           )
2135
            + 1; /* turn floor into ceil */
2136
          break;
2137
        case TYPE_ULONGINT:
2138
          tmp_length =
2139
            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
2140
                            * 0.333334 /* binary -> octal */
2141
                           )
2142
            + 1; /* turn floor into ceil */
2143
          break;
2144
        case TYPE_ULONGLONGINT:
2145
          tmp_length =
2146
            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
2147
                            * 0.333334 /* binary -> octal */
2148
                           )
2149
            + 1; /* turn floor into ceil */
2150
          break;
2151
        case TYPE_UINT8_T:
2152
          tmp_length =
2153
            (unsigned int) (sizeof (uint8_t) * CHAR_BIT
2154
                            * 0.333334 /* binary -> octal */
2155
                           )
2156
            + 1; /* turn floor into ceil */
2157
          break;
2158
        case TYPE_UINT16_T:
2159
          tmp_length =
2160
            (unsigned int) (sizeof (uint16_t) * CHAR_BIT
2161
                            * 0.333334 /* binary -> octal */
2162
                           )
2163
            + 1; /* turn floor into ceil */
2164
          break;
2165
        case TYPE_UINT32_T:
2166
          tmp_length =
2167
            (unsigned int) (sizeof (uint32_t) * CHAR_BIT
2168
                            * 0.333334 /* binary -> octal */
2169
                           )
2170
            + 1; /* turn floor into ceil */
2171
          break;
2172
        case TYPE_UINT64_T:
2173
          tmp_length =
2174
            (unsigned int) (sizeof (uint64_t) * CHAR_BIT
2175
                            * 0.333334 /* binary -> octal */
2176
                           )
2177
            + 1; /* turn floor into ceil */
2178
          break;
2179
        case TYPE_UINT_FAST8_T:
2180
          tmp_length =
2181
            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
2182
                            * 0.333334 /* binary -> octal */
2183
                           )
2184
            + 1; /* turn floor into ceil */
2185
          break;
2186
        case TYPE_UINT_FAST16_T:
2187
          tmp_length =
2188
            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
2189
                            * 0.333334 /* binary -> octal */
2190
                           )
2191
            + 1; /* turn floor into ceil */
2192
          break;
2193
        case TYPE_UINT_FAST32_T:
2194
          tmp_length =
2195
            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
2196
                            * 0.333334 /* binary -> octal */
2197
                           )
2198
            + 1; /* turn floor into ceil */
2199
          break;
2200
        case TYPE_UINT_FAST64_T:
2201
          tmp_length =
2202
            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
2203
                            * 0.333334 /* binary -> octal */
2204
                           )
2205
            + 1; /* turn floor into ceil */
2206
          break;
2207
        }
2208
      if (tmp_length < precision)
2209
        tmp_length = precision;
2210
      /* Add 1, to account for a leading sign.  */
2211
      tmp_length = xsum (tmp_length, 1);
2212
      break;
2213
2214
    case 'x': case 'X':
2215
      switch (type)
2216
        {
2217
        default:
2218
          tmp_length =
2219
            (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2220
                            * 0.25 /* binary -> hexadecimal */
2221
                           )
2222
            + 1; /* turn floor into ceil */
2223
          break;
2224
        case TYPE_ULONGINT:
2225
          tmp_length =
2226
            (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
2227
                            * 0.25 /* binary -> hexadecimal */
2228
                           )
2229
            + 1; /* turn floor into ceil */
2230
          break;
2231
        case TYPE_ULONGLONGINT:
2232
          tmp_length =
2233
            (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
2234
                            * 0.25 /* binary -> hexadecimal */
2235
                           )
2236
            + 1; /* turn floor into ceil */
2237
          break;
2238
        case TYPE_UINT8_T:
2239
          tmp_length =
2240
            (unsigned int) (sizeof (uint8_t) * CHAR_BIT
2241
                            * 0.25 /* binary -> hexadecimal */
2242
                           )
2243
            + 1; /* turn floor into ceil */
2244
          break;
2245
        case TYPE_UINT16_T:
2246
          tmp_length =
2247
            (unsigned int) (sizeof (uint16_t) * CHAR_BIT
2248
                            * 0.25 /* binary -> hexadecimal */
2249
                           )
2250
            + 1; /* turn floor into ceil */
2251
          break;
2252
        case TYPE_UINT32_T:
2253
          tmp_length =
2254
            (unsigned int) (sizeof (uint32_t) * CHAR_BIT
2255
                            * 0.25 /* binary -> hexadecimal */
2256
                           )
2257
            + 1; /* turn floor into ceil */
2258
          break;
2259
        case TYPE_UINT64_T:
2260
          tmp_length =
2261
            (unsigned int) (sizeof (uint64_t) * CHAR_BIT
2262
                            * 0.25 /* binary -> hexadecimal */
2263
                           )
2264
            + 1; /* turn floor into ceil */
2265
          break;
2266
        case TYPE_UINT_FAST8_T:
2267
          tmp_length =
2268
            (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
2269
                            * 0.25 /* binary -> hexadecimal */
2270
                           )
2271
            + 1; /* turn floor into ceil */
2272
          break;
2273
        case TYPE_UINT_FAST16_T:
2274
          tmp_length =
2275
            (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
2276
                            * 0.25 /* binary -> hexadecimal */
2277
                           )
2278
            + 1; /* turn floor into ceil */
2279
          break;
2280
        case TYPE_UINT_FAST32_T:
2281
          tmp_length =
2282
            (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
2283
                            * 0.25 /* binary -> hexadecimal */
2284
                           )
2285
            + 1; /* turn floor into ceil */
2286
          break;
2287
        case TYPE_UINT_FAST64_T:
2288
          tmp_length =
2289
            (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
2290
                            * 0.25 /* binary -> hexadecimal */
2291
                           )
2292
            + 1; /* turn floor into ceil */
2293
          break;
2294
        }
2295
      if (tmp_length < precision)
2296
        tmp_length = precision;
2297
      /* Add 2, to account for a prefix from the alternate form.  */
2298
      tmp_length = xsum (tmp_length, 2);
2299
      break;
2300
2301
    case 'e': case 'E':
2302
      tmp_length =
2303
        12; /* sign, decimal point, exponent etc. */
2304
      tmp_length = xsum (tmp_length, precision);
2305
      break;
2306
2307
    case 'f': case 'F':
2308
      if (type == TYPE_LONGDOUBLE)
2309
        tmp_length =
2310
          (unsigned int) (LDBL_MAX_EXP
2311
                          * 0.30103 /* binary -> decimal */
2312
                          * 0.5 * 3 /* estimate for FLAG_GROUP */
2313
                         )
2314
          + 1 /* turn floor into ceil */
2315
          + 10; /* sign, decimal point etc. */
2316
      else
2317
        tmp_length =
2318
          (unsigned int) (DBL_MAX_EXP
2319
                          * 0.30103 /* binary -> decimal */
2320
                          * 0.5 * 3 /* estimate for FLAG_GROUP */
2321
                         )
2322
          + 1 /* turn floor into ceil */
2323
          + 10; /* sign, decimal point etc. */
2324
      tmp_length = xsum (tmp_length, precision);
2325
      break;
2326
2327
    case 'g': case 'G':
2328
      tmp_length =
2329
        12; /* sign, decimal point, exponent etc. */
2330
      tmp_length = xsum (tmp_length,
2331
                         precision
2332
                         * 0.5 * 3 /* estimate for FLAG_GROUP */
2333
                        );
2334
      break;
2335
2336
    case 'a': case 'A':
2337
      if (type == TYPE_LONGDOUBLE)
2338
        tmp_length =
2339
          (unsigned int) (LDBL_DIG
2340
                          * 0.831 /* decimal -> hexadecimal */
2341
                         )
2342
          + 1; /* turn floor into ceil */
2343
      else
2344
        tmp_length =
2345
          (unsigned int) (DBL_DIG
2346
                          * 0.831 /* decimal -> hexadecimal */
2347
                         )
2348
          + 1; /* turn floor into ceil */
2349
      if (tmp_length < precision)
2350
        tmp_length = precision;
2351
      /* Account for sign, decimal point etc. */
2352
      tmp_length = xsum (tmp_length, 12);
2353
      break;
2354
2355
    case 'c':
2356
# if HAVE_WINT_T && !WIDE_CHAR_VERSION
2357
      if (type == TYPE_WIDE_CHAR)
2358
        {
2359
          tmp_length = MB_CUR_MAX;
2360
#  if ENABLE_WCHAR_FALLBACK
2361
          if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6))
2362
            tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6);
2363
#  endif
2364
        }
2365
      else
2366
# endif
2367
        tmp_length = 1;
2368
      break;
2369
2370
    case 's':
2371
      if (type == TYPE_WIDE_STRING)
2372
        {
2373
# if WIDE_CHAR_VERSION
2374
          /* ISO C says about %ls in fwprintf:
2375
               "If the precision is not specified or is greater than the size
2376
                of the array, the array shall contain a null wide character."
2377
             So if there is a precision, we must not use wcslen.  */
2378
          const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
2379
2380
          if (has_precision)
2381
            tmp_length = local_wcsnlen (arg, precision);
2382
          else
2383
            tmp_length = local_wcslen (arg);
2384
# else
2385
          /* ISO C says about %ls in fprintf:
2386
               "If a precision is specified, no more than that many bytes are
2387
                written (including shift sequences, if any), and the array
2388
                shall contain a null wide character if, to equal the multibyte
2389
                character sequence length given by the precision, the function
2390
                would need to access a wide character one past the end of the
2391
                array."
2392
             So if there is a precision, we must not use wcslen.  */
2393
          /* This case has already been handled separately in VASNPRINTF.  */
2394
          abort ();
2395
# endif
2396
        }
2397
      else
2398
        {
2399
# if WIDE_CHAR_VERSION
2400
          /* ISO C says about %s in fwprintf:
2401
               "If the precision is not specified or is greater than the size
2402
                of the converted array, the converted array shall contain a
2403
                null wide character."
2404
             So if there is a precision, we must not use strlen.  */
2405
          /* This case has already been handled separately in VASNPRINTF.  */
2406
          abort ();
2407
# else
2408
          /* ISO C says about %s in fprintf:
2409
               "If the precision is not specified or greater than the size of
2410
                the array, the array shall contain a null character."
2411
             So if there is a precision, we must not use strlen.  */
2412
          const char *arg = ap->arg[arg_index].a.a_string;
2413
2414
          if (has_precision)
2415
            tmp_length = local_strnlen (arg, precision);
2416
          else
2417
            tmp_length = strlen (arg);
2418
# endif
2419
        }
2420
      break;
2421
2422
    case 'p':
2423
      tmp_length =
2424
        (unsigned int) (sizeof (void *) * CHAR_BIT
2425
                        * 0.25 /* binary -> hexadecimal */
2426
                       )
2427
          + 1 /* turn floor into ceil */
2428
          + 2; /* account for leading 0x */
2429
      break;
2430
2431
    default:
2432
      abort ();
2433
    }
2434
2435
  if (!pad_ourselves)
2436
    {
2437
# if ENABLE_UNISTDIO
2438
      /* Padding considers the number of characters, therefore the number of
2439
         elements after padding may be
2440
           > max (tmp_length, width)
2441
         but is certainly
2442
           <= tmp_length + width.  */
2443
      tmp_length = xsum (tmp_length, width);
2444
# else
2445
      /* Padding considers the number of elements, says POSIX.  */
2446
      if (tmp_length < width)
2447
        tmp_length = width;
2448
# endif
2449
    }
2450
2451
  tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2452
2453
  return tmp_length;
2454
}
2455
2456
#endif
2457
2458
DCHAR_T *
2459
VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
2460
            const FCHAR_T *format, va_list args)
2461
9.16k
{
2462
9.16k
  DIRECTIVES d;
2463
9.16k
  arguments a;
2464
2465
9.16k
  if (PRINTF_PARSE (format, &d, &a) < 0)
2466
    /* errno is already set.  */
2467
0
    return NULL;
2468
2469
  /* Frees the memory allocated by this function.  Preserves errno.  */
2470
9.16k
#define CLEANUP() \
2471
9.16k
  if (d.dir != d.direct_alloc_dir)                                      \
2472
9.16k
    free (d.dir);                                                       \
2473
9.16k
  if (a.arg != a.direct_alloc_arg)                                      \
2474
9.16k
    free (a.arg);
2475
2476
9.16k
  if (PRINTF_FETCHARGS (args, &a) < 0)
2477
0
    goto fail_1_with_EINVAL;
2478
2479
9.16k
  {
2480
    /* Allocate a small buffer that will hold a directive passed to
2481
       sprintf or snprintf.  */
2482
9.16k
    size_t buf_neededlength =
2483
9.16k
      xsum4 (7, d.max_width_length, d.max_precision_length, 6);
2484
9.16k
    TCHAR_T *buf;
2485
9.16k
    TCHAR_T *buf_malloced;
2486
9.16k
#if HAVE_ALLOCA
2487
9.16k
    if (buf_neededlength < 4000 / sizeof (TCHAR_T))
2488
9.16k
      {
2489
9.16k
        buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
2490
9.16k
        buf_malloced = NULL;
2491
9.16k
      }
2492
0
    else
2493
0
#endif
2494
0
      {
2495
0
        size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
2496
0
        if (size_overflow_p (buf_memsize))
2497
0
          goto out_of_memory_1;
2498
0
        buf = (TCHAR_T *) malloc (buf_memsize);
2499
0
        if (buf == NULL)
2500
0
          goto out_of_memory_1;
2501
0
        buf_malloced = buf;
2502
0
      }
2503
2504
    /* Output string accumulator.  */
2505
9.16k
    DCHAR_T *result = resultbuf;
2506
9.16k
    size_t allocated = (resultbuf != NULL ? *lengthp : 0);
2507
9.16k
    size_t length = 0;
2508
2509
    /* Invariants:
2510
       result is either == resultbuf or malloc-allocated.
2511
       If result == NULL, resultbuf is == NULL as well.
2512
       If length > 0, then result != NULL.  */
2513
2514
    /* Ensures that allocated >= needed.  Aborts through a jump to
2515
       out_of_memory if needed is SIZE_MAX or otherwise too big.  */
2516
9.16k
#define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \
2517
36.6k
    if ((needed) > allocated)                                                \
2518
36.6k
      {                                                                      \
2519
32.5k
        allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
2520
32.5k
        if ((needed) > allocated)                                            \
2521
32.5k
          allocated = (needed);                                              \
2522
32.5k
        size_t memory_size = xtimes (allocated, sizeof (DCHAR_T));           \
2523
32.5k
        if (size_overflow_p (memory_size))                                   \
2524
32.5k
          oom_statement                                                      \
2525
32.5k
        DCHAR_T *memory;                                                     \
2526
32.5k
        if (result == resultbuf)                                             \
2527
32.5k
          memory = (DCHAR_T *) malloc (memory_size);                         \
2528
32.5k
        else                                                                 \
2529
32.5k
          memory = (DCHAR_T *) realloc (result, memory_size);                \
2530
32.5k
        if (memory == NULL)                                                  \
2531
32.5k
          oom_statement                                                      \
2532
32.5k
        if (result == resultbuf && length > 0)                               \
2533
32.5k
          DCHAR_CPY (memory, result, length);                                \
2534
32.5k
        result = memory;                                                     \
2535
32.5k
      }
2536
9.16k
#define ENSURE_ALLOCATION(needed) \
2537
36.6k
  ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; )
2538
2539
9.16k
    const FCHAR_T *cp;
2540
9.16k
    size_t di;
2541
9.16k
    DIRECTIVE *dp;
2542
9.16k
    for (cp = format, di = 0, dp = &d.dir[0]; ; cp = dp->dir_end, di++, dp++)
2543
18.3k
      {
2544
18.3k
        if (cp != dp->dir_start)
2545
18.3k
          {
2546
18.3k
            size_t n = dp->dir_start - cp;
2547
18.3k
            size_t augmented_length = xsum (length, n);
2548
2549
18.3k
            ENSURE_ALLOCATION (augmented_length);
2550
            /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
2551
               need that the format string contains only ASCII characters
2552
               if FCHAR_T and DCHAR_T are not the same type.  */
2553
18.3k
            if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
2554
18.3k
              {
2555
18.3k
                DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
2556
18.3k
                length = augmented_length;
2557
18.3k
              }
2558
0
            else
2559
0
              {
2560
0
                do
2561
0
                  result[length++] = *cp++;
2562
0
                while (--n > 0);
2563
0
              }
2564
18.3k
          }
2565
18.3k
        if (di == d.count)
2566
9.16k
          break;
2567
2568
        /* Execute a single directive.  */
2569
9.16k
        if (dp->conversion == '%')
2570
0
          {
2571
0
            size_t augmented_length;
2572
2573
0
            if (!(dp->arg_index == ARG_NONE))
2574
0
              abort ();
2575
0
            augmented_length = xsum (length, 1);
2576
0
            ENSURE_ALLOCATION (augmented_length);
2577
0
            result[length] = '%';
2578
0
            length = augmented_length;
2579
0
          }
2580
9.16k
        else
2581
9.16k
          {
2582
9.16k
            if (!(dp->arg_index != ARG_NONE))
2583
0
              abort ();
2584
2585
9.16k
            if (dp->conversion == 'n')
2586
0
              {
2587
#if NEED_PRINTF_WITH_N_DIRECTIVE
2588
                switch (a.arg[dp->arg_index].type)
2589
                  {
2590
                  case TYPE_COUNT_SCHAR_POINTER:
2591
                    *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
2592
                    break;
2593
                  case TYPE_COUNT_SHORT_POINTER:
2594
                    *a.arg[dp->arg_index].a.a_count_short_pointer = length;
2595
                    break;
2596
                  case TYPE_COUNT_INT_POINTER:
2597
                    *a.arg[dp->arg_index].a.a_count_int_pointer = length;
2598
                    break;
2599
                  case TYPE_COUNT_LONGINT_POINTER:
2600
                    *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
2601
                    break;
2602
                  case TYPE_COUNT_LONGLONGINT_POINTER:
2603
                    *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
2604
                    break;
2605
                  case TYPE_COUNT_INT8_T_POINTER:
2606
                    *a.arg[dp->arg_index].a.a_count_int8_t_pointer = length;
2607
                    break;
2608
                  case TYPE_COUNT_INT16_T_POINTER:
2609
                    *a.arg[dp->arg_index].a.a_count_int16_t_pointer = length;
2610
                    break;
2611
                  case TYPE_COUNT_INT32_T_POINTER:
2612
                    *a.arg[dp->arg_index].a.a_count_int32_t_pointer = length;
2613
                    break;
2614
                  case TYPE_COUNT_INT64_T_POINTER:
2615
                    *a.arg[dp->arg_index].a.a_count_int64_t_pointer = length;
2616
                    break;
2617
                  case TYPE_COUNT_INT_FAST8_T_POINTER:
2618
                    *a.arg[dp->arg_index].a.a_count_int_fast8_t_pointer = length;
2619
                    break;
2620
                  case TYPE_COUNT_INT_FAST16_T_POINTER:
2621
                    *a.arg[dp->arg_index].a.a_count_int_fast16_t_pointer = length;
2622
                    break;
2623
                  case TYPE_COUNT_INT_FAST32_T_POINTER:
2624
                    *a.arg[dp->arg_index].a.a_count_int_fast32_t_pointer = length;
2625
                    break;
2626
                  case TYPE_COUNT_INT_FAST64_T_POINTER:
2627
                    *a.arg[dp->arg_index].a.a_count_int_fast64_t_pointer = length;
2628
                    break;
2629
                  default:
2630
                    abort ();
2631
                  }
2632
#else
2633
0
                abort ();
2634
0
#endif
2635
0
              }
2636
#if ENABLE_UNISTDIO
2637
            /* The unistdio extensions.  */
2638
            else if (dp->conversion == 'U')
2639
              {
2640
                arg_type type = a.arg[dp->arg_index].type;
2641
                int flags = dp->flags;
2642
2643
                int has_width = 0;
2644
                size_t width = 0;
2645
                if (dp->width_start != dp->width_end)
2646
                  {
2647
                    if (dp->width_arg_index != ARG_NONE)
2648
                      {
2649
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2650
                          abort ();
2651
                        int arg = a.arg[dp->width_arg_index].a.a_int;
2652
                        width = arg;
2653
                        if (arg < 0)
2654
                          {
2655
                            /* "A negative field width is taken as a '-' flag
2656
                                followed by a positive field width."  */
2657
                            flags |= FLAG_LEFT;
2658
                            width = -width;
2659
                          }
2660
                      }
2661
                    else
2662
                      {
2663
                        const FCHAR_T *digitp = dp->width_start;
2664
2665
                        do
2666
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
2667
                        while (digitp != dp->width_end);
2668
                      }
2669
                    if (width > (size_t) INT_MAX)
2670
                      goto overflow;
2671
                    has_width = 1;
2672
                  }
2673
2674
                int has_precision = 0;
2675
                size_t precision = 0;
2676
                if (dp->precision_start != dp->precision_end)
2677
                  {
2678
                    if (dp->precision_arg_index != ARG_NONE)
2679
                      {
2680
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2681
                          abort ();
2682
                        int arg = a.arg[dp->precision_arg_index].a.a_int;
2683
                        /* "A negative precision is taken as if the precision
2684
                            were omitted."  */
2685
                        if (arg >= 0)
2686
                          {
2687
                            precision = arg;
2688
                            has_precision = 1;
2689
                          }
2690
                      }
2691
                    else
2692
                      {
2693
                        const FCHAR_T *digitp = dp->precision_start + 1;
2694
2695
                        precision = 0;
2696
                        while (digitp != dp->precision_end)
2697
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2698
                        has_precision = 1;
2699
                      }
2700
                  }
2701
2702
                switch (type)
2703
                  {
2704
                  case TYPE_U8_STRING:
2705
                    {
2706
                      const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2707
                      const uint8_t *arg_end;
2708
                      size_t characters;
2709
2710
                      if (has_precision)
2711
                        {
2712
                          /* Use only PRECISION characters, from the left.  */
2713
                          arg_end = arg;
2714
                          characters = 0;
2715
                          for (; precision > 0; precision--)
2716
                            {
2717
                              int count = u8_strmblen (arg_end);
2718
                              if (count == 0)
2719
                                break;
2720
                              if (count < 0)
2721
                                goto fail_with_EILSEQ;
2722
                              arg_end += count;
2723
                              characters++;
2724
                            }
2725
                        }
2726
                      else if (has_width)
2727
                        {
2728
                          /* Use the entire string, and count the number of
2729
                             characters.  */
2730
                          arg_end = arg;
2731
                          characters = 0;
2732
                          for (;;)
2733
                            {
2734
                              int count = u8_strmblen (arg_end);
2735
                              if (count == 0)
2736
                                break;
2737
                              if (count < 0)
2738
                                goto fail_with_EILSEQ;
2739
                              arg_end += count;
2740
                              characters++;
2741
                            }
2742
                        }
2743
                      else
2744
                        {
2745
                          /* Use the entire string.  */
2746
                          arg_end = arg + u8_strlen (arg);
2747
                          /* The number of characters doesn't matter,
2748
                             because !has_width and therefore width==0.  */
2749
                          characters = 0;
2750
                        }
2751
2752
                      if (characters < width && !(flags & FLAG_LEFT))
2753
                        {
2754
                          size_t n = width - characters;
2755
                          ENSURE_ALLOCATION (xsum (length, n));
2756
                          DCHAR_SET (result + length, ' ', n);
2757
                          length += n;
2758
                        }
2759
2760
# if DCHAR_IS_UINT8_T
2761
                      {
2762
                        size_t n = arg_end - arg;
2763
                        ENSURE_ALLOCATION (xsum (length, n));
2764
                        DCHAR_CPY (result + length, arg, n);
2765
                        length += n;
2766
                      }
2767
# else
2768
                      { /* Convert.  */
2769
                        DCHAR_T *converted = result + length;
2770
                        size_t converted_len = allocated - length;
2771
#  if DCHAR_IS_TCHAR
2772
                        /* Convert from UTF-8 to locale encoding.  */
2773
                        converted =
2774
                          u8_conv_to_encoding (locale_charset (),
2775
                                               iconveh_question_mark,
2776
                                               arg, arg_end - arg, NULL,
2777
                                               converted, &converted_len);
2778
#  else
2779
                        /* Convert from UTF-8 to UTF-16/UTF-32.  */
2780
                        converted =
2781
                          U8_TO_DCHAR (arg, arg_end - arg,
2782
                                       converted, &converted_len);
2783
#  endif
2784
                        if (converted == NULL)
2785
                          goto fail_with_errno;
2786
                        if (converted != result + length)
2787
                          {
2788
                            ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2789
                              { free (converted); goto out_of_memory; });
2790
                            DCHAR_CPY (result + length, converted, converted_len);
2791
                            free (converted);
2792
                          }
2793
                        length += converted_len;
2794
                      }
2795
# endif
2796
2797
                      if (characters < width && (flags & FLAG_LEFT))
2798
                        {
2799
                          size_t n = width - characters;
2800
                          ENSURE_ALLOCATION (xsum (length, n));
2801
                          DCHAR_SET (result + length, ' ', n);
2802
                          length += n;
2803
                        }
2804
                    }
2805
                    break;
2806
2807
                  case TYPE_U16_STRING:
2808
                    {
2809
                      const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2810
                      const uint16_t *arg_end;
2811
                      size_t characters;
2812
2813
                      if (has_precision)
2814
                        {
2815
                          /* Use only PRECISION characters, from the left.  */
2816
                          arg_end = arg;
2817
                          characters = 0;
2818
                          for (; precision > 0; precision--)
2819
                            {
2820
                              int count = u16_strmblen (arg_end);
2821
                              if (count == 0)
2822
                                break;
2823
                              if (count < 0)
2824
                                goto fail_with_EILSEQ;
2825
                              arg_end += count;
2826
                              characters++;
2827
                            }
2828
                        }
2829
                      else if (has_width)
2830
                        {
2831
                          /* Use the entire string, and count the number of
2832
                             characters.  */
2833
                          arg_end = arg;
2834
                          characters = 0;
2835
                          for (;;)
2836
                            {
2837
                              int count = u16_strmblen (arg_end);
2838
                              if (count == 0)
2839
                                break;
2840
                              if (count < 0)
2841
                                goto fail_with_EILSEQ;
2842
                              arg_end += count;
2843
                              characters++;
2844
                            }
2845
                        }
2846
                      else
2847
                        {
2848
                          /* Use the entire string.  */
2849
                          arg_end = arg + u16_strlen (arg);
2850
                          /* The number of characters doesn't matter,
2851
                             because !has_width and therefore width==0.  */
2852
                          characters = 0;
2853
                        }
2854
2855
                      if (characters < width && !(flags & FLAG_LEFT))
2856
                        {
2857
                          size_t n = width - characters;
2858
                          ENSURE_ALLOCATION (xsum (length, n));
2859
                          DCHAR_SET (result + length, ' ', n);
2860
                          length += n;
2861
                        }
2862
2863
# if DCHAR_IS_UINT16_T
2864
                      {
2865
                        size_t n = arg_end - arg;
2866
                        ENSURE_ALLOCATION (xsum (length, n));
2867
                        DCHAR_CPY (result + length, arg, n);
2868
                        length += n;
2869
                      }
2870
# else
2871
                      { /* Convert.  */
2872
                        DCHAR_T *converted = result + length;
2873
                        size_t converted_len = allocated - length;
2874
#  if DCHAR_IS_TCHAR
2875
                        /* Convert from UTF-16 to locale encoding.  */
2876
                        converted =
2877
                          u16_conv_to_encoding (locale_charset (),
2878
                                                iconveh_question_mark,
2879
                                                arg, arg_end - arg, NULL,
2880
                                                converted, &converted_len);
2881
#  else
2882
                        /* Convert from UTF-16 to UTF-8/UTF-32.  */
2883
                        converted =
2884
                          U16_TO_DCHAR (arg, arg_end - arg,
2885
                                        converted, &converted_len);
2886
#  endif
2887
                        if (converted == NULL)
2888
                          goto fail_with_errno;
2889
                        if (converted != result + length)
2890
                          {
2891
                            ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2892
                              { free (converted); goto out_of_memory; });
2893
                            DCHAR_CPY (result + length, converted, converted_len);
2894
                            free (converted);
2895
                          }
2896
                        length += converted_len;
2897
                      }
2898
# endif
2899
2900
                      if (characters < width && (flags & FLAG_LEFT))
2901
                        {
2902
                          size_t n = width - characters;
2903
                          ENSURE_ALLOCATION (xsum (length, n));
2904
                          DCHAR_SET (result + length, ' ', n);
2905
                          length += n;
2906
                        }
2907
                    }
2908
                    break;
2909
2910
                  case TYPE_U32_STRING:
2911
                    {
2912
                      const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2913
                      const uint32_t *arg_end;
2914
                      size_t characters;
2915
2916
                      if (has_precision)
2917
                        {
2918
                          /* Use only PRECISION characters, from the left.  */
2919
                          arg_end = arg;
2920
                          characters = 0;
2921
                          for (; precision > 0; precision--)
2922
                            {
2923
                              int count = u32_strmblen (arg_end);
2924
                              if (count == 0)
2925
                                break;
2926
                              if (count < 0)
2927
                                goto fail_with_EILSEQ;
2928
                              arg_end += count;
2929
                              characters++;
2930
                            }
2931
                        }
2932
                      else if (has_width)
2933
                        {
2934
                          /* Use the entire string, and count the number of
2935
                             characters.  */
2936
                          arg_end = arg;
2937
                          characters = 0;
2938
                          for (;;)
2939
                            {
2940
                              int count = u32_strmblen (arg_end);
2941
                              if (count == 0)
2942
                                break;
2943
                              if (count < 0)
2944
                                goto fail_with_EILSEQ;
2945
                              arg_end += count;
2946
                              characters++;
2947
                            }
2948
                        }
2949
                      else
2950
                        {
2951
                          /* Use the entire string.  */
2952
                          arg_end = arg + u32_strlen (arg);
2953
                          /* The number of characters doesn't matter,
2954
                             because !has_width and therefore width==0.  */
2955
                          characters = 0;
2956
                        }
2957
2958
                      if (characters < width && !(flags & FLAG_LEFT))
2959
                        {
2960
                          size_t n = width - characters;
2961
                          ENSURE_ALLOCATION (xsum (length, n));
2962
                          DCHAR_SET (result + length, ' ', n);
2963
                          length += n;
2964
                        }
2965
2966
# if DCHAR_IS_UINT32_T
2967
                      {
2968
                        size_t n = arg_end - arg;
2969
                        ENSURE_ALLOCATION (xsum (length, n));
2970
                        DCHAR_CPY (result + length, arg, n);
2971
                        length += n;
2972
                      }
2973
# else
2974
                      { /* Convert.  */
2975
                        DCHAR_T *converted = result + length;
2976
                        size_t converted_len = allocated - length;
2977
#  if DCHAR_IS_TCHAR
2978
                        /* Convert from UTF-32 to locale encoding.  */
2979
                        converted =
2980
                          u32_conv_to_encoding (locale_charset (),
2981
                                                iconveh_question_mark,
2982
                                                arg, arg_end - arg, NULL,
2983
                                                converted, &converted_len);
2984
#  else
2985
                        /* Convert from UTF-32 to UTF-8/UTF-16.  */
2986
                        converted =
2987
                          U32_TO_DCHAR (arg, arg_end - arg,
2988
                                        converted, &converted_len);
2989
#  endif
2990
                        if (converted == NULL)
2991
                          goto fail_with_errno;
2992
                        if (converted != result + length)
2993
                          {
2994
                            ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2995
                              { free (converted); goto out_of_memory; });
2996
                            DCHAR_CPY (result + length, converted, converted_len);
2997
                            free (converted);
2998
                          }
2999
                        length += converted_len;
3000
                      }
3001
# endif
3002
3003
                      if (characters < width && (flags & FLAG_LEFT))
3004
                        {
3005
                          size_t n = width - characters;
3006
                          ENSURE_ALLOCATION (xsum (length, n));
3007
                          DCHAR_SET (result + length, ' ', n);
3008
                          length += n;
3009
                        }
3010
                    }
3011
                    break;
3012
3013
                  default:
3014
                    abort ();
3015
                  }
3016
              }
3017
#endif
3018
9.16k
#if !WIDE_CHAR_VERSION && (PTRDIFF_MAX > INT_MAX)
3019
9.16k
            else if (dp->conversion == 's'
3020
9.16k
                     && a.arg[dp->arg_index].type != TYPE_WIDE_STRING)
3021
9.16k
              {
3022
                /* %s in vasnprintf.  See the specification of fprintf.
3023
                   We handle it ourselves here, because the string may be longer
3024
                   than INT_MAX characters, whence snprintf or sprintf would
3025
                   fail to process it.  */
3026
9.16k
                int flags = dp->flags;
3027
3028
9.16k
                int has_width = 0;
3029
9.16k
                size_t width = 0;
3030
9.16k
                if (dp->width_start != dp->width_end)
3031
0
                  {
3032
0
                    if (dp->width_arg_index != ARG_NONE)
3033
0
                      {
3034
0
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3035
0
                          abort ();
3036
0
                        int arg = a.arg[dp->width_arg_index].a.a_int;
3037
0
                        width = arg;
3038
0
                        if (arg < 0)
3039
0
                          {
3040
                            /* "A negative field width is taken as a '-' flag
3041
                                followed by a positive field width."  */
3042
0
                            flags |= FLAG_LEFT;
3043
0
                            width = -width;
3044
0
                          }
3045
0
                      }
3046
0
                    else
3047
0
                      {
3048
0
                        const FCHAR_T *digitp = dp->width_start;
3049
3050
0
                        do
3051
0
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
3052
0
                        while (digitp != dp->width_end);
3053
0
                      }
3054
0
                    if (width > (size_t) INT_MAX)
3055
0
                      goto overflow;
3056
0
                    has_width = 1;
3057
0
                  }
3058
3059
9.16k
                int has_precision = 0;
3060
9.16k
                size_t precision = 6;
3061
9.16k
                if (dp->precision_start != dp->precision_end)
3062
0
                  {
3063
0
                    if (dp->precision_arg_index != ARG_NONE)
3064
0
                      {
3065
0
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3066
0
                          abort ();
3067
0
                        int arg = a.arg[dp->precision_arg_index].a.a_int;
3068
                        /* "A negative precision is taken as if the precision
3069
                            were omitted."  */
3070
0
                        if (arg >= 0)
3071
0
                          {
3072
0
                            precision = arg;
3073
0
                            has_precision = 1;
3074
0
                          }
3075
0
                      }
3076
0
                    else
3077
0
                      {
3078
0
                        const FCHAR_T *digitp = dp->precision_start + 1;
3079
3080
0
                        precision = 0;
3081
0
                        while (digitp != dp->precision_end)
3082
0
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3083
0
                        has_precision = 1;
3084
0
                      }
3085
0
                  }
3086
3087
9.16k
                {
3088
9.16k
                  const char *arg = a.arg[dp->arg_index].a.a_string;
3089
3090
9.16k
                  size_t bytes;
3091
9.16k
                  if (has_precision)
3092
0
                    {
3093
                      /* Use only at most PRECISION bytes, from the left.  */
3094
0
                      bytes = local_strnlen (arg, precision);
3095
0
                    }
3096
9.16k
                  else
3097
9.16k
                    {
3098
                      /* Use the entire string, and count the number of
3099
                         bytes.  */
3100
9.16k
                      bytes = strlen (arg);
3101
9.16k
                    }
3102
3103
# if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3104
                  size_t characters;
3105
                  if (has_width)
3106
                    characters = mbsnlen (arg, bytes);
3107
                  else
3108
                    {
3109
                      /* The number of characters doesn't matter,
3110
                         because !has_width and therefore width==0.  */
3111
                      characters = 0;
3112
                    }
3113
# endif
3114
3115
# if !DCHAR_IS_TCHAR
3116
                  /* This code assumes that TCHAR_T is 'char'.  */
3117
                  static_assert (sizeof (TCHAR_T) == 1);
3118
                  DCHAR_T *tmpdst;
3119
                  size_t tmpdst_len;
3120
                  /* Convert from TCHAR_T[] to DCHAR_T[].  */
3121
                  tmpdst =
3122
                    DCHAR_CONV_FROM_ENCODING (locale_charset (),
3123
                                              iconveh_question_mark,
3124
                                              arg, bytes,
3125
                                              NULL,
3126
                                              NULL, &tmpdst_len);
3127
                  if (tmpdst == NULL)
3128
                    goto fail_with_errno;
3129
# endif
3130
3131
9.16k
                  size_t w;
3132
9.16k
                  if (has_width)
3133
0
                    {
3134
# if ENABLE_UNISTDIO
3135
                      /* Outside POSIX, it's preferable to compare the width
3136
                         against the number of _characters_ of the converted
3137
                         value.  */
3138
#  if DCHAR_IS_TCHAR
3139
                      w = characters;
3140
#  else
3141
                      w = DCHAR_MBSNLEN (tmpdst, tmpdst_len);
3142
#  endif
3143
# else
3144
                      /* The width is compared against the number of _bytes_
3145
                         of the converted value, says POSIX.  */
3146
0
                      w = bytes;
3147
0
# endif
3148
0
                    }
3149
9.16k
                  else
3150
                    /* w doesn't matter.  */
3151
9.16k
                    w = 0;
3152
3153
9.16k
                  {
3154
9.16k
# if DCHAR_IS_TCHAR
3155
9.16k
                    size_t total = bytes + (w < width ? width - w : 0);
3156
9.16k
                    ENSURE_ALLOCATION (xsum (length, total));
3157
# else
3158
                    size_t total = tmpdst_len + (w < width ? width - w : 0);
3159
                    ENSURE_ALLOCATION_ELSE (xsum (length, total),
3160
                      { free (tmpdst); goto out_of_memory; });
3161
# endif
3162
3163
9.16k
                    if (w < width && !(flags & FLAG_LEFT))
3164
0
                      {
3165
0
                        size_t n = width - w;
3166
0
                        DCHAR_SET (result + length, ' ', n);
3167
0
                        length += n;
3168
0
                      }
3169
3170
9.16k
# if DCHAR_IS_TCHAR
3171
9.16k
                    memcpy (result + length, arg, bytes);
3172
9.16k
                    length += bytes;
3173
# else
3174
                    DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3175
                    free (tmpdst);
3176
                    length += tmpdst_len;
3177
# endif
3178
3179
9.16k
                    if (w < width && (flags & FLAG_LEFT))
3180
0
                      {
3181
0
                        size_t n = width - w;
3182
0
                        DCHAR_SET (result + length, ' ', n);
3183
0
                        length += n;
3184
0
                      }
3185
9.16k
                  }
3186
9.16k
                }
3187
9.16k
              }
3188
0
#endif
3189
#if WIDE_CHAR_VERSION && ((PTRDIFF_MAX > INT_MAX) || !DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC)
3190
            else if ((dp->conversion == 's'
3191
                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING)
3192
                     || (dp->conversion == 'c'
3193
                         && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR))
3194
              {
3195
                /* %ls or %lc in vasnwprintf.  See the specification of
3196
                   fwprintf.  */
3197
                /* It would be silly to use snprintf ("%ls", ...) and then
3198
                   convert back the result from a char[] to a wchar_t[].
3199
                   Instead, just copy the argument wchar_t[] to the result.  */
3200
                int flags = dp->flags;
3201
3202
                size_t width = 0;
3203
                if (dp->width_start != dp->width_end)
3204
                  {
3205
                    if (dp->width_arg_index != ARG_NONE)
3206
                      {
3207
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3208
                          abort ();
3209
                        int arg = a.arg[dp->width_arg_index].a.a_int;
3210
                        width = arg;
3211
                        if (arg < 0)
3212
                          {
3213
                            /* "A negative field width is taken as a '-' flag
3214
                                followed by a positive field width."  */
3215
                            flags |= FLAG_LEFT;
3216
                            width = -width;
3217
                          }
3218
                      }
3219
                    else
3220
                      {
3221
                        const FCHAR_T *digitp = dp->width_start;
3222
3223
                        do
3224
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
3225
                        while (digitp != dp->width_end);
3226
                      }
3227
                    if (width > (size_t) INT_MAX)
3228
                      goto overflow;
3229
                  }
3230
3231
                {
3232
                  const wchar_t *ls_arg;
3233
                  wchar_t lc_arg[1];
3234
                  size_t characters;
3235
3236
                  if (dp->conversion == 's')
3237
                    {
3238
                      int has_precision = 0;
3239
                      size_t precision = 6;
3240
                      if (dp->precision_start != dp->precision_end)
3241
                        {
3242
                          if (dp->precision_arg_index != ARG_NONE)
3243
                            {
3244
                              if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3245
                                abort ();
3246
                              int arg = a.arg[dp->precision_arg_index].a.a_int;
3247
                              /* "A negative precision is taken as if the precision
3248
                                  were omitted."  */
3249
                              if (arg >= 0)
3250
                                {
3251
                                  precision = arg;
3252
                                  has_precision = 1;
3253
                                }
3254
                            }
3255
                          else
3256
                            {
3257
                              const FCHAR_T *digitp = dp->precision_start + 1;
3258
3259
                              precision = 0;
3260
                              while (digitp != dp->precision_end)
3261
                                precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3262
                              has_precision = 1;
3263
                            }
3264
                        }
3265
3266
                      ls_arg = a.arg[dp->arg_index].a.a_wide_string;
3267
3268
                      if (has_precision)
3269
                        {
3270
                          /* Use only at most PRECISION wide characters, from
3271
                             the left.  */
3272
                          const wchar_t *ls_arg_end = ls_arg;
3273
                          characters = 0;
3274
                          for (; precision > 0; precision--)
3275
                            {
3276
                              if (*ls_arg_end == 0)
3277
                                /* Found the terminating null wide character.  */
3278
                                break;
3279
                              ls_arg_end++;
3280
                              characters++;
3281
                            }
3282
                        }
3283
                      else
3284
                        {
3285
                          /* Use the entire string, and count the number of wide
3286
                             characters.  */
3287
                          characters = local_wcslen (ls_arg);
3288
                        }
3289
                    }
3290
                  else /* dp->conversion == 'c' */
3291
                    {
3292
                      lc_arg[0] = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
3293
                      ls_arg = lc_arg;
3294
                      characters = 1;
3295
                    }
3296
3297
                  {
3298
                    size_t total = (characters < width ? width : characters);
3299
                    ENSURE_ALLOCATION (xsum (length, total));
3300
3301
                    if (characters < width && !(flags & FLAG_LEFT))
3302
                      {
3303
                        size_t n = width - characters;
3304
                        DCHAR_SET (result + length, ' ', n);
3305
                        length += n;
3306
                      }
3307
3308
                    if (characters > 0)
3309
                      {
3310
                        DCHAR_CPY (result + length, ls_arg, characters);
3311
                        length += characters;
3312
                      }
3313
3314
                    if (characters < width && (flags & FLAG_LEFT))
3315
                      {
3316
                        size_t n = width - characters;
3317
                        DCHAR_SET (result + length, ' ', n);
3318
                        length += n;
3319
                      }
3320
                  }
3321
                }
3322
              }
3323
#endif
3324
0
#if WIDE_CHAR_VERSION || !USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK
3325
0
            else if (dp->conversion == 's'
3326
# if WIDE_CHAR_VERSION
3327
                     && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
3328
# else
3329
0
                     && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
3330
0
# endif
3331
0
                    )
3332
0
              {
3333
                /* The normal handling of the 's' directive below requires
3334
                   allocating a temporary buffer.  The determination of its
3335
                   length (tmp_length), in the case when a precision is
3336
                   specified, below requires a conversion between a char[]
3337
                   string and a wchar_t[] wide string.  It could be done, but
3338
                   we have no guarantee that the implementation of sprintf will
3339
                   use the exactly same algorithm.  Without this guarantee, it
3340
                   is possible to have buffer overrun bugs.  In order to avoid
3341
                   such bugs, we implement the entire processing of the 's'
3342
                   directive ourselves.  */
3343
0
                int flags = dp->flags;
3344
3345
0
                int has_width = 0;
3346
0
                size_t width = 0;
3347
0
                if (dp->width_start != dp->width_end)
3348
0
                  {
3349
0
                    if (dp->width_arg_index != ARG_NONE)
3350
0
                      {
3351
0
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3352
0
                          abort ();
3353
0
                        int arg = a.arg[dp->width_arg_index].a.a_int;
3354
0
                        width = arg;
3355
0
                        if (arg < 0)
3356
0
                          {
3357
                            /* "A negative field width is taken as a '-' flag
3358
                                followed by a positive field width."  */
3359
0
                            flags |= FLAG_LEFT;
3360
0
                            width = -width;
3361
0
                          }
3362
0
                      }
3363
0
                    else
3364
0
                      {
3365
0
                        const FCHAR_T *digitp = dp->width_start;
3366
3367
0
                        do
3368
0
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
3369
0
                        while (digitp != dp->width_end);
3370
0
                      }
3371
0
                    if (width > (size_t) INT_MAX)
3372
0
                      goto overflow;
3373
0
                    has_width = 1;
3374
0
                  }
3375
3376
0
                int has_precision = 0;
3377
0
                size_t precision = 6;
3378
0
                if (dp->precision_start != dp->precision_end)
3379
0
                  {
3380
0
                    if (dp->precision_arg_index != ARG_NONE)
3381
0
                      {
3382
0
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3383
0
                          abort ();
3384
0
                        int arg = a.arg[dp->precision_arg_index].a.a_int;
3385
                        /* "A negative precision is taken as if the precision
3386
                            were omitted."  */
3387
0
                        if (arg >= 0)
3388
0
                          {
3389
0
                            precision = arg;
3390
0
                            has_precision = 1;
3391
0
                          }
3392
0
                      }
3393
0
                    else
3394
0
                      {
3395
0
                        const FCHAR_T *digitp = dp->precision_start + 1;
3396
3397
0
                        precision = 0;
3398
0
                        while (digitp != dp->precision_end)
3399
0
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3400
0
                        has_precision = 1;
3401
0
                      }
3402
0
                  }
3403
3404
# if WIDE_CHAR_VERSION
3405
                /* %s in vasnwprintf.  See the specification of fwprintf.  */
3406
                {
3407
                  const char *arg = a.arg[dp->arg_index].a.a_string;
3408
                  const char *arg_end;
3409
                  size_t characters;
3410
3411
                  if (has_precision)
3412
                    {
3413
                      /* Use only as many bytes as needed to produce PRECISION
3414
                         wide characters, from the left.  */
3415
#  if HAVE_MBRTOWC
3416
                      mbstate_t state;
3417
                      mbszero (&state);
3418
#  endif
3419
                      arg_end = arg;
3420
                      characters = 0;
3421
                      for (; precision > 0; precision--)
3422
                        {
3423
                          int count;
3424
#  if HAVE_MBRTOWC
3425
                          count = mbrlen (arg_end, MB_CUR_MAX, &state);
3426
#  else
3427
                          count = mblen (arg_end, MB_CUR_MAX);
3428
#  endif
3429
                          if (count == 0)
3430
                            /* Found the terminating NUL.  */
3431
                            break;
3432
                          if (count < 0)
3433
                            /* Invalid or incomplete multibyte character.  */
3434
                            goto fail_with_EILSEQ;
3435
                          arg_end += count;
3436
                          characters++;
3437
                        }
3438
                    }
3439
                  else if (has_width)
3440
                    {
3441
                      /* Use the entire string, and count the number of wide
3442
                         characters.  */
3443
#  if HAVE_MBRTOWC
3444
                      mbstate_t state;
3445
                      mbszero (&state);
3446
#  endif
3447
                      arg_end = arg;
3448
                      characters = 0;
3449
                      for (;;)
3450
                        {
3451
                          int count;
3452
#  if HAVE_MBRTOWC
3453
                          count = mbrlen (arg_end, MB_CUR_MAX, &state);
3454
#  else
3455
                          count = mblen (arg_end, MB_CUR_MAX);
3456
#  endif
3457
                          if (count == 0)
3458
                            /* Found the terminating NUL.  */
3459
                            break;
3460
                          if (count < 0)
3461
                            /* Invalid or incomplete multibyte character.  */
3462
                            goto fail_with_EILSEQ;
3463
                          arg_end += count;
3464
                          characters++;
3465
                        }
3466
                    }
3467
                  else
3468
                    {
3469
                      /* Use the entire string.  */
3470
                      arg_end = arg + strlen (arg);
3471
                      /* The number of characters doesn't matter.  */
3472
                      characters = 0;
3473
                    }
3474
3475
                  if (characters < width && !(flags & FLAG_LEFT))
3476
                    {
3477
                      size_t n = width - characters;
3478
                      ENSURE_ALLOCATION (xsum (length, n));
3479
                      DCHAR_SET (result + length, ' ', n);
3480
                      length += n;
3481
                    }
3482
3483
                  if (has_precision || has_width)
3484
                    {
3485
                      /* We know the number of wide characters in advance.  */
3486
#  if HAVE_MBRTOWC
3487
                      mbstate_t state;
3488
                      mbszero (&state);
3489
#  endif
3490
                      ENSURE_ALLOCATION (xsum (length, characters));
3491
                      for (size_t remaining = characters; remaining > 0; remaining--)
3492
                        {
3493
                          wchar_t wc;
3494
                          int count;
3495
#  if HAVE_MBRTOWC
3496
                          count = mbrtowc (&wc, arg, arg_end - arg, &state);
3497
#  else
3498
                          count = mbtowc (&wc, arg, arg_end - arg);
3499
#  endif
3500
                          if (count <= 0)
3501
                            /* mbrtowc not consistent with mbrlen, or mbtowc
3502
                               not consistent with mblen.  */
3503
                            abort ();
3504
                          result[length++] = wc;
3505
                          arg += count;
3506
                        }
3507
                      if (!(arg == arg_end))
3508
                        abort ();
3509
                    }
3510
                  else
3511
                    {
3512
#  if HAVE_MBRTOWC
3513
                      mbstate_t state;
3514
                      mbszero (&state);
3515
#  endif
3516
                      while (arg < arg_end)
3517
                        {
3518
                          wchar_t wc;
3519
                          int count;
3520
#  if HAVE_MBRTOWC
3521
                          count = mbrtowc (&wc, arg, arg_end - arg, &state);
3522
#  else
3523
                          count = mbtowc (&wc, arg, arg_end - arg);
3524
#  endif
3525
                          if (count == 0)
3526
                            /* mbrtowc not consistent with strlen.  */
3527
                            abort ();
3528
                          if (count < 0)
3529
                            /* Invalid or incomplete multibyte character.  */
3530
                            goto fail_with_EILSEQ;
3531
                          ENSURE_ALLOCATION (xsum (length, 1));
3532
                          result[length++] = wc;
3533
                          arg += count;
3534
                        }
3535
                    }
3536
3537
                  if (characters < width && (flags & FLAG_LEFT))
3538
                    {
3539
                      size_t n = width - characters;
3540
                      ENSURE_ALLOCATION (xsum (length, n));
3541
                      DCHAR_SET (result + length, ' ', n);
3542
                      length += n;
3543
                    }
3544
                }
3545
# else
3546
                /* %ls in vasnprintf.  See the specification of fprintf.  */
3547
0
                {
3548
0
                  const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
3549
0
                  const wchar_t *arg_end;
3550
0
                  size_t bytes;
3551
#  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3552
                  size_t characters;
3553
#  endif
3554
#  if !DCHAR_IS_TCHAR
3555
                  /* This code assumes that TCHAR_T is 'char'.  */
3556
                  static_assert (sizeof (TCHAR_T) == 1);
3557
                  DCHAR_T *tmpdst;
3558
                  size_t tmpdst_len;
3559
#  endif
3560
0
                  size_t w;
3561
3562
0
                  if (has_precision)
3563
0
                    {
3564
                      /* Use only as many wide characters as needed to produce
3565
                         at most PRECISION bytes, from the left.  */
3566
0
#  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3567
0
                      mbstate_t state;
3568
0
                      mbszero (&state);
3569
0
#  endif
3570
0
                      arg_end = arg;
3571
0
                      bytes = 0;
3572
#  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3573
                      characters = 0;
3574
#  endif
3575
0
                      while (precision > 0)
3576
0
                        {
3577
0
                          if (*arg_end == 0)
3578
                            /* Found the terminating null wide character.  */
3579
0
                            break;
3580
0
                          char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3581
0
                          int count = local_wcrtomb (cbuf, *arg_end, &state);
3582
0
                          if (count < 0)
3583
                            /* Cannot convert.  */
3584
0
                            goto fail_with_EILSEQ;
3585
0
                          if (precision < (unsigned int) count)
3586
0
                            break;
3587
0
                          arg_end++;
3588
0
                          bytes += count;
3589
#  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3590
                          characters += mbsnlen (cbuf, count);
3591
#  endif
3592
0
                          precision -= count;
3593
0
                        }
3594
0
                    }
3595
0
#  if DCHAR_IS_TCHAR
3596
0
                  else if (has_width)
3597
#  else
3598
                  else
3599
#  endif
3600
0
                    {
3601
                      /* Use the entire string, and count the number of
3602
                         bytes.  */
3603
0
#  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3604
0
                      mbstate_t state;
3605
0
                      mbszero (&state);
3606
0
#  endif
3607
0
                      arg_end = arg;
3608
0
                      bytes = 0;
3609
#  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3610
                      characters = 0;
3611
#  endif
3612
0
                      for (;;)
3613
0
                        {
3614
0
                          if (*arg_end == 0)
3615
                            /* Found the terminating null wide character.  */
3616
0
                            break;
3617
0
                          char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3618
0
                          int count = local_wcrtomb (cbuf, *arg_end, &state);
3619
0
                          if (count < 0)
3620
                            /* Cannot convert.  */
3621
0
                            goto fail_with_EILSEQ;
3622
0
                          arg_end++;
3623
0
                          bytes += count;
3624
#  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3625
                          characters += mbsnlen (cbuf, count);
3626
#  endif
3627
0
                        }
3628
0
                    }
3629
0
#  if DCHAR_IS_TCHAR
3630
0
                  else
3631
0
                    {
3632
                      /* Use the entire string.  */
3633
0
                      arg_end = arg + local_wcslen (arg);
3634
                      /* The number of bytes and characters doesn't matter,
3635
                         because !has_width and therefore width==0.  */
3636
0
                      bytes = 0;
3637
#   if ENABLE_UNISTDIO
3638
                      characters = 0;
3639
#   endif
3640
0
                    }
3641
0
#  endif
3642
3643
#  if !DCHAR_IS_TCHAR
3644
                  {
3645
                    /* Convert the string into a piece of temporary memory.  */
3646
                    TCHAR_T *tmpsrc = (TCHAR_T *) malloc (bytes * sizeof (TCHAR_T));
3647
                    if (tmpsrc == NULL)
3648
                      goto out_of_memory;
3649
                    {
3650
                      TCHAR_T *tmpptr = tmpsrc;
3651
#   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3652
                      mbstate_t state;
3653
                      mbszero (&state);
3654
#   endif
3655
                      for (size_t remaining = bytes; remaining > 0; )
3656
                        {
3657
                          if (*arg == 0)
3658
                            abort ();
3659
                          char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3660
                          int count = local_wcrtomb (cbuf, *arg, &state);
3661
                          if (count <= 0)
3662
                            /* Inconsistency.  */
3663
                            abort ();
3664
                          memcpy (tmpptr, cbuf, count);
3665
                          tmpptr += count;
3666
                          arg++;
3667
                          remaining -= count;
3668
                        }
3669
                      if (!(arg == arg_end))
3670
                        abort ();
3671
                    }
3672
3673
                    /* Convert from TCHAR_T[] to DCHAR_T[].  */
3674
                    tmpdst =
3675
                      DCHAR_CONV_FROM_ENCODING (locale_charset (),
3676
                                                iconveh_question_mark,
3677
                                                tmpsrc, bytes,
3678
                                                NULL,
3679
                                                NULL, &tmpdst_len);
3680
                    if (tmpdst == NULL)
3681
                      {
3682
                        free (tmpsrc);
3683
                        goto fail_with_errno;
3684
                      }
3685
                    free (tmpsrc);
3686
                  }
3687
#  endif
3688
3689
0
                  if (has_width)
3690
0
                    {
3691
#  if ENABLE_UNISTDIO
3692
                      /* Outside POSIX, it's preferable to compare the width
3693
                         against the number of _characters_ of the converted
3694
                         value.  */
3695
#   if DCHAR_IS_TCHAR
3696
                      w = characters;
3697
#   else
3698
                      w = DCHAR_MBSNLEN (tmpdst, tmpdst_len);
3699
#   endif
3700
#  else
3701
                      /* The width is compared against the number of _bytes_
3702
                         of the converted value, says POSIX.  */
3703
0
                      w = bytes;
3704
0
#  endif
3705
0
                    }
3706
0
                  else
3707
                    /* w doesn't matter.  */
3708
0
                    w = 0;
3709
3710
0
                  if (w < width && !(flags & FLAG_LEFT))
3711
0
                    {
3712
0
                      size_t n = width - w;
3713
0
#  if DCHAR_IS_TCHAR
3714
0
                      ENSURE_ALLOCATION (xsum (length, n));
3715
#  else
3716
                      ENSURE_ALLOCATION_ELSE (xsum (length, n),
3717
                        { free (tmpdst); goto out_of_memory; });
3718
#  endif
3719
0
                      DCHAR_SET (result + length, ' ', n);
3720
0
                      length += n;
3721
0
                    }
3722
3723
0
#  if DCHAR_IS_TCHAR
3724
0
                  if (has_precision || has_width)
3725
0
                    {
3726
                      /* We know the number of bytes in advance.  */
3727
0
#   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3728
0
                      mbstate_t state;
3729
0
                      mbszero (&state);
3730
0
#   endif
3731
0
                      ENSURE_ALLOCATION (xsum (length, bytes));
3732
0
                      for (size_t remaining = bytes; remaining > 0; )
3733
0
                        {
3734
0
                          if (*arg == 0)
3735
0
                            abort ();
3736
0
                          char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3737
0
                          int count = local_wcrtomb (cbuf, *arg, &state);
3738
0
                          if (count <= 0)
3739
                            /* Inconsistency.  */
3740
0
                            abort ();
3741
0
                          memcpy (result + length, cbuf, count);
3742
0
                          length += count;
3743
0
                          arg++;
3744
0
                          remaining -= count;
3745
0
                        }
3746
0
                      if (!(arg == arg_end))
3747
0
                        abort ();
3748
0
                    }
3749
0
                  else
3750
0
                    {
3751
0
#   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3752
0
                      mbstate_t state;
3753
0
                      mbszero (&state);
3754
0
#   endif
3755
0
                      while (arg < arg_end)
3756
0
                        {
3757
0
                          if (*arg == 0)
3758
0
                            abort ();
3759
0
                          char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3760
0
                          int count = local_wcrtomb (cbuf, *arg, &state);
3761
0
                          if (count <= 0)
3762
                            /* Cannot convert.  */
3763
0
                            goto fail_with_EILSEQ;
3764
0
                          ENSURE_ALLOCATION (xsum (length, count));
3765
0
                          memcpy (result + length, cbuf, count);
3766
0
                          length += count;
3767
0
                          arg++;
3768
0
                        }
3769
0
                    }
3770
#  else
3771
                  ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
3772
                    { free (tmpdst); goto out_of_memory; });
3773
                  DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3774
                  free (tmpdst);
3775
                  length += tmpdst_len;
3776
#  endif
3777
3778
0
                  if (w < width && (flags & FLAG_LEFT))
3779
0
                    {
3780
0
                      size_t n = width - w;
3781
0
                      ENSURE_ALLOCATION (xsum (length, n));
3782
0
                      DCHAR_SET (result + length, ' ', n);
3783
0
                      length += n;
3784
0
                    }
3785
0
                }
3786
0
# endif
3787
0
              }
3788
0
#endif
3789
#if (NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION
3790
            else if (dp->conversion == 'c'
3791
                     && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)
3792
              {
3793
                /* Implement the 'lc' directive ourselves, in order to provide
3794
                   a correct behaviour for the null wint_t argument and/or the
3795
                   fallback that avoids EILSEQ.  */
3796
                int flags = dp->flags;
3797
3798
                int has_width = 0;
3799
                size_t width = 0;
3800
                if (dp->width_start != dp->width_end)
3801
                  {
3802
                    if (dp->width_arg_index != ARG_NONE)
3803
                      {
3804
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3805
                          abort ();
3806
                        int arg = a.arg[dp->width_arg_index].a.a_int;
3807
                        width = arg;
3808
                        if (arg < 0)
3809
                          {
3810
                            /* "A negative field width is taken as a '-' flag
3811
                                followed by a positive field width."  */
3812
                            flags |= FLAG_LEFT;
3813
                            width = -width;
3814
                          }
3815
                      }
3816
                    else
3817
                      {
3818
                        const FCHAR_T *digitp = dp->width_start;
3819
3820
                        do
3821
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
3822
                        while (digitp != dp->width_end);
3823
                      }
3824
                    if (width > (size_t) INT_MAX)
3825
                      goto overflow;
3826
                    has_width = 1;
3827
                  }
3828
3829
                /* %lc in vasnprintf.  See the specification of fprintf.  */
3830
                {
3831
                  wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
3832
                  size_t bytes;
3833
# if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3834
                  size_t characters;
3835
# endif
3836
# if !DCHAR_IS_TCHAR
3837
                  /* This code assumes that TCHAR_T is 'char'.  */
3838
                  static_assert (sizeof (TCHAR_T) == 1);
3839
                  DCHAR_T *tmpdst;
3840
                  size_t tmpdst_len;
3841
# endif
3842
                  size_t w;
3843
3844
# if DCHAR_IS_TCHAR
3845
                  if (has_width)
3846
# endif
3847
                    {
3848
                      /* Count the number of bytes.  */
3849
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3850
                      mbstate_t state;
3851
                      mbszero (&state);
3852
# endif
3853
3854
                      char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3855
                      int count = local_wcrtomb (cbuf, arg, &state);
3856
                      if (count < 0)
3857
                        /* Cannot convert.  */
3858
                        goto fail_with_EILSEQ;
3859
                      bytes = count;
3860
# if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3861
                      characters = mbsnlen (cbuf, count);
3862
# endif
3863
                    }
3864
# if DCHAR_IS_TCHAR
3865
                  else
3866
                    {
3867
                      /* The number of bytes and characters doesn't matter,
3868
                         because !has_width and therefore width==0.  */
3869
                      bytes = 0;
3870
#  if ENABLE_UNISTDIO
3871
                      characters = 0;
3872
#  endif
3873
                    }
3874
# endif
3875
3876
# if !DCHAR_IS_TCHAR
3877
                  {
3878
                    TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64.  */
3879
3880
                    /* Convert the string into a piece of temporary memory.  */
3881
                    if (bytes > 0)
3882
                      {
3883
#  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3884
                        mbstate_t state;
3885
                        mbszero (&state);
3886
#  endif
3887
3888
                        char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3889
                        int count = local_wcrtomb (cbuf, arg, &state);
3890
                        if (count <= 0)
3891
                          /* Inconsistency.  */
3892
                          abort ();
3893
                        memcpy (tmpsrc, cbuf, count);
3894
                      }
3895
3896
                    /* Convert from TCHAR_T[] to DCHAR_T[].  */
3897
                    tmpdst =
3898
                      DCHAR_CONV_FROM_ENCODING (locale_charset (),
3899
                                                iconveh_question_mark,
3900
                                                tmpsrc, bytes,
3901
                                                NULL,
3902
                                                NULL, &tmpdst_len);
3903
                    if (tmpdst == NULL)
3904
                      goto fail_with_errno;
3905
                  }
3906
# endif
3907
3908
                  if (has_width)
3909
                    {
3910
# if ENABLE_UNISTDIO
3911
                      /* Outside POSIX, it's preferable to compare the width
3912
                         against the number of _characters_ of the converted
3913
                         value.  */
3914
#  if DCHAR_IS_TCHAR
3915
                      w = characters;
3916
#  else
3917
                      w = DCHAR_MBSNLEN (tmpdst, tmpdst_len);
3918
#  endif
3919
# else
3920
                      /* The width is compared against the number of _bytes_
3921
                         of the converted value, says POSIX.  */
3922
                      w = bytes;
3923
# endif
3924
                    }
3925
                  else
3926
                    /* w doesn't matter.  */
3927
                    w = 0;
3928
3929
                  if (w < width && !(flags & FLAG_LEFT))
3930
                    {
3931
                      size_t n = width - w;
3932
#  if DCHAR_IS_TCHAR
3933
                      ENSURE_ALLOCATION (xsum (length, n));
3934
#  else
3935
                      ENSURE_ALLOCATION_ELSE (xsum (length, n),
3936
                        { free (tmpdst); goto out_of_memory; });
3937
#  endif
3938
                      DCHAR_SET (result + length, ' ', n);
3939
                      length += n;
3940
                    }
3941
3942
# if DCHAR_IS_TCHAR
3943
                  if (has_width)
3944
                    {
3945
                      /* We know the number of bytes in advance.  */
3946
                      ENSURE_ALLOCATION (xsum (length, bytes));
3947
                      if (bytes > 0)
3948
                        {
3949
#  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3950
                          mbstate_t state;
3951
                          mbszero (&state);
3952
#  endif
3953
3954
                          int count = local_wcrtomb (result + length, arg, &state);
3955
                          if (count <= 0)
3956
                            /* Inconsistency.  */
3957
                            abort ();
3958
                          length += count;
3959
                        }
3960
                    }
3961
                  else
3962
                    {
3963
#  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3964
                      mbstate_t state;
3965
                      mbszero (&state);
3966
#  endif
3967
3968
                      char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
3969
                      int count = local_wcrtomb (cbuf, arg, &state);
3970
                      if (count < 0)
3971
                        /* Cannot convert.  */
3972
                        goto fail_with_EILSEQ;
3973
                      ENSURE_ALLOCATION (xsum (length, count));
3974
                      memcpy (result + length, cbuf, count);
3975
                      length += count;
3976
                    }
3977
# else
3978
                  ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
3979
                    { free (tmpdst); goto out_of_memory; });
3980
                  DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3981
                  free (tmpdst);
3982
                  length += tmpdst_len;
3983
# endif
3984
3985
                  if (w < width && (flags & FLAG_LEFT))
3986
                    {
3987
                      size_t n = width - w;
3988
                      ENSURE_ALLOCATION (xsum (length, n));
3989
                      DCHAR_SET (result + length, ' ', n);
3990
                      length += n;
3991
                    }
3992
                }
3993
              }
3994
#endif
3995
#if NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION
3996
            else if (dp->conversion == 'c'
3997
                     && a.arg[dp->arg_index].type != TYPE_WIDE_CHAR)
3998
              {
3999
                /* Implement the 'c' directive ourselves, in order to avoid
4000
                   EILSEQ in the "C" locale.  */
4001
                int flags = dp->flags;
4002
4003
                size_t width = 0;
4004
                if (dp->width_start != dp->width_end)
4005
                  {
4006
                    if (dp->width_arg_index != ARG_NONE)
4007
                      {
4008
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4009
                          abort ();
4010
                        int arg = a.arg[dp->width_arg_index].a.a_int;
4011
                        width = arg;
4012
                        if (arg < 0)
4013
                          {
4014
                            /* "A negative field width is taken as a '-' flag
4015
                                followed by a positive field width."  */
4016
                            flags |= FLAG_LEFT;
4017
                            width = -width;
4018
                          }
4019
                      }
4020
                    else
4021
                      {
4022
                        const FCHAR_T *digitp = dp->width_start;
4023
4024
                        do
4025
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
4026
                        while (digitp != dp->width_end);
4027
                      }
4028
                    if (width > (size_t) INT_MAX)
4029
                      goto overflow;
4030
                  }
4031
4032
                /* %c in vasnwprintf.  See the specification of fwprintf.  */
4033
                {
4034
                  char arg = (char) a.arg[dp->arg_index].a.a_char;
4035
                  mbstate_t state;
4036
                  mbszero (&state);
4037
4038
                  wchar_t wc;
4039
                  int count = mbrtowc (&wc, &arg, 1, &state);
4040
                  if (count < 0)
4041
                    /* Invalid or incomplete multibyte character.  */
4042
                    goto fail_with_EILSEQ;
4043
4044
                  {
4045
                    size_t total = (1 < width ? width : 1);
4046
                    ENSURE_ALLOCATION (xsum (length, total));
4047
4048
                    if (1 < width && !(flags & FLAG_LEFT))
4049
                      {
4050
                        size_t n = width - 1;
4051
                        DCHAR_SET (result + length, ' ', n);
4052
                        length += n;
4053
                      }
4054
4055
                    result[length++] = wc;
4056
4057
                    if (1 < width && (flags & FLAG_LEFT))
4058
                      {
4059
                        size_t n = width - 1;
4060
                        DCHAR_SET (result + length, ' ', n);
4061
                        length += n;
4062
                      }
4063
                  }
4064
                }
4065
              }
4066
#endif
4067
0
#if NEED_PRINTF_DIRECTIVE_B || NEED_PRINTF_DIRECTIVE_UPPERCASE_B
4068
0
            else if (0
4069
0
# if NEED_PRINTF_DIRECTIVE_B
4070
0
                     || (dp->conversion == 'b')
4071
0
# endif
4072
# if NEED_PRINTF_DIRECTIVE_UPPERCASE_B
4073
                     || (dp->conversion == 'B')
4074
# endif
4075
0
                    )
4076
0
              {
4077
0
                arg_type type = a.arg[dp->arg_index].type;
4078
0
                int flags = dp->flags;
4079
4080
0
                int has_width = 0;
4081
0
                size_t width = 0;
4082
0
                if (dp->width_start != dp->width_end)
4083
0
                  {
4084
0
                    if (dp->width_arg_index != ARG_NONE)
4085
0
                      {
4086
0
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4087
0
                          abort ();
4088
0
                        int arg = a.arg[dp->width_arg_index].a.a_int;
4089
0
                        width = arg;
4090
0
                        if (arg < 0)
4091
0
                          {
4092
                            /* "A negative field width is taken as a '-' flag
4093
                                followed by a positive field width."  */
4094
0
                            flags |= FLAG_LEFT;
4095
0
                            width = -width;
4096
0
                          }
4097
0
                      }
4098
0
                    else
4099
0
                      {
4100
0
                        const FCHAR_T *digitp = dp->width_start;
4101
4102
0
                        do
4103
0
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
4104
0
                        while (digitp != dp->width_end);
4105
0
                      }
4106
0
                    if (width > (size_t) INT_MAX)
4107
0
                      goto overflow;
4108
0
                    has_width = 1;
4109
0
                  }
4110
4111
0
                int has_precision = 0;
4112
0
                size_t precision = 1;
4113
0
                if (dp->precision_start != dp->precision_end)
4114
0
                  {
4115
0
                    if (dp->precision_arg_index != ARG_NONE)
4116
0
                      {
4117
0
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4118
0
                          abort ();
4119
0
                        int arg = a.arg[dp->precision_arg_index].a.a_int;
4120
                        /* "A negative precision is taken as if the precision
4121
                            were omitted."  */
4122
0
                        if (arg >= 0)
4123
0
                          {
4124
0
                            precision = arg;
4125
0
                            has_precision = 1;
4126
0
                          }
4127
0
                      }
4128
0
                    else
4129
0
                      {
4130
0
                        const FCHAR_T *digitp = dp->precision_start + 1;
4131
4132
0
                        precision = 0;
4133
0
                        while (digitp != dp->precision_end)
4134
0
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4135
0
                        has_precision = 1;
4136
0
                      }
4137
0
                  }
4138
4139
                /* Allocate a temporary buffer of sufficient size.  */
4140
0
                size_t tmp_length;
4141
0
                switch (type)
4142
0
                  {
4143
0
                  default:
4144
0
                    tmp_length =
4145
0
                      (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
4146
0
                      + 1; /* turn floor into ceil */
4147
0
                    break;
4148
0
                  case TYPE_ULONGINT:
4149
0
                    tmp_length =
4150
0
                      (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
4151
0
                      + 1; /* turn floor into ceil */
4152
0
                    break;
4153
0
                  case TYPE_ULONGLONGINT:
4154
0
                    tmp_length =
4155
0
                      (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
4156
0
                      + 1; /* turn floor into ceil */
4157
0
                    break;
4158
0
                  case TYPE_UINT8_T:
4159
0
                    tmp_length =
4160
0
                      (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
4161
0
                      + 1; /* turn floor into ceil */
4162
0
                    break;
4163
0
                  case TYPE_UINT16_T:
4164
0
                    tmp_length =
4165
0
                      (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
4166
0
                      + 1; /* turn floor into ceil */
4167
0
                    break;
4168
0
                  case TYPE_UINT32_T:
4169
0
                    tmp_length =
4170
0
                      (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
4171
0
                      + 1; /* turn floor into ceil */
4172
0
                    break;
4173
0
                  case TYPE_UINT64_T:
4174
0
                    tmp_length =
4175
0
                      (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
4176
0
                      + 1; /* turn floor into ceil */
4177
0
                    break;
4178
0
                  case TYPE_UINT_FAST8_T:
4179
0
                    tmp_length =
4180
0
                      (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
4181
0
                      + 1; /* turn floor into ceil */
4182
0
                    break;
4183
0
                  case TYPE_UINT_FAST16_T:
4184
0
                    tmp_length =
4185
0
                      (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
4186
0
                      + 1; /* turn floor into ceil */
4187
0
                    break;
4188
0
                  case TYPE_UINT_FAST32_T:
4189
0
                    tmp_length =
4190
0
                      (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
4191
0
                      + 1; /* turn floor into ceil */
4192
0
                    break;
4193
0
                  case TYPE_UINT_FAST64_T:
4194
0
                    tmp_length =
4195
0
                      (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
4196
0
                      + 1; /* turn floor into ceil */
4197
0
                    break;
4198
0
                  }
4199
0
                if (tmp_length < precision)
4200
0
                  tmp_length = precision;
4201
                /* Add 2, to account for a prefix from the alternate form.  */
4202
0
                tmp_length = xsum (tmp_length, 2);
4203
4204
0
                if (tmp_length < width)
4205
0
                  tmp_length = width;
4206
4207
0
                DCHAR_T tmpbuf[700];
4208
0
                DCHAR_T *tmp;
4209
0
                if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
4210
0
                  tmp = tmpbuf;
4211
0
                else
4212
0
                  {
4213
0
                    size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
4214
4215
0
                    if (size_overflow_p (tmp_memsize))
4216
                      /* Overflow, would lead to out of memory.  */
4217
0
                      goto out_of_memory;
4218
0
                    tmp = (DCHAR_T *) malloc (tmp_memsize);
4219
0
                    if (tmp == NULL)
4220
                      /* Out of memory.  */
4221
0
                      goto out_of_memory;
4222
0
                  }
4223
4224
0
                DCHAR_T *tmp_end = tmp + tmp_length;
4225
4226
0
                unsigned long long arg;
4227
0
                switch (type)
4228
0
                  {
4229
0
                  case TYPE_UCHAR:
4230
0
                    arg = a.arg[dp->arg_index].a.a_uchar;
4231
0
                    break;
4232
0
                  case TYPE_USHORT:
4233
0
                    arg = a.arg[dp->arg_index].a.a_ushort;
4234
0
                    break;
4235
0
                  case TYPE_UINT:
4236
0
                    arg = a.arg[dp->arg_index].a.a_uint;
4237
0
                    break;
4238
0
                  case TYPE_ULONGINT:
4239
0
                    arg = a.arg[dp->arg_index].a.a_ulongint;
4240
0
                    break;
4241
0
                  case TYPE_ULONGLONGINT:
4242
0
                    arg = a.arg[dp->arg_index].a.a_ulonglongint;
4243
0
                    break;
4244
0
                  case TYPE_UINT8_T:
4245
0
                    arg = a.arg[dp->arg_index].a.a_uint8_t;
4246
0
                    break;
4247
0
                  case TYPE_UINT16_T:
4248
0
                    arg = a.arg[dp->arg_index].a.a_uint16_t;
4249
0
                    break;
4250
0
                  case TYPE_UINT32_T:
4251
0
                    arg = a.arg[dp->arg_index].a.a_uint32_t;
4252
0
                    break;
4253
0
                  case TYPE_UINT64_T:
4254
0
                    arg = a.arg[dp->arg_index].a.a_uint64_t;
4255
0
                    break;
4256
0
                  case TYPE_UINT_FAST8_T:
4257
0
                    arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
4258
0
                    break;
4259
0
                  case TYPE_UINT_FAST16_T:
4260
0
                    arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
4261
0
                    break;
4262
0
                  case TYPE_UINT_FAST32_T:
4263
0
                    arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
4264
0
                    break;
4265
0
                  case TYPE_UINT_FAST64_T:
4266
0
                    arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
4267
0
                    break;
4268
0
                  default:
4269
0
                    abort ();
4270
0
                  }
4271
0
                int need_prefix = ((flags & FLAG_ALT) && arg != 0);
4272
4273
0
                DCHAR_T *p = tmp_end;
4274
                /* "The result of converting a zero value with a precision
4275
                   of zero is no characters."  */
4276
0
                if (!(has_precision && precision == 0 && arg == 0))
4277
0
                  {
4278
0
                    do
4279
0
                      {
4280
0
                        *--p = '0' + (arg & 1);
4281
0
                        arg = arg >> 1;
4282
0
                      }
4283
0
                    while (arg != 0);
4284
0
                  }
4285
4286
0
                if (has_precision)
4287
0
                  {
4288
0
                    DCHAR_T *digits_start = tmp_end - precision;
4289
0
                    while (p > digits_start)
4290
0
                      *--p = '0';
4291
0
                  }
4292
4293
0
                DCHAR_T *pad_ptr = p;
4294
4295
0
                if (need_prefix)
4296
0
                  {
4297
0
# if NEED_PRINTF_DIRECTIVE_B && !NEED_PRINTF_DIRECTIVE_UPPERCASE_B
4298
0
                    *--p = 'b';
4299
# elif NEED_PRINTF_DIRECTIVE_UPPERCASE_B && !NEED_PRINTF_DIRECTIVE_B
4300
                    *--p = 'B';
4301
# else
4302
                    *--p = dp->conversion;
4303
# endif
4304
0
                    *--p = '0';
4305
0
                  }
4306
0
                DCHAR_T *tmp_start = p;
4307
4308
                /* The generated string now extends from tmp_start to tmp_end,
4309
                   with the zero padding insertion point being at pad_ptr,
4310
                   tmp_start <= pad_ptr <= tmp_end.  */
4311
0
                size_t count = tmp_end - tmp_start;
4312
4313
0
                if (count < width)
4314
0
                  {
4315
0
                    size_t pad = width - count;
4316
4317
0
                    if (flags & FLAG_LEFT)
4318
0
                      {
4319
                        /* Pad with spaces on the right.  */
4320
0
                        for (p = tmp_start; p < tmp_end; p++)
4321
0
                          *(p - pad) = *p;
4322
0
                        for (p = tmp_end - pad; p < tmp_end; p++)
4323
0
                          *p = ' ';
4324
0
                      }
4325
0
                    else if ((flags & FLAG_ZERO)
4326
                             /* Neither ISO C nor POSIX specify that the '0'
4327
                                flag is ignored when a width and a precision
4328
                                are both present.  But most implementations
4329
                                do so.  */
4330
0
                             && !(has_width && has_precision))
4331
0
                      {
4332
                        /* Pad with zeroes.  */
4333
0
                        for (p = tmp_start; p < pad_ptr; p++)
4334
0
                          *(p - pad) = *p;
4335
0
                        for (p = pad_ptr - pad; p < pad_ptr; p++)
4336
0
                          *p = '0';
4337
0
                      }
4338
0
                    else
4339
0
                      {
4340
                        /* Pad with spaces on the left.  */
4341
0
                        for (p = tmp_start - pad; p < tmp_start; p++)
4342
0
                          *p = ' ';
4343
0
                      }
4344
4345
0
                    tmp_start = tmp_start - pad;
4346
0
                  }
4347
4348
0
                count = tmp_end - tmp_start;
4349
4350
0
                if (count > tmp_length)
4351
                  /* tmp_length was incorrectly calculated - fix the
4352
                     code above!  */
4353
0
                  abort ();
4354
4355
                /* Make room for the result.  */
4356
0
                if (count >= allocated - length)
4357
0
                  {
4358
0
                    size_t n = xsum (length, count);
4359
4360
0
                    ENSURE_ALLOCATION_ELSE (n,
4361
0
                      { if (tmp != tmpbuf) free (tmp); goto out_of_memory; });
4362
0
                  }
4363
4364
                /* Append the result.  */
4365
0
                memcpy (result + length, tmp_start, count * sizeof (DCHAR_T));
4366
0
                if (tmp != tmpbuf)
4367
0
                  free (tmp);
4368
0
                length += count;
4369
0
              }
4370
0
#endif
4371
#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
4372
            else if ((dp->conversion == 'a' || dp->conversion == 'A')
4373
# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
4374
                     && (0
4375
#  if NEED_PRINTF_DOUBLE
4376
                         || a.arg[dp->arg_index].type == TYPE_DOUBLE
4377
#  endif
4378
#  if NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
4379
                         || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
4380
#  endif
4381
                        )
4382
# endif
4383
                    )
4384
              {
4385
                arg_type type = a.arg[dp->arg_index].type;
4386
                int flags = dp->flags;
4387
4388
                size_t width = 0;
4389
                if (dp->width_start != dp->width_end)
4390
                  {
4391
                    if (dp->width_arg_index != ARG_NONE)
4392
                      {
4393
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4394
                          abort ();
4395
                        int arg = a.arg[dp->width_arg_index].a.a_int;
4396
                        width = arg;
4397
                        if (arg < 0)
4398
                          {
4399
                            /* "A negative field width is taken as a '-' flag
4400
                                followed by a positive field width."  */
4401
                            flags |= FLAG_LEFT;
4402
                            width = -width;
4403
                          }
4404
                      }
4405
                    else
4406
                      {
4407
                        const FCHAR_T *digitp = dp->width_start;
4408
4409
                        do
4410
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
4411
                        while (digitp != dp->width_end);
4412
                      }
4413
                    if (width > (size_t) INT_MAX)
4414
                      goto overflow;
4415
                  }
4416
4417
                int has_precision = 0;
4418
                size_t precision = 0;
4419
                if (dp->precision_start != dp->precision_end)
4420
                  {
4421
                    if (dp->precision_arg_index != ARG_NONE)
4422
                      {
4423
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4424
                          abort ();
4425
                        int arg = a.arg[dp->precision_arg_index].a.a_int;
4426
                        /* "A negative precision is taken as if the precision
4427
                            were omitted."  */
4428
                        if (arg >= 0)
4429
                          {
4430
                            precision = arg;
4431
                            has_precision = 1;
4432
                          }
4433
                      }
4434
                    else
4435
                      {
4436
                        const FCHAR_T *digitp = dp->precision_start + 1;
4437
4438
                        precision = 0;
4439
                        while (digitp != dp->precision_end)
4440
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4441
                        has_precision = 1;
4442
                      }
4443
                  }
4444
4445
                /* Allocate a temporary buffer of sufficient size.  */
4446
                size_t tmp_length;
4447
                if (type == TYPE_LONGDOUBLE)
4448
                  tmp_length =
4449
                    (unsigned int) ((LDBL_DIG + 1)
4450
                                    * 0.831 /* decimal -> hexadecimal */
4451
                                   )
4452
                    + 1; /* turn floor into ceil */
4453
                else
4454
                  tmp_length =
4455
                    (unsigned int) ((DBL_DIG + 1)
4456
                                    * 0.831 /* decimal -> hexadecimal */
4457
                                   )
4458
                    + 1; /* turn floor into ceil */
4459
                if (tmp_length < precision)
4460
                  tmp_length = precision;
4461
                /* Account for sign, decimal point etc. */
4462
                tmp_length = xsum (tmp_length, 12);
4463
4464
                if (tmp_length < width)
4465
                  tmp_length = width;
4466
4467
                tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
4468
4469
                DCHAR_T tmpbuf[700];
4470
                DCHAR_T *tmp;
4471
                if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
4472
                  tmp = tmpbuf;
4473
                else
4474
                  {
4475
                    size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
4476
4477
                    if (size_overflow_p (tmp_memsize))
4478
                      /* Overflow, would lead to out of memory.  */
4479
                      goto out_of_memory;
4480
                    tmp = (DCHAR_T *) malloc (tmp_memsize);
4481
                    if (tmp == NULL)
4482
                      /* Out of memory.  */
4483
                      goto out_of_memory;
4484
                  }
4485
4486
                DCHAR_T *pad_ptr = NULL;
4487
                DCHAR_T *p = tmp;
4488
                if (type == TYPE_LONGDOUBLE)
4489
                  {
4490
# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
4491
                    long double arg = a.arg[dp->arg_index].a.a_longdouble;
4492
4493
                    if (isnanl (arg))
4494
                      {
4495
                        if (dp->conversion == 'A')
4496
                          {
4497
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4498
                          }
4499
                        else
4500
                          {
4501
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4502
                          }
4503
                      }
4504
                    else
4505
                      {
4506
                        DECL_LONG_DOUBLE_ROUNDING
4507
4508
                        BEGIN_LONG_DOUBLE_ROUNDING ();
4509
4510
                        int sign = 0;
4511
                        if (signbit (arg)) /* arg < 0.0L or negative zero */
4512
                          {
4513
                            sign = -1;
4514
                            arg = -arg;
4515
                          }
4516
4517
                        if (sign < 0)
4518
                          *p++ = '-';
4519
                        else if (flags & FLAG_SHOWSIGN)
4520
                          *p++ = '+';
4521
                        else if (flags & FLAG_SPACE)
4522
                          *p++ = ' ';
4523
4524
                        if (arg > 0.0L && arg + arg == arg)
4525
                          {
4526
                            if (dp->conversion == 'A')
4527
                              {
4528
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4529
                              }
4530
                            else
4531
                              {
4532
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4533
                              }
4534
                          }
4535
                        else
4536
                          {
4537
                            int exponent;
4538
                            long double mantissa;
4539
                            if (arg > 0.0L)
4540
                              mantissa = printf_frexpl (arg, &exponent);
4541
                            else
4542
                              {
4543
                                exponent = 0;
4544
                                mantissa = 0.0L;
4545
                              }
4546
4547
                            if (has_precision
4548
                                && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
4549
                              {
4550
                                /* Round the mantissa.  */
4551
                                long double tail = mantissa;
4552
4553
                                for (size_t q = precision; ; q--)
4554
                                  {
4555
                                    int digit = (int) tail;
4556
                                    tail -= digit;
4557
                                    if (q == 0)
4558
                                      {
4559
                                        if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
4560
                                          tail = 1 - tail;
4561
                                        else
4562
                                          tail = - tail;
4563
                                        break;
4564
                                      }
4565
                                    tail *= 16.0L;
4566
                                  }
4567
                                if (tail != 0.0L)
4568
                                  for (size_t q = precision; q > 0; q--)
4569
                                    tail *= 0.0625L;
4570
                                mantissa += tail;
4571
                              }
4572
4573
                            *p++ = '0';
4574
                            *p++ = dp->conversion - 'A' + 'X';
4575
                            pad_ptr = p;
4576
                            {
4577
                              int digit = (int) mantissa;
4578
                              mantissa -= digit;
4579
                              *p++ = '0' + digit;
4580
                              if ((flags & FLAG_ALT)
4581
                                  || mantissa > 0.0L || precision > 0)
4582
                                {
4583
                                  *p++ = decimal_point_char ();
4584
                                  /* This loop terminates because we assume
4585
                                     that FLT_RADIX is a power of 2.  */
4586
                                  while (mantissa > 0.0L)
4587
                                    {
4588
                                      mantissa *= 16.0L;
4589
                                      digit = (int) mantissa;
4590
                                      mantissa -= digit;
4591
                                      *p++ = digit
4592
                                             + (digit < 10
4593
                                                ? '0'
4594
                                                : dp->conversion - 10);
4595
                                      if (precision > 0)
4596
                                        precision--;
4597
                                    }
4598
                                  while (precision > 0)
4599
                                    {
4600
                                      *p++ = '0';
4601
                                      precision--;
4602
                                    }
4603
                                }
4604
                              }
4605
                              *p++ = dp->conversion - 'A' + 'P';
4606
#  if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
4607
                              {
4608
                                static const wchar_t decimal_format[] =
4609
                                  { '%', '+', 'd', '\0' };
4610
                                SNPRINTF (p, 6 + 1, decimal_format, exponent);
4611
                              }
4612
                              while (*p != '\0')
4613
                                p++;
4614
#  else
4615
                              if (sizeof (DCHAR_T) == 1)
4616
                                {
4617
                                  sprintf ((char *) p, "%+d", exponent);
4618
                                  while (*p != '\0')
4619
                                    p++;
4620
                                }
4621
                              else
4622
                                {
4623
                                  char expbuf[6 + 1];
4624
                                  sprintf (expbuf, "%+d", exponent);
4625
                                  for (const char *ep = expbuf; (*p = *ep) != '\0'; ep++)
4626
                                    p++;
4627
                                }
4628
#  endif
4629
                          }
4630
4631
                        END_LONG_DOUBLE_ROUNDING ();
4632
                      }
4633
# else
4634
                    abort ();
4635
# endif
4636
                  }
4637
                else
4638
                  {
4639
# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
4640
                    double arg = a.arg[dp->arg_index].a.a_double;
4641
4642
                    if (isnand (arg))
4643
                      {
4644
                        if (dp->conversion == 'A')
4645
                          {
4646
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4647
                          }
4648
                        else
4649
                          {
4650
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4651
                          }
4652
                      }
4653
                    else
4654
                      {
4655
                        int sign = 0;
4656
                        if (signbit (arg)) /* arg < 0.0 or negative zero */
4657
                          {
4658
                            sign = -1;
4659
                            arg = -arg;
4660
                          }
4661
4662
                        if (sign < 0)
4663
                          *p++ = '-';
4664
                        else if (flags & FLAG_SHOWSIGN)
4665
                          *p++ = '+';
4666
                        else if (flags & FLAG_SPACE)
4667
                          *p++ = ' ';
4668
4669
                        if (arg > 0.0 && arg + arg == arg)
4670
                          {
4671
                            if (dp->conversion == 'A')
4672
                              {
4673
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4674
                              }
4675
                            else
4676
                              {
4677
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4678
                              }
4679
                          }
4680
                        else
4681
                          {
4682
                            int exponent;
4683
                            double mantissa;
4684
                            if (arg > 0.0)
4685
                              mantissa = printf_frexp (arg, &exponent);
4686
                            else
4687
                              {
4688
                                exponent = 0;
4689
                                mantissa = 0.0;
4690
                              }
4691
4692
                            if (has_precision
4693
                                && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
4694
                              {
4695
                                /* Round the mantissa.  */
4696
                                double tail = mantissa;
4697
4698
                                for (size_t q = precision; ; q--)
4699
                                  {
4700
                                    int digit = (int) tail;
4701
                                    tail -= digit;
4702
                                    if (q == 0)
4703
                                      {
4704
                                        if (digit & 1 ? tail >= 0.5 : tail > 0.5)
4705
                                          tail = 1 - tail;
4706
                                        else
4707
                                          tail = - tail;
4708
                                        break;
4709
                                      }
4710
                                    tail *= 16.0;
4711
                                  }
4712
                                if (tail != 0.0)
4713
                                  for (size_t q = precision; q > 0; q--)
4714
                                    tail *= 0.0625;
4715
                                mantissa += tail;
4716
                              }
4717
4718
                            *p++ = '0';
4719
                            *p++ = dp->conversion - 'A' + 'X';
4720
                            pad_ptr = p;
4721
                            {
4722
                              int digit = (int) mantissa;
4723
                              mantissa -= digit;
4724
                              *p++ = '0' + digit;
4725
                              if ((flags & FLAG_ALT)
4726
                                  || mantissa > 0.0 || precision > 0)
4727
                                {
4728
                                  *p++ = decimal_point_char ();
4729
                                  /* This loop terminates because we assume
4730
                                     that FLT_RADIX is a power of 2.  */
4731
                                  while (mantissa > 0.0)
4732
                                    {
4733
                                      mantissa *= 16.0;
4734
                                      digit = (int) mantissa;
4735
                                      mantissa -= digit;
4736
                                      *p++ = digit
4737
                                             + (digit < 10
4738
                                                ? '0'
4739
                                                : dp->conversion - 10);
4740
                                      if (precision > 0)
4741
                                        precision--;
4742
                                    }
4743
                                  while (precision > 0)
4744
                                    {
4745
                                      *p++ = '0';
4746
                                      precision--;
4747
                                    }
4748
                                }
4749
                              }
4750
                              *p++ = dp->conversion - 'A' + 'P';
4751
#  if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
4752
                              {
4753
                                static const wchar_t decimal_format[] =
4754
                                  { '%', '+', 'd', '\0' };
4755
                                SNPRINTF (p, 6 + 1, decimal_format, exponent);
4756
                              }
4757
                              while (*p != '\0')
4758
                                p++;
4759
#  else
4760
                              if (sizeof (DCHAR_T) == 1)
4761
                                {
4762
                                  sprintf ((char *) p, "%+d", exponent);
4763
                                  while (*p != '\0')
4764
                                    p++;
4765
                                }
4766
                              else
4767
                                {
4768
                                  char expbuf[6 + 1];
4769
                                  sprintf (expbuf, "%+d", exponent);
4770
                                  for (const char *ep = expbuf; (*p = *ep) != '\0'; ep++)
4771
                                    p++;
4772
                                }
4773
#  endif
4774
                          }
4775
                      }
4776
# else
4777
                    abort ();
4778
# endif
4779
                  }
4780
4781
                /* The generated string now extends from tmp to p, with the
4782
                   zero padding insertion point being at pad_ptr.  */
4783
                size_t count = p - tmp;
4784
4785
                if (count < width)
4786
                  {
4787
                    size_t pad = width - count;
4788
                    DCHAR_T *end = p + pad;
4789
4790
                    if (flags & FLAG_LEFT)
4791
                      {
4792
                        /* Pad with spaces on the right.  */
4793
                        for (; pad > 0; pad--)
4794
                          *p++ = ' ';
4795
                      }
4796
                    else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4797
                      {
4798
                        /* Pad with zeroes.  */
4799
                        DCHAR_T *q = end;
4800
4801
                        while (p > pad_ptr)
4802
                          *--q = *--p;
4803
                        for (; pad > 0; pad--)
4804
                          *p++ = '0';
4805
                      }
4806
                    else
4807
                      {
4808
                        /* Pad with spaces on the left.  */
4809
                        DCHAR_T *q = end;
4810
4811
                        while (p > tmp)
4812
                          *--q = *--p;
4813
                        for (; pad > 0; pad--)
4814
                          *p++ = ' ';
4815
                      }
4816
4817
                    p = end;
4818
                  }
4819
4820
                count = p - tmp;
4821
4822
                if (count >= tmp_length)
4823
                  /* tmp_length was incorrectly calculated - fix the
4824
                     code above!  */
4825
                  abort ();
4826
4827
                /* Make room for the result.  */
4828
                if (count >= allocated - length)
4829
                  {
4830
                    size_t n = xsum (length, count);
4831
4832
                    ENSURE_ALLOCATION_ELSE (n,
4833
                      { if (tmp != tmpbuf) free (tmp); goto out_of_memory; });
4834
                  }
4835
4836
                /* Append the result.  */
4837
                memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4838
                if (tmp != tmpbuf)
4839
                  free (tmp);
4840
                length += count;
4841
              }
4842
#endif
4843
#if NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE
4844
            else if ((dp->conversion == 'f' || dp->conversion == 'F'
4845
                      || dp->conversion == 'e' || dp->conversion == 'E'
4846
                      || dp->conversion == 'g' || dp->conversion == 'G'
4847
                      || dp->conversion == 'a' || dp->conversion == 'A')
4848
                     && (0
4849
# if NEED_PRINTF_DOUBLE
4850
                         || a.arg[dp->arg_index].type == TYPE_DOUBLE
4851
# elif NEED_PRINTF_INFINITE_DOUBLE
4852
                         || (a.arg[dp->arg_index].type == TYPE_DOUBLE
4853
                             /* The systems (mingw) which produce wrong output
4854
                                for Inf, -Inf, and NaN also do so for -0.0.
4855
                                Therefore we treat this case here as well.  */
4856
                             && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
4857
# endif
4858
# if NEED_PRINTF_LONG_DOUBLE
4859
                         || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
4860
# elif NEED_PRINTF_INFINITE_LONG_DOUBLE
4861
                         || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
4862
                             /* Some systems produce wrong output for Inf,
4863
                                -Inf, and NaN.  Some systems in this category
4864
                                also do so for -0.0.  Therefore we treat this
4865
                                case here as well.  */
4866
                             && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
4867
# endif
4868
                        ))
4869
              {
4870
# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
4871
                arg_type type = a.arg[dp->arg_index].type;
4872
# endif
4873
                int flags = dp->flags;
4874
4875
                size_t width = 0;
4876
                if (dp->width_start != dp->width_end)
4877
                  {
4878
                    if (dp->width_arg_index != ARG_NONE)
4879
                      {
4880
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4881
                          abort ();
4882
                        int arg = a.arg[dp->width_arg_index].a.a_int;
4883
                        width = arg;
4884
                        if (arg < 0)
4885
                          {
4886
                            /* "A negative field width is taken as a '-' flag
4887
                                followed by a positive field width."  */
4888
                            flags |= FLAG_LEFT;
4889
                            width = -width;
4890
                          }
4891
                      }
4892
                    else
4893
                      {
4894
                        const FCHAR_T *digitp = dp->width_start;
4895
4896
                        do
4897
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
4898
                        while (digitp != dp->width_end);
4899
                      }
4900
                    if (width > (size_t) INT_MAX)
4901
                      goto overflow;
4902
                  }
4903
4904
                int has_precision = 0;
4905
                size_t precision = 0;
4906
                if (dp->precision_start != dp->precision_end)
4907
                  {
4908
                    if (dp->precision_arg_index != ARG_NONE)
4909
                      {
4910
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4911
                          abort ();
4912
                        int arg = a.arg[dp->precision_arg_index].a.a_int;
4913
                        /* "A negative precision is taken as if the precision
4914
                            were omitted."  */
4915
                        if (arg >= 0)
4916
                          {
4917
                            precision = arg;
4918
                            has_precision = 1;
4919
                          }
4920
                      }
4921
                    else
4922
                      {
4923
                        const FCHAR_T *digitp = dp->precision_start + 1;
4924
4925
                        precision = 0;
4926
                        while (digitp != dp->precision_end)
4927
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4928
                        has_precision = 1;
4929
                      }
4930
                  }
4931
4932
                /* POSIX specifies the default precision to be 6 for %f, %F,
4933
                   %e, %E, but not for %g, %G.  Implementations appear to use
4934
                   the same default precision also for %g, %G.  But for %a, %A,
4935
                   the default precision is 0.  */
4936
                if (!has_precision)
4937
                  if (!(dp->conversion == 'a' || dp->conversion == 'A'))
4938
                    precision = 6;
4939
4940
                /* Allocate a temporary buffer of sufficient size.  */
4941
                size_t tmp_length;
4942
# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
4943
                tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
4944
# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
4945
                tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
4946
# elif NEED_PRINTF_LONG_DOUBLE
4947
                tmp_length = LDBL_DIG + 1;
4948
# elif NEED_PRINTF_DOUBLE
4949
                tmp_length = DBL_DIG + 1;
4950
# else
4951
                tmp_length = 0;
4952
# endif
4953
                if (tmp_length < precision)
4954
                  tmp_length = precision;
4955
# if NEED_PRINTF_LONG_DOUBLE
4956
#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4957
                if (type == TYPE_LONGDOUBLE)
4958
#  endif
4959
                  if (dp->conversion == 'f' || dp->conversion == 'F')
4960
                    {
4961
                      long double arg = a.arg[dp->arg_index].a.a_longdouble;
4962
                      if (!(isnanl (arg) || arg + arg == arg))
4963
                        {
4964
                          /* arg is finite and nonzero.  */
4965
                          int exponent = floorlog10l (arg < 0 ? -arg : arg);
4966
                          if (exponent >= 0 && tmp_length < exponent + precision)
4967
                            tmp_length = exponent + precision;
4968
                        }
4969
                    }
4970
# endif
4971
# if NEED_PRINTF_DOUBLE
4972
#  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
4973
                if (type == TYPE_DOUBLE)
4974
#  endif
4975
                  if (dp->conversion == 'f' || dp->conversion == 'F')
4976
                    {
4977
                      double arg = a.arg[dp->arg_index].a.a_double;
4978
                      if (!(isnand (arg) || arg + arg == arg))
4979
                        {
4980
                          /* arg is finite and nonzero.  */
4981
                          int exponent = floorlog10 (arg < 0 ? -arg : arg);
4982
                          if (exponent >= 0 && tmp_length < exponent + precision)
4983
                            tmp_length = exponent + precision;
4984
                        }
4985
                    }
4986
# endif
4987
                /* Account for thousands separators.  */
4988
                if (flags & FLAG_GROUP)
4989
                  {
4990
                    /* A thousands separator needs to be inserted at most every 2 digits.
4991
                       This is the case in the ta_IN locale.  */
4992
# if WIDE_CHAR_VERSION
4993
                    tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_WCHAR_MAXLEN);
4994
# else
4995
                    tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_CHAR_MAXLEN);
4996
# endif
4997
                  }
4998
                /* Account for sign, decimal point etc. */
4999
                tmp_length = xsum (tmp_length, 12);
5000
5001
                if (tmp_length < width)
5002
                  tmp_length = width;
5003
5004
                tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
5005
5006
                DCHAR_T tmpbuf[700];
5007
                DCHAR_T *tmp;
5008
                if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
5009
                  tmp = tmpbuf;
5010
                else
5011
                  {
5012
                    size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
5013
5014
                    if (size_overflow_p (tmp_memsize))
5015
                      /* Overflow, would lead to out of memory.  */
5016
                      goto out_of_memory;
5017
                    tmp = (DCHAR_T *) malloc (tmp_memsize);
5018
                    if (tmp == NULL)
5019
                      /* Out of memory.  */
5020
                      goto out_of_memory;
5021
                  }
5022
5023
                DCHAR_T *pad_ptr = NULL;
5024
                DCHAR_T *p = tmp;
5025
5026
# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
5027
#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
5028
                if (type == TYPE_LONGDOUBLE)
5029
#  endif
5030
                  {
5031
                    long double arg = a.arg[dp->arg_index].a.a_longdouble;
5032
5033
                    if (isnanl (arg))
5034
                      {
5035
                        if (dp->conversion >= 'A' && dp->conversion <= 'Z')
5036
                          {
5037
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
5038
                          }
5039
                        else
5040
                          {
5041
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
5042
                          }
5043
                      }
5044
                    else
5045
                      {
5046
                        DECL_LONG_DOUBLE_ROUNDING
5047
5048
                        BEGIN_LONG_DOUBLE_ROUNDING ();
5049
5050
                        int sign = 0;
5051
                        if (signbit (arg)) /* arg < 0.0L or negative zero */
5052
                          {
5053
                            sign = -1;
5054
                            arg = -arg;
5055
                          }
5056
5057
                        if (sign < 0)
5058
                          *p++ = '-';
5059
                        else if (flags & FLAG_SHOWSIGN)
5060
                          *p++ = '+';
5061
                        else if (flags & FLAG_SPACE)
5062
                          *p++ = ' ';
5063
5064
                        if (arg > 0.0L && arg + arg == arg)
5065
                          {
5066
                            if (dp->conversion >= 'A' && dp->conversion <= 'Z')
5067
                              {
5068
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
5069
                              }
5070
                            else
5071
                              {
5072
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
5073
                              }
5074
                          }
5075
                        else
5076
                          {
5077
#  if NEED_PRINTF_LONG_DOUBLE
5078
                            pad_ptr = p;
5079
5080
                            if (dp->conversion == 'f' || dp->conversion == 'F')
5081
                              {
5082
                                char *digits =
5083
                                  scale10_round_decimal_long_double (arg, precision);
5084
                                if (digits == NULL)
5085
                                  {
5086
                                    END_LONG_DOUBLE_ROUNDING ();
5087
                                    goto out_of_memory;
5088
                                  }
5089
                                size_t ndigits = strlen (digits);
5090
5091
                                if (ndigits > precision)
5092
                                  {
5093
                                    /* Number of digits before the decimal point.  */
5094
                                    size_t intpart_digits = ndigits - precision;
5095
5096
                                    const DCHAR_T *thousep = NULL;
5097
                                    DCHAR_T thousep_buf[10];
5098
#   if !WIDE_CHAR_VERSION
5099
                                    size_t thousep_len = 0;
5100
#   endif
5101
                                    const signed char *grouping;
5102
                                    size_t insert = 0;
5103
5104
                                    if ((flags & FLAG_GROUP) && (intpart_digits > 1))
5105
                                      {
5106
                                        /* Determine the thousands separator and
5107
                                           the grouping rule of the current locale.  */
5108
#   if WIDE_CHAR_VERSION
5109
                                        /* DCHAR_T is wchar_t.  */
5110
                                        thousep = thousands_separator_wchar (thousep_buf);
5111
#                                       define thousep_len 1
5112
#   elif defined DCHAR_CONV_FROM_ENCODING
5113
                                        /* DCHAR_T is uintN_t.  */
5114
                                        thousep = thousands_separator_DCHAR (thousep_buf);
5115
                                        thousep_len = DCHAR_STRLEN (thousep);
5116
#   else
5117
                                        /* DCHAR_T is char.  */
5118
                                        thousep = thousands_separator_char (thousep_buf);
5119
                                        thousep_len = strlen (thousep);
5120
#   endif
5121
                                        if (*thousep == 0)
5122
                                          thousep = NULL;
5123
                                        if (thousep != NULL)
5124
                                          {
5125
                                            grouping = grouping_rule ();
5126
                                            insert =
5127
                                              num_thousands_separators (grouping, intpart_digits);
5128
                                          }
5129
                                      }
5130
5131
                                    const char *digitp = digits + precision;
5132
                                    DCHAR_T *p_before_intpart = p;
5133
                                    p += intpart_digits + insert * thousep_len;
5134
                                    DCHAR_T *p_after_intpart = p;
5135
                                    if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
5136
                                      {
5137
                                        const signed char *g = grouping;
5138
                                        for (;;)
5139
                                          {
5140
                                            int h = *g;
5141
                                            if (h <= 0)
5142
                                              abort ();
5143
                                            int i = h;
5144
                                            do
5145
                                              *--p = *digitp++;
5146
                                            while (--i > 0);
5147
#   if WIDE_CHAR_VERSION
5148
                                            *--p = thousep[0];
5149
#   else
5150
                                            p -= thousep_len;
5151
                                            DCHAR_CPY (p, thousep, thousep_len);
5152
#   endif
5153
                                            insert--;
5154
                                            if (insert == 0)
5155
                                              break;
5156
                                            if (g[1] != 0)
5157
                                              g++;
5158
                                          }
5159
                                      }
5160
                                    for (;;)
5161
                                      {
5162
                                        *--p = *digitp++;
5163
                                        if (p == p_before_intpart)
5164
                                          break;
5165
                                      }
5166
                                    p = p_after_intpart;
5167
                                    ndigits = precision;
5168
#   undef thousep_len
5169
                                  }
5170
                                else
5171
                                  *p++ = '0';
5172
                                /* Here ndigits <= precision.  */
5173
                                if ((flags & FLAG_ALT) || precision > 0)
5174
                                  {
5175
                                    *p++ = decimal_point_char ();
5176
                                    for (; precision > ndigits; precision--)
5177
                                      *p++ = '0';
5178
                                    while (ndigits > 0)
5179
                                      {
5180
                                        --ndigits;
5181
                                        *p++ = digits[ndigits];
5182
                                      }
5183
                                  }
5184
5185
                                free (digits);
5186
                              }
5187
                            else if (dp->conversion == 'e' || dp->conversion == 'E')
5188
                              {
5189
                                int exponent;
5190
5191
                                if (arg == 0.0L)
5192
                                  {
5193
                                    exponent = 0;
5194
                                    *p++ = '0';
5195
                                    if ((flags & FLAG_ALT) || precision > 0)
5196
                                      {
5197
                                        *p++ = decimal_point_char ();
5198
                                        for (; precision > 0; precision--)
5199
                                          *p++ = '0';
5200
                                      }
5201
                                  }
5202
                                else
5203
                                  {
5204
                                    /* arg > 0.0L.  */
5205
                                    exponent = floorlog10l (arg);
5206
                                    int adjusted = 0;
5207
                                    char *digits;
5208
                                    size_t ndigits;
5209
                                    for (;;)
5210
                                      {
5211
                                        digits =
5212
                                          scale10_round_decimal_long_double (arg,
5213
                                                                             (int)precision - exponent);
5214
                                        if (digits == NULL)
5215
                                          {
5216
                                            END_LONG_DOUBLE_ROUNDING ();
5217
                                            goto out_of_memory;
5218
                                          }
5219
                                        ndigits = strlen (digits);
5220
5221
                                        if (ndigits == precision + 1)
5222
                                          break;
5223
                                        if (ndigits < precision
5224
                                            || ndigits > precision + 2)
5225
                                          /* The exponent was not guessed
5226
                                             precisely enough.  */
5227
                                          abort ();
5228
                                        if (adjusted)
5229
                                          /* None of two values of exponent is
5230
                                             the right one.  Prevent an endless
5231
                                             loop.  */
5232
                                          abort ();
5233
                                        free (digits);
5234
                                        if (ndigits == precision)
5235
                                          exponent -= 1;
5236
                                        else
5237
                                          exponent += 1;
5238
                                        adjusted = 1;
5239
                                      }
5240
                                    /* Here ndigits = precision+1.  */
5241
                                    if (is_borderline (digits, precision))
5242
                                      {
5243
                                        /* Maybe the exponent guess was too high
5244
                                           and a smaller exponent can be reached
5245
                                           by turning a 10...0 into 9...9x.  */
5246
                                        char *digits2 =
5247
                                          scale10_round_decimal_long_double (arg,
5248
                                                                             (int)precision - exponent + 1);
5249
                                        if (digits2 == NULL)
5250
                                          {
5251
                                            free (digits);
5252
                                            END_LONG_DOUBLE_ROUNDING ();
5253
                                            goto out_of_memory;
5254
                                          }
5255
                                        if (strlen (digits2) == precision + 1)
5256
                                          {
5257
                                            free (digits);
5258
                                            digits = digits2;
5259
                                            exponent -= 1;
5260
                                          }
5261
                                        else
5262
                                          free (digits2);
5263
                                      }
5264
                                    /* Here ndigits = precision+1.  */
5265
5266
                                    *p++ = digits[--ndigits];
5267
                                    if ((flags & FLAG_ALT) || precision > 0)
5268
                                      {
5269
                                        *p++ = decimal_point_char ();
5270
                                        while (ndigits > 0)
5271
                                          {
5272
                                            --ndigits;
5273
                                            *p++ = digits[ndigits];
5274
                                          }
5275
                                      }
5276
5277
                                    free (digits);
5278
                                  }
5279
5280
                                *p++ = dp->conversion; /* 'e' or 'E' */
5281
#   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
5282
                                {
5283
                                  static const wchar_t decimal_format[] =
5284
                                    { '%', '+', '.', '2', 'd', '\0' };
5285
                                  SNPRINTF (p, 6 + 1, decimal_format, exponent);
5286
                                }
5287
                                while (*p != '\0')
5288
                                  p++;
5289
#   else
5290
                                if (sizeof (DCHAR_T) == 1)
5291
                                  {
5292
                                    sprintf ((char *) p, "%+.2d", exponent);
5293
                                    while (*p != '\0')
5294
                                      p++;
5295
                                  }
5296
                                else
5297
                                  {
5298
                                    char expbuf[6 + 1];
5299
                                    sprintf (expbuf, "%+.2d", exponent);
5300
                                    for (const char *ep = expbuf; (*p = *ep) != '\0'; ep++)
5301
                                      p++;
5302
                                  }
5303
#   endif
5304
                              }
5305
                            else if (dp->conversion == 'g' || dp->conversion == 'G')
5306
                              {
5307
                                if (precision == 0)
5308
                                  precision = 1;
5309
                                /* precision >= 1.  */
5310
5311
                                if (arg == 0.0L)
5312
                                  /* The exponent is 0, >= -4, < precision.
5313
                                     Use fixed-point notation.  */
5314
                                  {
5315
                                    size_t ndigits = precision;
5316
                                    /* Number of trailing zeroes that have to be
5317
                                       dropped.  */
5318
                                    size_t nzeroes =
5319
                                      (flags & FLAG_ALT ? 0 : precision - 1);
5320
5321
                                    --ndigits;
5322
                                    *p++ = '0';
5323
                                    if ((flags & FLAG_ALT) || ndigits > nzeroes)
5324
                                      {
5325
                                        *p++ = decimal_point_char ();
5326
                                        while (ndigits > nzeroes)
5327
                                          {
5328
                                            --ndigits;
5329
                                            *p++ = '0';
5330
                                          }
5331
                                      }
5332
                                  }
5333
                                else
5334
                                  {
5335
                                    /* arg > 0.0L.  */
5336
                                    int exponent = floorlog10l (arg);
5337
                                    int adjusted = 0;
5338
                                    char *digits;
5339
                                    size_t ndigits;
5340
                                    for (;;)
5341
                                      {
5342
                                        digits =
5343
                                          scale10_round_decimal_long_double (arg,
5344
                                                                             (int)(precision - 1) - exponent);
5345
                                        if (digits == NULL)
5346
                                          {
5347
                                            END_LONG_DOUBLE_ROUNDING ();
5348
                                            goto out_of_memory;
5349
                                          }
5350
                                        ndigits = strlen (digits);
5351
5352
                                        if (ndigits == precision)
5353
                                          break;
5354
                                        if (ndigits < precision - 1
5355
                                            || ndigits > precision + 1)
5356
                                          /* The exponent was not guessed
5357
                                             precisely enough.  */
5358
                                          abort ();
5359
                                        if (adjusted)
5360
                                          /* None of two values of exponent is
5361
                                             the right one.  Prevent an endless
5362
                                             loop.  */
5363
                                          abort ();
5364
                                        free (digits);
5365
                                        if (ndigits < precision)
5366
                                          exponent -= 1;
5367
                                        else
5368
                                          exponent += 1;
5369
                                        adjusted = 1;
5370
                                      }
5371
                                    /* Here ndigits = precision.  */
5372
                                    if (is_borderline (digits, precision - 1))
5373
                                      {
5374
                                        /* Maybe the exponent guess was too high
5375
                                           and a smaller exponent can be reached
5376
                                           by turning a 10...0 into 9...9x.  */
5377
                                        char *digits2 =
5378
                                          scale10_round_decimal_long_double (arg,
5379
                                                                             (int)(precision - 1) - exponent + 1);
5380
                                        if (digits2 == NULL)
5381
                                          {
5382
                                            free (digits);
5383
                                            END_LONG_DOUBLE_ROUNDING ();
5384
                                            goto out_of_memory;
5385
                                          }
5386
                                        if (strlen (digits2) == precision)
5387
                                          {
5388
                                            free (digits);
5389
                                            digits = digits2;
5390
                                            exponent -= 1;
5391
                                          }
5392
                                        else
5393
                                          free (digits2);
5394
                                      }
5395
                                    /* Here ndigits = precision.  */
5396
5397
                                    /* Determine the number of trailing zeroes
5398
                                       that have to be dropped.  */
5399
                                    size_t nzeroes = 0;
5400
                                    if ((flags & FLAG_ALT) == 0)
5401
                                      while (nzeroes < ndigits
5402
                                             && digits[nzeroes] == '0')
5403
                                        nzeroes++;
5404
5405
                                    /* The exponent is now determined.  */
5406
                                    if (exponent >= -4
5407
                                        && exponent < (long)precision)
5408
                                      {
5409
                                        /* Fixed-point notation:
5410
                                           max(exponent,0)+1 digits, then the
5411
                                           decimal point, then the remaining
5412
                                           digits without trailing zeroes.  */
5413
                                        if (exponent >= 0)
5414
                                          {
5415
                                            /* Number of digits before the decimal point.  */
5416
                                            size_t intpart_digits = exponent + 1;
5417
                                            /* Note: intpart_digits <= precision = ndigits.  */
5418
5419
                                            const DCHAR_T *thousep = NULL;
5420
                                            DCHAR_T thousep_buf[10];
5421
#   if !WIDE_CHAR_VERSION
5422
                                            size_t thousep_len = 0;
5423
#   endif
5424
                                            const signed char *grouping;
5425
                                            size_t insert = 0;
5426
5427
                                            if ((flags & FLAG_GROUP) && (intpart_digits > 1))
5428
                                              {
5429
                                                /* Determine the thousands separator and
5430
                                                   the grouping rule of the current locale.  */
5431
#   if WIDE_CHAR_VERSION
5432
                                                /* DCHAR_T is wchar_t.  */
5433
                                                thousep = thousands_separator_wchar (thousep_buf);
5434
#                                               define thousep_len 1
5435
#   elif defined DCHAR_CONV_FROM_ENCODING
5436
                                                /* DCHAR_T is uintN_t.  */
5437
                                                thousep = thousands_separator_DCHAR (thousep_buf);
5438
                                                thousep_len = DCHAR_STRLEN (thousep);
5439
#   else
5440
                                                /* DCHAR_T is char.  */
5441
                                                thousep = thousands_separator_char (thousep_buf);
5442
                                                thousep_len = strlen (thousep);
5443
#   endif
5444
                                                if (*thousep == 0)
5445
                                                  thousep = NULL;
5446
                                                if (thousep != NULL)
5447
                                                  {
5448
                                                    grouping = grouping_rule ();
5449
                                                    insert =
5450
                                                      num_thousands_separators (grouping, intpart_digits);
5451
                                                  }
5452
                                              }
5453
5454
                                            const char *digitp = digits + ndigits - intpart_digits;
5455
                                            DCHAR_T *p_before_intpart = p;
5456
                                            p += intpart_digits + insert * thousep_len;
5457
                                            DCHAR_T *p_after_intpart = p;
5458
                                            if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
5459
                                              {
5460
                                                const signed char *g = grouping;
5461
                                                for (;;)
5462
                                                  {
5463
                                                    int h = *g;
5464
                                                    if (h <= 0)
5465
                                                      abort ();
5466
                                                    int i = h;
5467
                                                    do
5468
                                                      *--p = *digitp++;
5469
                                                    while (--i > 0);
5470
#   if WIDE_CHAR_VERSION
5471
                                                    *--p = thousep[0];
5472
#   else
5473
                                                    p -= thousep_len;
5474
                                                    DCHAR_CPY (p, thousep, thousep_len);
5475
#   endif
5476
                                                    insert--;
5477
                                                    if (insert == 0)
5478
                                                      break;
5479
                                                    if (g[1] != 0)
5480
                                                      g++;
5481
                                                  }
5482
                                              }
5483
                                            for (;;)
5484
                                              {
5485
                                                *--p = *digitp++;
5486
                                                if (p == p_before_intpart)
5487
                                                  break;
5488
                                              }
5489
                                            p = p_after_intpart;
5490
                                            ndigits -= intpart_digits;
5491
#   undef thousep_len
5492
5493
                                            if ((flags & FLAG_ALT) || ndigits > nzeroes)
5494
                                              {
5495
                                                *p++ = decimal_point_char ();
5496
                                                while (ndigits > nzeroes)
5497
                                                  {
5498
                                                    --ndigits;
5499
                                                    *p++ = digits[ndigits];
5500
                                                  }
5501
                                              }
5502
                                          }
5503
                                        else
5504
                                          {
5505
                                            size_t ecount = -exponent - 1;
5506
                                            *p++ = '0';
5507
                                            *p++ = decimal_point_char ();
5508
                                            for (; ecount > 0; ecount--)
5509
                                              *p++ = '0';
5510
                                            while (ndigits > nzeroes)
5511
                                              {
5512
                                                --ndigits;
5513
                                                *p++ = digits[ndigits];
5514
                                              }
5515
                                          }
5516
                                      }
5517
                                    else
5518
                                      {
5519
                                        /* Exponential notation.  */
5520
                                        *p++ = digits[--ndigits];
5521
                                        if ((flags & FLAG_ALT) || ndigits > nzeroes)
5522
                                          {
5523
                                            *p++ = decimal_point_char ();
5524
                                            while (ndigits > nzeroes)
5525
                                              {
5526
                                                --ndigits;
5527
                                                *p++ = digits[ndigits];
5528
                                              }
5529
                                          }
5530
                                        *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
5531
#   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
5532
                                        {
5533
                                          static const wchar_t decimal_format[] =
5534
                                            { '%', '+', '.', '2', 'd', '\0' };
5535
                                          SNPRINTF (p, 6 + 1, decimal_format, exponent);
5536
                                        }
5537
                                        while (*p != '\0')
5538
                                          p++;
5539
#   else
5540
                                        if (sizeof (DCHAR_T) == 1)
5541
                                          {
5542
                                            sprintf ((char *) p, "%+.2d", exponent);
5543
                                            while (*p != '\0')
5544
                                              p++;
5545
                                          }
5546
                                        else
5547
                                          {
5548
                                            char expbuf[6 + 1];
5549
                                            sprintf (expbuf, "%+.2d", exponent);
5550
                                            for (const char *ep = expbuf; (*p = *ep) != '\0'; ep++)
5551
                                              p++;
5552
                                          }
5553
#   endif
5554
                                      }
5555
5556
                                    free (digits);
5557
                                  }
5558
                              }
5559
                            else
5560
                              abort ();
5561
#  else
5562
                            /* arg is finite.  */
5563
                            if (!(arg == 0.0L))
5564
                              abort ();
5565
5566
                            pad_ptr = p;
5567
5568
                            if (dp->conversion == 'f' || dp->conversion == 'F')
5569
                              {
5570
                                *p++ = '0';
5571
                                if ((flags & FLAG_ALT) || precision > 0)
5572
                                  {
5573
                                    *p++ = decimal_point_char ();
5574
                                    for (; precision > 0; precision--)
5575
                                      *p++ = '0';
5576
                                  }
5577
                              }
5578
                            else if (dp->conversion == 'e' || dp->conversion == 'E')
5579
                              {
5580
                                *p++ = '0';
5581
                                if ((flags & FLAG_ALT) || precision > 0)
5582
                                  {
5583
                                    *p++ = decimal_point_char ();
5584
                                    for (; precision > 0; precision--)
5585
                                      *p++ = '0';
5586
                                  }
5587
                                *p++ = dp->conversion; /* 'e' or 'E' */
5588
                                *p++ = '+';
5589
                                *p++ = '0';
5590
                                *p++ = '0';
5591
                              }
5592
                            else if (dp->conversion == 'g' || dp->conversion == 'G')
5593
                              {
5594
                                *p++ = '0';
5595
                                if (flags & FLAG_ALT)
5596
                                  {
5597
                                    size_t ndigits =
5598
                                      (precision > 0 ? precision - 1 : 0);
5599
                                    *p++ = decimal_point_char ();
5600
                                    for (; ndigits > 0; --ndigits)
5601
                                      *p++ = '0';
5602
                                  }
5603
                              }
5604
                            else if (dp->conversion == 'a' || dp->conversion == 'A')
5605
                              {
5606
                                *p++ = '0';
5607
                                *p++ = dp->conversion - 'A' + 'X';
5608
                                pad_ptr = p;
5609
                                *p++ = '0';
5610
                                if ((flags & FLAG_ALT) || precision > 0)
5611
                                  {
5612
                                    *p++ = decimal_point_char ();
5613
                                    for (; precision > 0; precision--)
5614
                                      *p++ = '0';
5615
                                  }
5616
                                *p++ = dp->conversion - 'A' + 'P';
5617
                                *p++ = '+';
5618
                                *p++ = '0';
5619
                              }
5620
                            else
5621
                              abort ();
5622
#  endif
5623
                          }
5624
5625
                        END_LONG_DOUBLE_ROUNDING ();
5626
                      }
5627
                  }
5628
#  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
5629
                else
5630
#  endif
5631
# endif
5632
# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
5633
                  {
5634
                    double arg = a.arg[dp->arg_index].a.a_double;
5635
5636
                    if (isnand (arg))
5637
                      {
5638
                        if (dp->conversion >= 'A' && dp->conversion <= 'Z')
5639
                          {
5640
                            *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
5641
                          }
5642
                        else
5643
                          {
5644
                            *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
5645
                          }
5646
                      }
5647
                    else
5648
                      {
5649
                        int sign = 0;
5650
                        if (signbit (arg)) /* arg < 0.0 or negative zero */
5651
                          {
5652
                            sign = -1;
5653
                            arg = -arg;
5654
                          }
5655
5656
                        if (sign < 0)
5657
                          *p++ = '-';
5658
                        else if (flags & FLAG_SHOWSIGN)
5659
                          *p++ = '+';
5660
                        else if (flags & FLAG_SPACE)
5661
                          *p++ = ' ';
5662
5663
                        if (arg > 0.0 && arg + arg == arg)
5664
                          {
5665
                            if (dp->conversion >= 'A' && dp->conversion <= 'Z')
5666
                              {
5667
                                *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
5668
                              }
5669
                            else
5670
                              {
5671
                                *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
5672
                              }
5673
                          }
5674
                        else
5675
                          {
5676
#  if NEED_PRINTF_DOUBLE
5677
                            pad_ptr = p;
5678
5679
                            if (dp->conversion == 'f' || dp->conversion == 'F')
5680
                              {
5681
                                char *digits =
5682
                                  scale10_round_decimal_double (arg, precision);
5683
                                if (digits == NULL)
5684
                                  goto out_of_memory;
5685
                                size_t ndigits = strlen (digits);
5686
5687
                                if (ndigits > precision)
5688
                                  {
5689
                                    /* Number of digits before the decimal point.  */
5690
                                    size_t intpart_digits = ndigits - precision;
5691
5692
                                    const DCHAR_T *thousep = NULL;
5693
                                    DCHAR_T thousep_buf[10];
5694
#   if !WIDE_CHAR_VERSION
5695
                                    size_t thousep_len = 0;
5696
#   endif
5697
                                    const signed char *grouping;
5698
                                    size_t insert = 0;
5699
5700
                                    if ((flags & FLAG_GROUP) && (intpart_digits > 1))
5701
                                      {
5702
                                        /* Determine the thousands separator and
5703
                                           the grouping rule of the current locale.  */
5704
#   if WIDE_CHAR_VERSION
5705
                                        /* DCHAR_T is wchar_t.  */
5706
                                        thousep = thousands_separator_wchar (thousep_buf);
5707
#                                       define thousep_len 1
5708
#   elif defined DCHAR_CONV_FROM_ENCODING
5709
                                        /* DCHAR_T is uintN_t.  */
5710
                                        thousep = thousands_separator_DCHAR (thousep_buf);
5711
                                        thousep_len = DCHAR_STRLEN (thousep);
5712
#   else
5713
                                        /* DCHAR_T is char.  */
5714
                                        thousep = thousands_separator_char (thousep_buf);
5715
                                        thousep_len = strlen (thousep);
5716
#   endif
5717
                                        if (*thousep == 0)
5718
                                          thousep = NULL;
5719
                                        if (thousep != NULL)
5720
                                          {
5721
                                            grouping = grouping_rule ();
5722
                                            insert =
5723
                                              num_thousands_separators (grouping, intpart_digits);
5724
                                          }
5725
                                      }
5726
5727
                                    const char *digitp = digits + precision;
5728
                                    DCHAR_T *p_before_intpart = p;
5729
                                    p += intpart_digits + insert * thousep_len;
5730
                                    DCHAR_T *p_after_intpart = p;
5731
                                    if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
5732
                                      {
5733
                                        const signed char *g = grouping;
5734
                                        for (;;)
5735
                                          {
5736
                                            int h = *g;
5737
                                            if (h <= 0)
5738
                                              abort ();
5739
                                            int i = h;
5740
                                            do
5741
                                              *--p = *digitp++;
5742
                                            while (--i > 0);
5743
#   if WIDE_CHAR_VERSION
5744
                                            *--p = thousep[0];
5745
#   else
5746
                                            p -= thousep_len;
5747
                                            DCHAR_CPY (p, thousep, thousep_len);
5748
#   endif
5749
                                            insert--;
5750
                                            if (insert == 0)
5751
                                              break;
5752
                                            if (g[1] != 0)
5753
                                              g++;
5754
                                          }
5755
                                      }
5756
                                    for (;;)
5757
                                      {
5758
                                        *--p = *digitp++;
5759
                                        if (p == p_before_intpart)
5760
                                          break;
5761
                                      }
5762
                                    p = p_after_intpart;
5763
                                    ndigits = precision;
5764
#   undef thousep_len
5765
                                  }
5766
                                else
5767
                                  *p++ = '0';
5768
                                /* Here ndigits <= precision.  */
5769
                                if ((flags & FLAG_ALT) || precision > 0)
5770
                                  {
5771
                                    *p++ = decimal_point_char ();
5772
                                    for (; precision > ndigits; precision--)
5773
                                      *p++ = '0';
5774
                                    while (ndigits > 0)
5775
                                      {
5776
                                        --ndigits;
5777
                                        *p++ = digits[ndigits];
5778
                                      }
5779
                                  }
5780
5781
                                free (digits);
5782
                              }
5783
                            else if (dp->conversion == 'e' || dp->conversion == 'E')
5784
                              {
5785
                                int exponent;
5786
5787
                                if (arg == 0.0)
5788
                                  {
5789
                                    exponent = 0;
5790
                                    *p++ = '0';
5791
                                    if ((flags & FLAG_ALT) || precision > 0)
5792
                                      {
5793
                                        *p++ = decimal_point_char ();
5794
                                        for (; precision > 0; precision--)
5795
                                          *p++ = '0';
5796
                                      }
5797
                                  }
5798
                                else
5799
                                  {
5800
                                    /* arg > 0.0.  */
5801
                                    exponent = floorlog10 (arg);
5802
                                    int adjusted = 0;
5803
                                    char *digits;
5804
                                    size_t ndigits;
5805
                                    for (;;)
5806
                                      {
5807
                                        digits =
5808
                                          scale10_round_decimal_double (arg,
5809
                                                                        (int)precision - exponent);
5810
                                        if (digits == NULL)
5811
                                          goto out_of_memory;
5812
                                        ndigits = strlen (digits);
5813
5814
                                        if (ndigits == precision + 1)
5815
                                          break;
5816
                                        if (ndigits < precision
5817
                                            || ndigits > precision + 2)
5818
                                          /* The exponent was not guessed
5819
                                             precisely enough.  */
5820
                                          abort ();
5821
                                        if (adjusted)
5822
                                          /* None of two values of exponent is
5823
                                             the right one.  Prevent an endless
5824
                                             loop.  */
5825
                                          abort ();
5826
                                        free (digits);
5827
                                        if (ndigits == precision)
5828
                                          exponent -= 1;
5829
                                        else
5830
                                          exponent += 1;
5831
                                        adjusted = 1;
5832
                                      }
5833
                                    /* Here ndigits = precision+1.  */
5834
                                    if (is_borderline (digits, precision))
5835
                                      {
5836
                                        /* Maybe the exponent guess was too high
5837
                                           and a smaller exponent can be reached
5838
                                           by turning a 10...0 into 9...9x.  */
5839
                                        char *digits2 =
5840
                                          scale10_round_decimal_double (arg,
5841
                                                                        (int)precision - exponent + 1);
5842
                                        if (digits2 == NULL)
5843
                                          {
5844
                                            free (digits);
5845
                                            goto out_of_memory;
5846
                                          }
5847
                                        if (strlen (digits2) == precision + 1)
5848
                                          {
5849
                                            free (digits);
5850
                                            digits = digits2;
5851
                                            exponent -= 1;
5852
                                          }
5853
                                        else
5854
                                          free (digits2);
5855
                                      }
5856
                                    /* Here ndigits = precision+1.  */
5857
5858
                                    *p++ = digits[--ndigits];
5859
                                    if ((flags & FLAG_ALT) || precision > 0)
5860
                                      {
5861
                                        *p++ = decimal_point_char ();
5862
                                        while (ndigits > 0)
5863
                                          {
5864
                                            --ndigits;
5865
                                            *p++ = digits[ndigits];
5866
                                          }
5867
                                      }
5868
5869
                                    free (digits);
5870
                                  }
5871
5872
                                *p++ = dp->conversion; /* 'e' or 'E' */
5873
#   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
5874
                                {
5875
                                  static const wchar_t decimal_format[] =
5876
                                    /* Produce the same number of exponent digits
5877
                                       as the native printf implementation.  */
5878
#    if defined _WIN32 && ! defined __CYGWIN__
5879
                                    { '%', '+', '.', '3', 'd', '\0' };
5880
#    else
5881
                                    { '%', '+', '.', '2', 'd', '\0' };
5882
#    endif
5883
                                  SNPRINTF (p, 6 + 1, decimal_format, exponent);
5884
                                }
5885
                                while (*p != '\0')
5886
                                  p++;
5887
#   else
5888
                                {
5889
                                  static const char decimal_format[] =
5890
                                    /* Produce the same number of exponent digits
5891
                                       as the native printf implementation.  */
5892
#    if defined _WIN32 && ! defined __CYGWIN__
5893
                                    "%+.3d";
5894
#    else
5895
                                    "%+.2d";
5896
#    endif
5897
                                  if (sizeof (DCHAR_T) == 1)
5898
                                    {
5899
                                      sprintf ((char *) p, decimal_format, exponent);
5900
                                      while (*p != '\0')
5901
                                        p++;
5902
                                    }
5903
                                  else
5904
                                    {
5905
                                      char expbuf[6 + 1];
5906
                                      sprintf (expbuf, decimal_format, exponent);
5907
                                      for (const char *ep = expbuf; (*p = *ep) != '\0'; ep++)
5908
                                        p++;
5909
                                    }
5910
                                }
5911
#   endif
5912
                              }
5913
                            else if (dp->conversion == 'g' || dp->conversion == 'G')
5914
                              {
5915
                                if (precision == 0)
5916
                                  precision = 1;
5917
                                /* precision >= 1.  */
5918
5919
                                if (arg == 0.0)
5920
                                  /* The exponent is 0, >= -4, < precision.
5921
                                     Use fixed-point notation.  */
5922
                                  {
5923
                                    size_t ndigits = precision;
5924
                                    /* Number of trailing zeroes that have to be
5925
                                       dropped.  */
5926
                                    size_t nzeroes =
5927
                                      (flags & FLAG_ALT ? 0 : precision - 1);
5928
5929
                                    --ndigits;
5930
                                    *p++ = '0';
5931
                                    if ((flags & FLAG_ALT) || ndigits > nzeroes)
5932
                                      {
5933
                                        *p++ = decimal_point_char ();
5934
                                        while (ndigits > nzeroes)
5935
                                          {
5936
                                            --ndigits;
5937
                                            *p++ = '0';
5938
                                          }
5939
                                      }
5940
                                  }
5941
                                else
5942
                                  {
5943
                                    /* arg > 0.0.  */
5944
                                    int exponent = floorlog10 (arg);
5945
                                    int adjusted = 0;
5946
                                    char *digits;
5947
                                    size_t ndigits;
5948
                                    for (;;)
5949
                                      {
5950
                                        digits =
5951
                                          scale10_round_decimal_double (arg,
5952
                                                                        (int)(precision - 1) - exponent);
5953
                                        if (digits == NULL)
5954
                                          goto out_of_memory;
5955
                                        ndigits = strlen (digits);
5956
5957
                                        if (ndigits == precision)
5958
                                          break;
5959
                                        if (ndigits < precision - 1
5960
                                            || ndigits > precision + 1)
5961
                                          /* The exponent was not guessed
5962
                                             precisely enough.  */
5963
                                          abort ();
5964
                                        if (adjusted)
5965
                                          /* None of two values of exponent is
5966
                                             the right one.  Prevent an endless
5967
                                             loop.  */
5968
                                          abort ();
5969
                                        free (digits);
5970
                                        if (ndigits < precision)
5971
                                          exponent -= 1;
5972
                                        else
5973
                                          exponent += 1;
5974
                                        adjusted = 1;
5975
                                      }
5976
                                    /* Here ndigits = precision.  */
5977
                                    if (is_borderline (digits, precision - 1))
5978
                                      {
5979
                                        /* Maybe the exponent guess was too high
5980
                                           and a smaller exponent can be reached
5981
                                           by turning a 10...0 into 9...9x.  */
5982
                                        char *digits2 =
5983
                                          scale10_round_decimal_double (arg,
5984
                                                                        (int)(precision - 1) - exponent + 1);
5985
                                        if (digits2 == NULL)
5986
                                          {
5987
                                            free (digits);
5988
                                            goto out_of_memory;
5989
                                          }
5990
                                        if (strlen (digits2) == precision)
5991
                                          {
5992
                                            free (digits);
5993
                                            digits = digits2;
5994
                                            exponent -= 1;
5995
                                          }
5996
                                        else
5997
                                          free (digits2);
5998
                                      }
5999
                                    /* Here ndigits = precision.  */
6000
6001
                                    /* Determine the number of trailing zeroes
6002
                                       that have to be dropped.  */
6003
                                    size_t nzeroes = 0;
6004
                                    if ((flags & FLAG_ALT) == 0)
6005
                                      while (nzeroes < ndigits
6006
                                             && digits[nzeroes] == '0')
6007
                                        nzeroes++;
6008
6009
                                    /* The exponent is now determined.  */
6010
                                    if (exponent >= -4
6011
                                        && exponent < (long)precision)
6012
                                      {
6013
                                        /* Fixed-point notation:
6014
                                           max(exponent,0)+1 digits, then the
6015
                                           decimal point, then the remaining
6016
                                           digits without trailing zeroes.  */
6017
                                        if (exponent >= 0)
6018
                                          {
6019
                                            /* Number of digits before the decimal point.  */
6020
                                            size_t intpart_digits = exponent + 1;
6021
                                            /* Note: intpart_digits <= precision = ndigits.  */
6022
6023
                                            const DCHAR_T *thousep = NULL;
6024
                                            DCHAR_T thousep_buf[10];
6025
#   if !WIDE_CHAR_VERSION
6026
                                            size_t thousep_len = 0;
6027
#   endif
6028
                                            const signed char *grouping;
6029
                                            size_t insert = 0;
6030
6031
                                            if ((flags & FLAG_GROUP) && (intpart_digits > 1))
6032
                                              {
6033
                                                /* Determine the thousands separator and
6034
                                                   the grouping rule of the current locale.  */
6035
#   if WIDE_CHAR_VERSION
6036
                                                /* DCHAR_T is wchar_t.  */
6037
                                                thousep = thousands_separator_wchar (thousep_buf);
6038
#                                               define thousep_len 1
6039
#   elif defined DCHAR_CONV_FROM_ENCODING
6040
                                                /* DCHAR_T is uintN_t.  */
6041
                                                thousep = thousands_separator_DCHAR (thousep_buf);
6042
                                                thousep_len = DCHAR_STRLEN (thousep);
6043
#   else
6044
                                                /* DCHAR_T is char.  */
6045
                                                thousep = thousands_separator_char (thousep_buf);
6046
                                                thousep_len = strlen (thousep);
6047
#   endif
6048
                                                if (*thousep == 0)
6049
                                                  thousep = NULL;
6050
                                                if (thousep != NULL)
6051
                                                  {
6052
                                                    grouping = grouping_rule ();
6053
                                                    insert =
6054
                                                      num_thousands_separators (grouping, intpart_digits);
6055
                                                  }
6056
                                              }
6057
6058
                                            const char *digitp = digits + ndigits - intpart_digits;
6059
                                            DCHAR_T *p_before_intpart = p;
6060
                                            p += intpart_digits + insert * thousep_len;
6061
                                            DCHAR_T *p_after_intpart = p;
6062
                                            if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
6063
                                              {
6064
                                                const signed char *g = grouping;
6065
                                                for (;;)
6066
                                                  {
6067
                                                    int h = *g;
6068
                                                    if (h <= 0)
6069
                                                      abort ();
6070
                                                    int i = h;
6071
                                                    do
6072
                                                      *--p = *digitp++;
6073
                                                    while (--i > 0);
6074
#   if WIDE_CHAR_VERSION
6075
                                                    *--p = thousep[0];
6076
#   else
6077
                                                    p -= thousep_len;
6078
                                                    DCHAR_CPY (p, thousep, thousep_len);
6079
#   endif
6080
                                                    insert--;
6081
                                                    if (insert == 0)
6082
                                                      break;
6083
                                                    if (g[1] != 0)
6084
                                                      g++;
6085
                                                  }
6086
                                              }
6087
                                            for (;;)
6088
                                              {
6089
                                                *--p = *digitp++;
6090
                                                if (p == p_before_intpart)
6091
                                                  break;
6092
                                              }
6093
                                            p = p_after_intpart;
6094
                                            ndigits -= intpart_digits;
6095
#   undef thousep_len
6096
6097
                                            if ((flags & FLAG_ALT) || ndigits > nzeroes)
6098
                                              {
6099
                                                *p++ = decimal_point_char ();
6100
                                                while (ndigits > nzeroes)
6101
                                                  {
6102
                                                    --ndigits;
6103
                                                    *p++ = digits[ndigits];
6104
                                                  }
6105
                                              }
6106
                                          }
6107
                                        else
6108
                                          {
6109
                                            size_t ecount = -exponent - 1;
6110
                                            *p++ = '0';
6111
                                            *p++ = decimal_point_char ();
6112
                                            for (; ecount > 0; ecount--)
6113
                                              *p++ = '0';
6114
                                            while (ndigits > nzeroes)
6115
                                              {
6116
                                                --ndigits;
6117
                                                *p++ = digits[ndigits];
6118
                                              }
6119
                                          }
6120
                                      }
6121
                                    else
6122
                                      {
6123
                                        /* Exponential notation.  */
6124
                                        *p++ = digits[--ndigits];
6125
                                        if ((flags & FLAG_ALT) || ndigits > nzeroes)
6126
                                          {
6127
                                            *p++ = decimal_point_char ();
6128
                                            while (ndigits > nzeroes)
6129
                                              {
6130
                                                --ndigits;
6131
                                                *p++ = digits[ndigits];
6132
                                              }
6133
                                          }
6134
                                        *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
6135
#   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
6136
                                        {
6137
                                          static const wchar_t decimal_format[] =
6138
                                            /* Produce the same number of exponent digits
6139
                                               as the native printf implementation.  */
6140
#    if defined _WIN32 && ! defined __CYGWIN__
6141
                                            { '%', '+', '.', '3', 'd', '\0' };
6142
#    else
6143
                                            { '%', '+', '.', '2', 'd', '\0' };
6144
#    endif
6145
                                          SNPRINTF (p, 6 + 1, decimal_format, exponent);
6146
                                        }
6147
                                        while (*p != '\0')
6148
                                          p++;
6149
#   else
6150
                                        {
6151
                                          static const char decimal_format[] =
6152
                                            /* Produce the same number of exponent digits
6153
                                               as the native printf implementation.  */
6154
#    if defined _WIN32 && ! defined __CYGWIN__
6155
                                            "%+.3d";
6156
#    else
6157
                                            "%+.2d";
6158
#    endif
6159
                                          if (sizeof (DCHAR_T) == 1)
6160
                                            {
6161
                                              sprintf ((char *) p, decimal_format, exponent);
6162
                                              while (*p != '\0')
6163
                                                p++;
6164
                                            }
6165
                                          else
6166
                                            {
6167
                                              char expbuf[6 + 1];
6168
                                              sprintf (expbuf, decimal_format, exponent);
6169
                                              for (const char *ep = expbuf; (*p = *ep) != '\0'; ep++)
6170
                                                p++;
6171
                                            }
6172
                                        }
6173
#   endif
6174
                                      }
6175
6176
                                    free (digits);
6177
                                  }
6178
                              }
6179
                            else
6180
                              abort ();
6181
#  else
6182
                            /* arg is finite.  */
6183
                            if (!(arg == 0.0))
6184
                              abort ();
6185
6186
                            pad_ptr = p;
6187
6188
                            if (dp->conversion == 'f' || dp->conversion == 'F')
6189
                              {
6190
                                *p++ = '0';
6191
                                if ((flags & FLAG_ALT) || precision > 0)
6192
                                  {
6193
                                    *p++ = decimal_point_char ();
6194
                                    for (; precision > 0; precision--)
6195
                                      *p++ = '0';
6196
                                  }
6197
                              }
6198
                            else if (dp->conversion == 'e' || dp->conversion == 'E')
6199
                              {
6200
                                *p++ = '0';
6201
                                if ((flags & FLAG_ALT) || precision > 0)
6202
                                  {
6203
                                    *p++ = decimal_point_char ();
6204
                                    for (; precision > 0; precision--)
6205
                                      *p++ = '0';
6206
                                  }
6207
                                *p++ = dp->conversion; /* 'e' or 'E' */
6208
                                *p++ = '+';
6209
                                /* Produce the same number of exponent digits as
6210
                                   the native printf implementation.  */
6211
#   if defined _WIN32 && ! defined __CYGWIN__
6212
                                *p++ = '0';
6213
#   endif
6214
                                *p++ = '0';
6215
                                *p++ = '0';
6216
                              }
6217
                            else if (dp->conversion == 'g' || dp->conversion == 'G')
6218
                              {
6219
                                *p++ = '0';
6220
                                if (flags & FLAG_ALT)
6221
                                  {
6222
                                    size_t ndigits =
6223
                                      (precision > 0 ? precision - 1 : 0);
6224
                                    *p++ = decimal_point_char ();
6225
                                    for (; ndigits > 0; --ndigits)
6226
                                      *p++ = '0';
6227
                                  }
6228
                              }
6229
                            else
6230
                              abort ();
6231
#  endif
6232
                          }
6233
                      }
6234
                  }
6235
# endif
6236
6237
                /* The generated string now extends from tmp to p, with the
6238
                   zero padding insertion point being at pad_ptr.  */
6239
                size_t count = p - tmp;
6240
6241
                if (count < width)
6242
                  {
6243
                    size_t pad = width - count;
6244
                    DCHAR_T *end = p + pad;
6245
6246
                    if (flags & FLAG_LEFT)
6247
                      {
6248
                        /* Pad with spaces on the right.  */
6249
                        for (; pad > 0; pad--)
6250
                          *p++ = ' ';
6251
                      }
6252
                    else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
6253
                      {
6254
                        /* Pad with zeroes.  */
6255
                        DCHAR_T *q = end;
6256
6257
                        while (p > pad_ptr)
6258
                          *--q = *--p;
6259
                        for (; pad > 0; pad--)
6260
                          *p++ = '0';
6261
                      }
6262
                    else
6263
                      {
6264
                        /* Pad with spaces on the left.  */
6265
                        DCHAR_T *q = end;
6266
6267
                        while (p > tmp)
6268
                          *--q = *--p;
6269
                        for (; pad > 0; pad--)
6270
                          *p++ = ' ';
6271
                      }
6272
6273
                    p = end;
6274
                  }
6275
6276
                count = p - tmp;
6277
6278
                if (count >= tmp_length)
6279
                  /* tmp_length was incorrectly calculated - fix the
6280
                     code above!  */
6281
                  abort ();
6282
6283
                /* Make room for the result.  */
6284
                if (count >= allocated - length)
6285
                  {
6286
                    size_t n = xsum (length, count);
6287
6288
                    ENSURE_ALLOCATION_ELSE (n,
6289
                      { if (tmp != tmpbuf) free (tmp); goto out_of_memory; });
6290
                  }
6291
6292
                /* Append the result.  */
6293
                memcpy (result + length, tmp, count * sizeof (DCHAR_T));
6294
                if (tmp != tmpbuf)
6295
                  free (tmp);
6296
                length += count;
6297
              }
6298
#endif
6299
0
            else
6300
0
              {
6301
0
                arg_type type = a.arg[dp->arg_index].type;
6302
0
                int flags = dp->flags;
6303
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
6304
                int prec_ourselves;
6305
#else
6306
0
#               define prec_ourselves 0
6307
0
#endif
6308
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6309
                int group_ourselves;
6310
#else
6311
0
#               define group_ourselves 0
6312
0
#endif
6313
#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST
6314
#               define pad_ourselves 1
6315
#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6316
                int pad_ourselves;
6317
#else
6318
0
#               define pad_ourselves 0
6319
0
#endif
6320
0
                TCHAR_T *fbp;
6321
0
                unsigned int prefix_count;
6322
0
                int prefixes[2] IF_LINT (= { 0 });
6323
0
                int orig_errno;
6324
#if !USE_SNPRINTF
6325
                size_t tmp_length;
6326
                TCHAR_T tmpbuf[700];
6327
                TCHAR_T *tmp;
6328
#endif
6329
6330
#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6331
                int has_width = 0;
6332
#endif
6333
#if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6334
                size_t width = 0;
6335
                if (dp->width_start != dp->width_end)
6336
                  {
6337
                    if (dp->width_arg_index != ARG_NONE)
6338
                      {
6339
                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
6340
                          abort ();
6341
                        int arg = a.arg[dp->width_arg_index].a.a_int;
6342
                        width = arg;
6343
                        if (arg < 0)
6344
                          {
6345
                            /* "A negative field width is taken as a '-' flag
6346
                                followed by a positive field width."  */
6347
                            flags |= FLAG_LEFT;
6348
                            width = -width;
6349
                          }
6350
                      }
6351
                    else
6352
                      {
6353
                        const FCHAR_T *digitp = dp->width_start;
6354
6355
                        do
6356
                          width = xsum (xtimes (width, 10), *digitp++ - '0');
6357
                        while (digitp != dp->width_end);
6358
                      }
6359
                    if (width > (size_t) INT_MAX)
6360
                      goto overflow;
6361
# define WIDTH_IS_CHECKED 1
6362
# if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6363
                    has_width = 1;
6364
# endif
6365
                  }
6366
#endif
6367
6368
#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6369
                int has_precision = 0;
6370
                size_t precision = 6;
6371
                if (dp->precision_start != dp->precision_end)
6372
                  {
6373
                    if (dp->precision_arg_index != ARG_NONE)
6374
                      {
6375
                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
6376
                          abort ();
6377
                        int arg = a.arg[dp->precision_arg_index].a.a_int;
6378
                        /* "A negative precision is taken as if the precision
6379
                            were omitted."  */
6380
                        if (arg >= 0)
6381
                          {
6382
                            precision = arg;
6383
                            has_precision = 1;
6384
                          }
6385
                      }
6386
                    else
6387
                      {
6388
                        const FCHAR_T *digitp = dp->precision_start + 1;
6389
6390
                        precision = 0;
6391
                        while (digitp != dp->precision_end)
6392
                          precision = xsum (xtimes (precision, 10), *digitp++ - '0');
6393
                        has_precision = 1;
6394
                      }
6395
                  }
6396
#endif
6397
6398
                /* Decide whether to handle the precision ourselves.  */
6399
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
6400
                switch (dp->conversion)
6401
                  {
6402
# if NEED_PRINTF_UNBOUNDED_PRECISION
6403
                  case 'd': case 'i': case 'u':
6404
                  case 'b':
6405
                  #if SUPPORT_GNU_PRINTF_DIRECTIVES \
6406
                      || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
6407
                  case 'B':
6408
                  #endif
6409
                  case 'o':
6410
                    prec_ourselves = has_precision && (precision > 0);
6411
                    break;
6412
# endif
6413
                  case 'x': case 'X': case 'p':
6414
                    prec_ourselves =
6415
                      has_precision
6416
                      && (0
6417
# if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
6418
                          || (precision == 0)
6419
# endif
6420
# if NEED_PRINTF_UNBOUNDED_PRECISION
6421
                          || (precision > 0)
6422
# endif
6423
                         );
6424
                    break;
6425
                  default:
6426
                    prec_ourselves = 0;
6427
                    break;
6428
                  }
6429
#endif
6430
6431
                /* Decide whether to add the thousands separators ourselves.  */
6432
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6433
                if (flags & FLAG_GROUP)
6434
                  {
6435
                    switch (dp->conversion)
6436
                      {
6437
                      case 'd': case 'i': case 'u':
6438
# if NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
6439
                        group_ourselves = 1;
6440
# else
6441
                        group_ourselves = prec_ourselves;
6442
# endif
6443
                        break;
6444
                      case 'f': case 'F': case 'g': case 'G':
6445
# if NEED_PRINTF_FLAG_GROUPING
6446
                        group_ourselves = 1;
6447
# else
6448
                        group_ourselves = prec_ourselves;
6449
# endif
6450
                        break;
6451
                      default:
6452
                        group_ourselves = 0;
6453
                        break;
6454
                      }
6455
                  }
6456
                else
6457
                  group_ourselves = 0;
6458
#endif
6459
6460
                /* Decide whether to perform the padding ourselves.  */
6461
#if !((WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST) && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
6462
                switch (dp->conversion)
6463
                  {
6464
# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO
6465
#  if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
6466
                  /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
6467
                     to perform the padding after this conversion.  Functions
6468
                     with unistdio extensions perform the padding based on
6469
                     character count rather than element count.  */
6470
                  case 'c': case 's':
6471
#  endif
6472
#  if NEED_PRINTF_FLAG_ZERO
6473
                  case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
6474
                  case 'a': case 'A':
6475
#  endif
6476
                    pad_ourselves = 1;
6477
                    break;
6478
# endif
6479
                  default:
6480
                    pad_ourselves = prec_ourselves | group_ourselves;
6481
                    break;
6482
                  }
6483
#endif
6484
6485
#if !USE_SNPRINTF
6486
                /* Allocate a temporary buffer of sufficient size for calling
6487
                   sprintf.  */
6488
                tmp_length =
6489
                  MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
6490
                                   flags, width, has_precision, precision,
6491
                                   pad_ourselves);
6492
6493
                if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
6494
                  tmp = tmpbuf;
6495
                else
6496
                  {
6497
                    size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
6498
6499
                    if (size_overflow_p (tmp_memsize))
6500
                      /* Overflow, would lead to out of memory.  */
6501
                      goto out_of_memory;
6502
                    tmp = (TCHAR_T *) malloc (tmp_memsize);
6503
                    if (tmp == NULL)
6504
                      /* Out of memory.  */
6505
                      goto out_of_memory;
6506
                  }
6507
#endif
6508
6509
                /* Construct the format string for calling snprintf or
6510
                   sprintf.  */
6511
0
                fbp = buf;
6512
0
                *fbp++ = '%';
6513
0
                if ((flags & FLAG_GROUP) && !group_ourselves)
6514
0
                  *fbp++ = '\'';
6515
0
                if (flags & FLAG_LEFT)
6516
0
                  *fbp++ = '-';
6517
0
                if (flags & FLAG_SHOWSIGN)
6518
0
                  *fbp++ = '+';
6519
0
                if (flags & FLAG_SPACE)
6520
0
                  *fbp++ = ' ';
6521
0
                if (flags & FLAG_ALT)
6522
0
                  *fbp++ = '#';
6523
0
#if __GLIBC__ >= 2 && !defined __UCLIBC__
6524
0
                if (flags & FLAG_LOCALIZED)
6525
0
                  *fbp++ = 'I';
6526
0
#endif
6527
0
                if (!pad_ourselves)
6528
0
                  {
6529
0
                    if (flags & FLAG_ZERO)
6530
0
                      *fbp++ = '0';
6531
0
                    if (dp->width_start != dp->width_end)
6532
0
                      {
6533
0
                        size_t n = dp->width_end - dp->width_start;
6534
0
#if !WIDTH_IS_CHECKED
6535
0
                        size_t width;
6536
                        /* Reject an out-of-range width.
6537
                           The underlying SNPRINTF already does this on some
6538
                           platforms (glibc, musl, macOS, FreeBSD, NetBSD,
6539
                           OpenBSD, Cygwin, Solaris, MSVC).  However, on others
6540
                           (AIX, mingw), it doesn't; thus this vasnprintf
6541
                           invocation would succeed and produce a wrong result.
6542
                           So, this is redundant on some platforms, but it's a
6543
                           quick check anyway.  */
6544
0
                        if (dp->width_arg_index != ARG_NONE)
6545
0
                          {
6546
0
                            if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
6547
0
                              abort ();
6548
0
                            int arg = a.arg[dp->width_arg_index].a.a_int;
6549
0
                            width = arg;
6550
0
                            if (arg < 0)
6551
0
                              {
6552
                                /* "A negative field width is taken as a '-' flag
6553
                                    followed by a positive field width."  */
6554
0
                                width = -width;
6555
0
                              }
6556
0
                          }
6557
0
                        else
6558
0
                          {
6559
0
                            const FCHAR_T *digitp = dp->width_start;
6560
6561
0
                            width = 0;
6562
0
                            do
6563
0
                              width = xsum (xtimes (width, 10), *digitp++ - '0');
6564
0
                            while (digitp != dp->width_end);
6565
0
                          }
6566
0
                        if (width > (size_t) INT_MAX)
6567
0
                          goto overflow;
6568
0
#endif
6569
                        /* The width specification is known to consist only
6570
                           of standard ASCII characters.  */
6571
0
                        if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
6572
0
                          {
6573
0
                            memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
6574
0
                            fbp += n;
6575
0
                          }
6576
0
                        else
6577
0
                          {
6578
0
                            const FCHAR_T *mp = dp->width_start;
6579
0
                            do
6580
0
                              *fbp++ = *mp++;
6581
0
                            while (--n > 0);
6582
0
                          }
6583
0
                      }
6584
0
                  }
6585
0
                if (!prec_ourselves)
6586
0
                  {
6587
0
                    if (dp->precision_start != dp->precision_end)
6588
0
                      {
6589
0
                        size_t n = dp->precision_end - dp->precision_start;
6590
                        /* The precision specification is known to consist only
6591
                           of standard ASCII characters.  */
6592
0
                        if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
6593
0
                          {
6594
0
                            memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
6595
0
                            fbp += n;
6596
0
                          }
6597
0
                        else
6598
0
                          {
6599
0
                            const FCHAR_T *mp = dp->precision_start;
6600
0
                            do
6601
0
                              *fbp++ = *mp++;
6602
0
                            while (--n > 0);
6603
0
                          }
6604
0
                      }
6605
0
                  }
6606
6607
0
                switch (+type)
6608
0
                  {
6609
0
                  case TYPE_LONGLONGINT:
6610
0
                  case TYPE_ULONGLONGINT:
6611
                  #if INT8_WIDTH > LONG_WIDTH
6612
                  case TYPE_INT8_T:
6613
                  #endif
6614
                  #if UINT8_WIDTH > LONG_WIDTH
6615
                  case TYPE_UINT8_T:
6616
                  #endif
6617
                  #if INT16_WIDTH > LONG_WIDTH
6618
                  case TYPE_INT16_T:
6619
                  #endif
6620
                  #if UINT16_WIDTH > LONG_WIDTH
6621
                  case TYPE_UINT16_T:
6622
                  #endif
6623
                  #if INT32_WIDTH > LONG_WIDTH
6624
                  case TYPE_INT32_T:
6625
                  #endif
6626
                  #if UINT32_WIDTH > LONG_WIDTH
6627
                  case TYPE_UINT32_T:
6628
                  #endif
6629
                  #if INT64_WIDTH > LONG_WIDTH
6630
                  case TYPE_INT64_T:
6631
                  #endif
6632
                  #if UINT64_WIDTH > LONG_WIDTH
6633
                  case TYPE_UINT64_T:
6634
                  #endif
6635
                  #if INT_FAST8_WIDTH > LONG_WIDTH
6636
                  case TYPE_INT_FAST8_T:
6637
                  #endif
6638
                  #if UINT_FAST8_WIDTH > LONG_WIDTH
6639
                  case TYPE_UINT_FAST8_T:
6640
                  #endif
6641
                  #if INT_FAST16_WIDTH > LONG_WIDTH
6642
                  case TYPE_INT_FAST16_T:
6643
                  #endif
6644
                  #if UINT_FAST16_WIDTH > LONG_WIDTH
6645
                  case TYPE_UINT_FAST16_T:
6646
                  #endif
6647
                  #if INT_FAST32_WIDTH > LONG_WIDTH
6648
                  case TYPE_INT3_FAST2_T:
6649
                  #endif
6650
                  #if UINT_FAST32_WIDTH > LONG_WIDTH
6651
                  case TYPE_UINT_FAST32_T:
6652
                  #endif
6653
                  #if INT_FAST64_WIDTH > LONG_WIDTH
6654
                  case TYPE_INT_FAST64_T:
6655
                  #endif
6656
                  #if UINT_FAST64_WIDTH > LONG_WIDTH
6657
                  case TYPE_UINT_FAST64_T:
6658
                  #endif
6659
#if defined _WIN32 && ! defined __CYGWIN__
6660
                    *fbp++ = 'I';
6661
                    *fbp++ = '6';
6662
                    *fbp++ = '4';
6663
                    break;
6664
#else
6665
0
                    *fbp++ = 'l';
6666
0
#endif
6667
0
                    FALLTHROUGH;
6668
0
                  case TYPE_LONGINT:
6669
0
                  case TYPE_ULONGINT:
6670
                  #if INT8_WIDTH > INT_WIDTH && INT8_WIDTH <= LONG_WIDTH
6671
                  case TYPE_INT8_T:
6672
                  #endif
6673
                  #if UINT8_WIDTH > INT_WIDTH && UINT8_WIDTH <= LONG_WIDTH
6674
                  case TYPE_UINT8_T:
6675
                  #endif
6676
                  #if INT16_WIDTH > INT_WIDTH && INT16_WIDTH <= LONG_WIDTH
6677
                  case TYPE_INT16_T:
6678
                  #endif
6679
                  #if UINT16_WIDTH > INT_WIDTH && UINT16_WIDTH <= LONG_WIDTH
6680
                  case TYPE_UINT16_T:
6681
                  #endif
6682
                  #if INT32_WIDTH > INT_WIDTH && INT32_WIDTH <= LONG_WIDTH
6683
                  case TYPE_INT32_T:
6684
                  #endif
6685
                  #if UINT32_WIDTH > INT_WIDTH && UINT32_WIDTH <= LONG_WIDTH
6686
                  case TYPE_UINT32_T:
6687
                  #endif
6688
0
                  #if INT64_WIDTH > INT_WIDTH && INT64_WIDTH <= LONG_WIDTH
6689
0
                  case TYPE_INT64_T:
6690
0
                  #endif
6691
0
                  #if UINT64_WIDTH > INT_WIDTH && UINT64_WIDTH <= LONG_WIDTH
6692
0
                  case TYPE_UINT64_T:
6693
0
                  #endif
6694
                  #if INT_FAST8_WIDTH > INT_WIDTH && INT_FAST8_WIDTH <= LONG_WIDTH
6695
                  case TYPE_INT_FAST8_T:
6696
                  #endif
6697
                  #if UINT_FAST8_WIDTH > INT_WIDTH && UINT_FAST8_WIDTH <= LONG_WIDTH
6698
                  case TYPE_UINT_FAST8_T:
6699
                  #endif
6700
0
                  #if INT_FAST16_WIDTH > INT_WIDTH && INT_FAST16_WIDTH <= LONG_WIDTH
6701
0
                  case TYPE_INT_FAST16_T:
6702
0
                  #endif
6703
0
                  #if UINT_FAST16_WIDTH > INT_WIDTH && UINT_FAST16_WIDTH <= LONG_WIDTH
6704
0
                  case TYPE_UINT_FAST16_T:
6705
0
                  #endif
6706
0
                  #if INT_FAST32_WIDTH > INT_WIDTH && INT_FAST32_WIDTH <= LONG_WIDTH
6707
0
                  case TYPE_INT_FAST32_T:
6708
0
                  #endif
6709
0
                  #if UINT_FAST32_WIDTH > INT_WIDTH && UINT_FAST32_WIDTH <= LONG_WIDTH
6710
0
                  case TYPE_UINT_FAST32_T:
6711
0
                  #endif
6712
0
                  #if INT_FAST64_WIDTH > INT_WIDTH && INT_FAST64_WIDTH <= LONG_WIDTH
6713
0
                  case TYPE_INT_FAST64_T:
6714
0
                  #endif
6715
0
                  #if UINT_FAST64_WIDTH > INT_WIDTH && UINT_FAST64_WIDTH <= LONG_WIDTH
6716
0
                  case TYPE_UINT_FAST64_T:
6717
0
                  #endif
6718
0
                  #if HAVE_WINT_T
6719
0
                  case TYPE_WIDE_CHAR:
6720
0
                  #endif
6721
0
                  case TYPE_WIDE_STRING:
6722
0
                    *fbp++ = 'l';
6723
0
                    break;
6724
0
                  case TYPE_LONGDOUBLE:
6725
0
                    *fbp++ = 'L';
6726
0
                    break;
6727
0
                  default:
6728
0
                    break;
6729
0
                  }
6730
#if NEED_PRINTF_DIRECTIVE_F
6731
                if (dp->conversion == 'F')
6732
                  *fbp = 'f';
6733
                else
6734
#endif
6735
0
                  *fbp = dp->conversion;
6736
0
#if USE_SNPRINTF
6737
                /* Decide whether to pass %n in the format string
6738
                   to SNPRINTF.  */
6739
0
# if (((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR)                              \
6740
0
       && (HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99))       \
6741
0
      || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))       \
6742
0
          && !defined __UCLIBC__)                                           \
6743
0
      || (defined __APPLE__ && defined __MACH__)                            \
6744
0
      || defined __OpenBSD__                                                \
6745
0
      || defined __ANDROID__                                                \
6746
0
      || (defined _WIN32 && ! defined __CYGWIN__))                          \
6747
0
      || (WIDE_CHAR_VERSION && MUSL_LIBC)
6748
                /* We can avoid passing %n and instead rely on SNPRINTF's
6749
                   return value if
6750
                     - !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR, because otherwise,
6751
                       when WIDE_CHAR_VERSION && DCHAR_IS_TCHAR,
6752
                       snwprintf()/_snwprintf() (Windows) and swprintf() (Unix)
6753
                       don't return the needed buffer size,
6754
                     and
6755
                     - we're compiling for a system where we know
6756
                       - that snprintf's return value conforms to ISO C 99
6757
                         (HAVE_SNPRINTF_RETVAL_C99) and
6758
                       - that snprintf always produces NUL-terminated strings
6759
                         (HAVE_SNPRINTF_TRUNCATION_C99).
6760
                   And it is desirable to do so, because more and more platforms
6761
                   no longer support %n, for "security reasons".  */
6762
                /* On specific platforms, listed below, we *must* avoid %n.
6763
                   In the case
6764
                     !WIDE_CHAR_VERSION && HAVE_SNPRINTF_RETVAL_C99 && !USE_MSVC__SNPRINTF
6765
                   we can rely on the return value of snprintf instead.  Whereas
6766
                   in the opposite case
6767
                     WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
6768
                   we need to make room based on an estimation, computed by
6769
                   MAX_ROOM_NEEDED.  */
6770
                /* The following platforms forbid %n:
6771
                     - On glibc2 systems from 2004-10-18 or newer, the use of
6772
                       %n in format strings in writable memory may crash the
6773
                       program (if compiled with _FORTIFY_SOURCE >= 2).
6774
                     - On macOS 10.13 or newer, the use of %n in format
6775
                       strings in writable memory by default crashes the
6776
                       program.
6777
                     - On OpenBSD, since 2021-08-30, the use of %n in format
6778
                       strings produces an abort (see
6779
                       <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfprintf.c.diff?r1=1.79&r2=1.80&f=h>,
6780
                       <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfwprintf.c.diff?r1=1.20&r2=1.21&f=h>).
6781
                     - On Android, starting on 2018-03-07, the use of %n in
6782
                       format strings produces a fatal error (see
6783
                       <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
6784
                     - On native Windows systems (such as mingw) where the OS is
6785
                       Windows Vista, the use of %n in format strings by default
6786
                       crashes the program. See
6787
                         <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
6788
                         <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
6789
                   On the first four of these platforms, if !WIDE_CHAR_VERSION,
6790
                   it is not a big deal to avoid %n, because on these platforms,
6791
                   HAVE_SNPRINTF_RETVAL_C99 and HAVE_SNPRINTF_TRUNCATION_C99 are
6792
                   1.
6793
                   On native Windows, if !WIDE_CHAR_VERSION, it's not a big deal
6794
                   either because:
6795
                     - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
6796
                       snprintf does not write more than the specified number
6797
                       of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
6798
                       '4', '5', '6' into buf, not '4', '5', '\0'.)
6799
                     - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
6800
                       allows us to recognize the case of an insufficient
6801
                       buffer size: it returns -1 in this case.  */
6802
                /* Additionally, in the WIDE_CHAR_VERSION case, we cannot use %n
6803
                   on musl libc because we would run into an swprintf() bug.
6804
                   See <https://www.openwall.com/lists/musl/2023/03/19/1>.  */
6805
0
                fbp[1] = '\0';
6806
# else           /* AIX <= 5.1, HP-UX, Solaris <= 9, BeOS */
6807
                fbp[1] = '%';
6808
                fbp[2] = 'n';
6809
                fbp[3] = '\0';
6810
# endif
6811
#else
6812
                fbp[1] = '\0';
6813
#endif
6814
6815
                /* Construct the arguments for calling snprintf or sprintf.  */
6816
0
                prefix_count = 0;
6817
0
                if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
6818
0
                  {
6819
0
                    if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
6820
0
                      abort ();
6821
0
                    prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
6822
0
                  }
6823
0
                if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
6824
0
                  {
6825
0
                    if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
6826
0
                      abort ();
6827
0
                    prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
6828
0
                  }
6829
6830
0
#if USE_SNPRINTF
6831
                /* The SNPRINTF result is appended after result[0..length].
6832
                   The latter is an array of DCHAR_T; SNPRINTF appends an
6833
                   array of TCHAR_T to it.  This is possible because
6834
                   sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
6835
                   alignof (TCHAR_T) <= alignof (DCHAR_T).  */
6836
0
# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
6837
                /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
6838
                   where an snprintf() with maxlen==1 acts like sprintf().  */
6839
0
                ENSURE_ALLOCATION (xsum (length,
6840
0
                                         (2 + TCHARS_PER_DCHAR - 1)
6841
0
                                         / TCHARS_PER_DCHAR));
6842
                /* Prepare checking whether snprintf returns the count
6843
                   via %n.  */
6844
0
                *(TCHAR_T *) (result + length) = '\0';
6845
0
#endif
6846
6847
0
                orig_errno = errno;
6848
6849
0
                for (;;)
6850
0
                  {
6851
0
                    int count = -1;
6852
6853
0
#if USE_SNPRINTF
6854
0
                    int retcount = 0;
6855
0
                    size_t maxlen = allocated - length;
6856
                    /* SNPRINTF can fail if its second argument is
6857
                       > INT_MAX.  */
6858
0
                    if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
6859
0
                      maxlen = INT_MAX / TCHARS_PER_DCHAR;
6860
0
                    maxlen = maxlen * TCHARS_PER_DCHAR;
6861
0
# define SNPRINTF_BUF(arg) \
6862
0
                    switch (prefix_count)                                   \
6863
0
                      {                                                     \
6864
0
                      case 0:                                               \
6865
0
                        retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6866
0
                                             maxlen, buf,                   \
6867
0
                                             arg, &count);                  \
6868
0
                        break;                                              \
6869
0
                      case 1:                                               \
6870
0
                        retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6871
0
                                             maxlen, buf,                   \
6872
0
                                             prefixes[0], arg, &count);     \
6873
0
                        break;                                              \
6874
0
                      case 2:                                               \
6875
0
                        retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6876
0
                                             maxlen, buf,                   \
6877
0
                                             prefixes[0], prefixes[1], arg, \
6878
0
                                             &count);                       \
6879
0
                        break;                                              \
6880
0
                      default:                                              \
6881
0
                        abort ();                                           \
6882
0
                      }
6883
#else
6884
# define SNPRINTF_BUF(arg) \
6885
                    switch (prefix_count)                                   \
6886
                      {                                                     \
6887
                      case 0:                                               \
6888
                        count = sprintf (tmp, buf, arg);                    \
6889
                        break;                                              \
6890
                      case 1:                                               \
6891
                        count = sprintf (tmp, buf, prefixes[0], arg);       \
6892
                        break;                                              \
6893
                      case 2:                                               \
6894
                        count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
6895
                                         arg);                              \
6896
                        break;                                              \
6897
                      default:                                              \
6898
                        abort ();                                           \
6899
                      }
6900
#endif
6901
6902
0
                    errno = 0;
6903
0
                    switch (+type)
6904
0
                      {
6905
0
                      case TYPE_SCHAR:
6906
0
                        {
6907
0
                          int arg = a.arg[dp->arg_index].a.a_schar;
6908
0
                          SNPRINTF_BUF (arg);
6909
0
                        }
6910
0
                        break;
6911
0
                      case TYPE_UCHAR:
6912
0
                        {
6913
0
                          unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
6914
0
                          SNPRINTF_BUF (arg);
6915
0
                        }
6916
0
                        break;
6917
0
                      case TYPE_SHORT:
6918
0
                        {
6919
0
                          int arg = a.arg[dp->arg_index].a.a_short;
6920
0
                          SNPRINTF_BUF (arg);
6921
0
                        }
6922
0
                        break;
6923
0
                      case TYPE_USHORT:
6924
0
                        {
6925
0
                          unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
6926
0
                          SNPRINTF_BUF (arg);
6927
0
                        }
6928
0
                        break;
6929
0
                      case TYPE_INT:
6930
0
                        {
6931
0
                          int arg = a.arg[dp->arg_index].a.a_int;
6932
0
                          SNPRINTF_BUF (arg);
6933
0
                        }
6934
0
                        break;
6935
0
                      case TYPE_UINT:
6936
0
                        {
6937
0
                          unsigned int arg = a.arg[dp->arg_index].a.a_uint;
6938
0
                          SNPRINTF_BUF (arg);
6939
0
                        }
6940
0
                        break;
6941
0
                      case TYPE_LONGINT:
6942
0
                        {
6943
0
                          long int arg = a.arg[dp->arg_index].a.a_longint;
6944
0
                          SNPRINTF_BUF (arg);
6945
0
                        }
6946
0
                        break;
6947
0
                      case TYPE_ULONGINT:
6948
0
                        {
6949
0
                          unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
6950
0
                          SNPRINTF_BUF (arg);
6951
0
                        }
6952
0
                        break;
6953
0
                      case TYPE_LONGLONGINT:
6954
0
                        {
6955
0
                          long long int arg = a.arg[dp->arg_index].a.a_longlongint;
6956
0
                          SNPRINTF_BUF (arg);
6957
0
                        }
6958
0
                        break;
6959
0
                      case TYPE_ULONGLONGINT:
6960
0
                        {
6961
0
                          unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
6962
0
                          SNPRINTF_BUF (arg);
6963
0
                        }
6964
0
                        break;
6965
0
                      case TYPE_INT8_T:
6966
0
                        {
6967
0
                          int8_t arg = a.arg[dp->arg_index].a.a_int8_t;
6968
0
                          SNPRINTF_BUF (arg);
6969
0
                        }
6970
0
                        break;
6971
0
                      case TYPE_UINT8_T:
6972
0
                        {
6973
0
                          uint8_t arg = a.arg[dp->arg_index].a.a_uint8_t;
6974
0
                          SNPRINTF_BUF (arg);
6975
0
                        }
6976
0
                        break;
6977
0
                      case TYPE_INT16_T:
6978
0
                        {
6979
0
                          int16_t arg = a.arg[dp->arg_index].a.a_int16_t;
6980
0
                          SNPRINTF_BUF (arg);
6981
0
                        }
6982
0
                        break;
6983
0
                      case TYPE_UINT16_T:
6984
0
                        {
6985
0
                          uint16_t arg = a.arg[dp->arg_index].a.a_uint16_t;
6986
0
                          SNPRINTF_BUF (arg);
6987
0
                        }
6988
0
                        break;
6989
0
                      case TYPE_INT32_T:
6990
0
                        {
6991
0
                          int32_t arg = a.arg[dp->arg_index].a.a_int32_t;
6992
0
                          SNPRINTF_BUF (arg);
6993
0
                        }
6994
0
                        break;
6995
0
                      case TYPE_UINT32_T:
6996
0
                        {
6997
0
                          uint32_t arg = a.arg[dp->arg_index].a.a_uint32_t;
6998
0
                          SNPRINTF_BUF (arg);
6999
0
                        }
7000
0
                        break;
7001
0
                      case TYPE_INT64_T:
7002
0
                        {
7003
0
                          int64_t arg = a.arg[dp->arg_index].a.a_int64_t;
7004
0
                          SNPRINTF_BUF (arg);
7005
0
                        }
7006
0
                        break;
7007
0
                      case TYPE_UINT64_T:
7008
0
                        {
7009
0
                          uint64_t arg = a.arg[dp->arg_index].a.a_uint64_t;
7010
0
                          SNPRINTF_BUF (arg);
7011
0
                        }
7012
0
                        break;
7013
0
                      case TYPE_INT_FAST8_T:
7014
0
                        {
7015
0
                          int_fast8_t arg = a.arg[dp->arg_index].a.a_int_fast8_t;
7016
0
                          SNPRINTF_BUF (arg);
7017
0
                        }
7018
0
                        break;
7019
0
                      case TYPE_UINT_FAST8_T:
7020
0
                        {
7021
0
                          uint_fast8_t arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
7022
0
                          SNPRINTF_BUF (arg);
7023
0
                        }
7024
0
                        break;
7025
0
                      case TYPE_INT_FAST16_T:
7026
0
                        {
7027
0
                          int_fast16_t arg = a.arg[dp->arg_index].a.a_int_fast16_t;
7028
0
                          SNPRINTF_BUF (arg);
7029
0
                        }
7030
0
                        break;
7031
0
                      case TYPE_UINT_FAST16_T:
7032
0
                        {
7033
0
                          uint_fast16_t arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
7034
0
                          SNPRINTF_BUF (arg);
7035
0
                        }
7036
0
                        break;
7037
0
                      case TYPE_INT_FAST32_T:
7038
0
                        {
7039
0
                          int_fast32_t arg = a.arg[dp->arg_index].a.a_int_fast32_t;
7040
0
                          SNPRINTF_BUF (arg);
7041
0
                        }
7042
0
                        break;
7043
0
                      case TYPE_UINT_FAST32_T:
7044
0
                        {
7045
0
                          uint_fast32_t arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
7046
0
                          SNPRINTF_BUF (arg);
7047
0
                        }
7048
0
                        break;
7049
0
                      case TYPE_INT_FAST64_T:
7050
0
                        {
7051
0
                          int_fast64_t arg = a.arg[dp->arg_index].a.a_int_fast64_t;
7052
0
                          SNPRINTF_BUF (arg);
7053
0
                        }
7054
0
                        break;
7055
0
                      case TYPE_UINT_FAST64_T:
7056
0
                        {
7057
0
                          uint_fast64_t arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
7058
0
                          SNPRINTF_BUF (arg);
7059
0
                        }
7060
0
                        break;
7061
0
                      case TYPE_DOUBLE:
7062
0
                        {
7063
0
                          double arg = a.arg[dp->arg_index].a.a_double;
7064
0
                          SNPRINTF_BUF (arg);
7065
0
                        }
7066
0
                        break;
7067
0
                      case TYPE_LONGDOUBLE:
7068
0
                        {
7069
0
                          long double arg = a.arg[dp->arg_index].a.a_longdouble;
7070
0
                          SNPRINTF_BUF (arg);
7071
0
                        }
7072
0
                        break;
7073
0
                      case TYPE_CHAR:
7074
0
                        {
7075
0
                          int arg = a.arg[dp->arg_index].a.a_char;
7076
0
                          SNPRINTF_BUF (arg);
7077
0
                        }
7078
0
                        break;
7079
0
#if HAVE_WINT_T
7080
0
                      case TYPE_WIDE_CHAR:
7081
0
                        {
7082
0
                          wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
7083
0
                          SNPRINTF_BUF (arg);
7084
0
                        }
7085
0
                        break;
7086
0
#endif
7087
0
                      case TYPE_STRING:
7088
0
                        {
7089
0
                          const char *arg = a.arg[dp->arg_index].a.a_string;
7090
0
                          SNPRINTF_BUF (arg);
7091
0
                        }
7092
0
                        break;
7093
0
                      case TYPE_WIDE_STRING:
7094
0
                        {
7095
0
                          const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
7096
0
                          SNPRINTF_BUF (arg);
7097
0
                        }
7098
0
                        break;
7099
0
                      case TYPE_POINTER:
7100
0
                        {
7101
0
                          void *arg = a.arg[dp->arg_index].a.a_pointer;
7102
0
                          SNPRINTF_BUF (arg);
7103
0
                        }
7104
0
                        break;
7105
0
                      default:
7106
0
                        abort ();
7107
0
                      }
7108
7109
0
#if USE_SNPRINTF
7110
                    /* Portability: Not all implementations of snprintf()
7111
                       are ISO C 99 compliant.  Determine the number of
7112
                       bytes that snprintf() has produced or would have
7113
                       produced.  */
7114
0
                    if (count >= 0)
7115
0
                      {
7116
                        /* Verify that snprintf() has NUL-terminated its
7117
                           result.  */
7118
0
                        if ((unsigned int) count < maxlen
7119
0
                            && ((TCHAR_T *) (result + length)) [count] != '\0')
7120
0
                          abort ();
7121
                        /* Portability hack.  */
7122
0
                        if (retcount > count)
7123
0
                          count = retcount;
7124
0
                      }
7125
0
                    else
7126
0
                      {
7127
                        /* snprintf() doesn't understand the '%n'
7128
                           directive.  */
7129
0
                        if (fbp[1] != '\0')
7130
0
                          {
7131
                            /* Don't use the '%n' directive; instead, look
7132
                               at the snprintf() return value.  */
7133
0
                            fbp[1] = '\0';
7134
0
                            continue;
7135
0
                          }
7136
0
                        else
7137
0
                          {
7138
                            /* Look at the snprintf() return value.  */
7139
0
                            if (retcount < 0)
7140
0
                              {
7141
# if (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
7142
                                /* HP-UX 10.20 snprintf() is doubly deficient:
7143
                                   It doesn't understand the '%n' directive,
7144
                                   *and* it returns -1 (rather than the length
7145
                                   that would have been required) when the
7146
                                   buffer is too small.
7147
                                   Likewise, in case of
7148
                                   WIDE_CHAR_VERSION && DCHAR_IS_TCHAR, the
7149
                                   functions snwprintf()/_snwprintf() (Windows)
7150
                                   or swprintf() (Unix).
7151
                                   But a failure at this point can also come
7152
                                   from other reasons than a too small buffer,
7153
                                   such as an invalid wide string argument to
7154
                                   the %ls directive, or possibly an invalid
7155
                                   floating-point argument.  */
7156
                                size_t tmp_length =
7157
                                  MAX_ROOM_NEEDED (&a, dp->arg_index,
7158
                                                   dp->conversion, type, flags,
7159
                                                   width,
7160
                                                   has_precision,
7161
                                                   precision, pad_ourselves);
7162
7163
                                if (maxlen < tmp_length)
7164
                                  {
7165
                                    /* Make more room.  But try to do through
7166
                                       this reallocation only once.  */
7167
                                    size_t bigger_need =
7168
                                      xsum (length,
7169
                                            xsum (tmp_length,
7170
                                                  TCHARS_PER_DCHAR - 1)
7171
                                            / TCHARS_PER_DCHAR);
7172
                                    /* And always grow proportionally.
7173
                                       (There may be several arguments, each
7174
                                       needing a little more room than the
7175
                                       previous one.)  */
7176
                                    size_t bigger_need2 =
7177
                                      xsum (xtimes (allocated, 2), 12);
7178
                                    if (bigger_need < bigger_need2)
7179
                                      bigger_need = bigger_need2;
7180
                                    ENSURE_ALLOCATION (bigger_need);
7181
                                    continue;
7182
                                  }
7183
# endif
7184
0
                              }
7185
0
                            else
7186
0
                              {
7187
0
                                count = retcount;
7188
# if WIDE_CHAR_VERSION && defined __MINGW32__
7189
                                if (count == 0 && dp->conversion == 'c')
7190
                                  /* snwprintf returned 0 instead of 1.  But it
7191
                                     wrote a null wide character.  */
7192
                                  count = 1;
7193
# endif
7194
0
                              }
7195
0
                          }
7196
0
                      }
7197
0
#endif
7198
7199
                    /* Attempt to handle failure.  */
7200
0
                    if (count < 0)
7201
0
                      {
7202
                        /* SNPRINTF or sprintf failed.  Use the errno that it
7203
                           has set, if any.  */
7204
0
                        if (errno == 0)
7205
0
                          {
7206
0
                            if (dp->conversion == 'c' || dp->conversion == 's')
7207
0
                              errno = EILSEQ;
7208
0
                            else
7209
0
                              errno = EINVAL;
7210
0
                          }
7211
7212
0
                        goto fail_with_errno;
7213
0
                      }
7214
7215
0
#if USE_SNPRINTF
7216
                    /* Handle overflow of the allocated buffer.
7217
                       If such an overflow occurs, a C99 compliant snprintf()
7218
                       returns a count >= maxlen.  However, a non-compliant
7219
                       snprintf() function returns only count = maxlen - 1.  To
7220
                       cover both cases, test whether count >= maxlen - 1.  */
7221
0
                    if ((unsigned int) count + 1 >= maxlen)
7222
0
                      {
7223
                        /* If maxlen already has attained its allowed maximum,
7224
                           allocating more memory will not increase maxlen.
7225
                           Instead of looping, bail out.  */
7226
0
                        if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
7227
0
                          goto overflow;
7228
0
                        else
7229
0
                          {
7230
                            /* Need at least (count + 1) * sizeof (TCHAR_T)
7231
                               bytes.  (The +1 is for the trailing NUL.)
7232
                               But ask for (count + 2) * sizeof (TCHAR_T)
7233
                               bytes, so that in the next round, we likely get
7234
                                 maxlen > (unsigned int) count + 1
7235
                               and so we don't get here again.
7236
                               And allocate proportionally, to avoid looping
7237
                               eternally if snprintf() reports a too small
7238
                               count.  */
7239
0
                            size_t n =
7240
0
                              xmax (xsum (length,
7241
0
                                          ((unsigned int) count + 2
7242
0
                                           + TCHARS_PER_DCHAR - 1)
7243
0
                                          / TCHARS_PER_DCHAR),
7244
0
                                    xtimes (allocated, 2));
7245
7246
0
                            ENSURE_ALLOCATION (n);
7247
0
                            continue;
7248
0
                          }
7249
0
                      }
7250
0
#endif
7251
7252
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
7253
                    if (prec_ourselves)
7254
                      {
7255
                        /* Handle the precision.  */
7256
                        TCHAR_T *prec_ptr =
7257
# if USE_SNPRINTF
7258
                          (TCHAR_T *) (result + length);
7259
# else
7260
                          tmp;
7261
# endif
7262
                        size_t prefix_count;
7263
                        size_t move;
7264
7265
                        prefix_count = 0;
7266
                        /* Put the additional zeroes after the sign.  */
7267
                        if (count >= 1
7268
                            && (*prec_ptr == '-' || *prec_ptr == '+'
7269
                                || *prec_ptr == ' '))
7270
                          prefix_count = 1;
7271
                        /* Put the additional zeroes after the 0x prefix if
7272
                           (flags & FLAG_ALT) || (dp->conversion == 'p'), or
7273
                           after the 0b prefix if (flags & FLAG_ALT).  */
7274
                        else if (count >= 2
7275
                                 && prec_ptr[0] == '0'
7276
                                 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'
7277
                                     || prec_ptr[1] == 'b'
7278
                                     || prec_ptr[1] == 'B'))
7279
                          prefix_count = 2;
7280
7281
                        move = count - prefix_count;
7282
                        if (precision > move)
7283
                          {
7284
                            /* Insert zeroes.  */
7285
                            size_t insert = precision - move;
7286
                            TCHAR_T *prec_end;
7287
7288
# if USE_SNPRINTF
7289
                            size_t n =
7290
                              xsum (length,
7291
                                    (count + insert + TCHARS_PER_DCHAR - 1)
7292
                                    / TCHARS_PER_DCHAR);
7293
                            length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7294
                            ENSURE_ALLOCATION (n);
7295
                            length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7296
                            prec_ptr = (TCHAR_T *) (result + length);
7297
# endif
7298
7299
                            prec_end = prec_ptr + count;
7300
                            prec_ptr += prefix_count;
7301
7302
                            while (prec_end > prec_ptr)
7303
                              {
7304
                                prec_end--;
7305
                                prec_end[insert] = prec_end[0];
7306
                              }
7307
7308
                            prec_end += insert;
7309
                            do
7310
                              *--prec_end = '0';
7311
                            while (prec_end > prec_ptr);
7312
7313
                            count += insert;
7314
                          }
7315
# if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
7316
                        else if (precision == 0
7317
                                 && move == 1
7318
                                 && prec_ptr[prefix_count] == '0')
7319
                          {
7320
                            /* Replace the "0" result with an empty string.  */
7321
                            count = prefix_count;
7322
                          }
7323
# endif
7324
                      }
7325
#endif
7326
7327
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
7328
                    if (group_ourselves) /* implies (flags & FLAG_GROUP) */
7329
                      /* Handle the grouping.  */
7330
                      switch (dp->conversion)
7331
                        {
7332
                        /* These are the only conversion to which grouping
7333
                           applies.  */
7334
                        case 'd': case 'i': case 'u':
7335
                        case 'f': case 'F': case 'g': case 'G':
7336
                          {
7337
                            /* Determine the thousands separator of the current
7338
                               locale.  */
7339
                            const TCHAR_T *thousep;
7340
                            TCHAR_T thousep_buf[10];
7341
7342
# if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
7343
                            /* TCHAR_T is wchar_t.  */
7344
                            thousep = thousands_separator_wchar (thousep_buf);
7345
# else
7346
                            /* TCHAR_T is char.  */
7347
                            thousep = thousands_separator_char (thousep_buf);
7348
# endif
7349
7350
                            /* Nothing to do in locales where thousep is the empty
7351
                               string.  */
7352
                            if (*thousep != 0)
7353
                              {
7354
                                /* Since FLAG_LOCALIZED is only supported on glibc
7355
                                   systems, here we can assume that all digits are
7356
                                   the ASCII digits '0'..'9'.  */
7357
                                TCHAR_T *number_ptr =
7358
# if USE_SNPRINTF
7359
                                  (TCHAR_T *) (result + length);
7360
# else
7361
                                  tmp;
7362
# endif
7363
                                TCHAR_T *end_ptr = number_ptr + count;
7364
7365
                                /* Find where the leading digits start.  */
7366
                                TCHAR_T *digits_ptr = number_ptr;
7367
                                if (count >= 1
7368
                                    && (*digits_ptr == '-' || *digits_ptr == '+'
7369
                                        || *digits_ptr == ' '))
7370
                                  digits_ptr++;
7371
7372
                                /* Find where the leading digits end.  */
7373
                                TCHAR_T *digits_end_ptr;
7374
                                switch (dp->conversion)
7375
                                  {
7376
                                  case 'd': case 'i': case 'u':
7377
                                    digits_end_ptr = end_ptr;
7378
                                    break;
7379
                                  case 'f': case 'F': case 'g': case 'G':
7380
                                    {
7381
                                      TCHAR_T decimal_point = decimal_point_char ();
7382
                                      for (digits_end_ptr = digits_ptr;
7383
                                           digits_end_ptr < end_ptr;
7384
                                           digits_end_ptr++)
7385
                                        if (*digits_end_ptr == decimal_point
7386
                                            || *digits_end_ptr == 'e')
7387
                                          break;
7388
                                    }
7389
                                    break;
7390
                                  }
7391
7392
                                /* Determine the number of thousands separators
7393
                                   to insert.  */
7394
                                const signed char *grouping = grouping_rule ();
7395
                                size_t insert =
7396
                                  num_thousands_separators (grouping, digits_end_ptr - digits_ptr);
7397
                                if (insert > 0)
7398
                                  {
7399
# if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
7400
#                                   define thousep_len 1
7401
# else
7402
                                    size_t thousep_len = strlen (thousep);
7403
# endif
7404
# if USE_SNPRINTF
7405
                                    size_t digits_offset = digits_ptr - number_ptr;
7406
                                    size_t digits_end_offset = digits_end_ptr - number_ptr;
7407
                                    size_t n =
7408
                                      xsum (length,
7409
                                            (count + insert * thousep_len + TCHARS_PER_DCHAR - 1)
7410
                                            / TCHARS_PER_DCHAR);
7411
                                    length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7412
                                    ENSURE_ALLOCATION (n);
7413
                                    length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7414
                                    number_ptr = (TCHAR_T *) (result + length);
7415
                                    end_ptr = number_ptr + count;
7416
                                    digits_ptr = number_ptr + digits_offset;
7417
                                    digits_end_ptr = number_ptr + digits_end_offset;
7418
# endif
7419
7420
                                    count += insert * thousep_len;
7421
7422
                                    const TCHAR_T *p = end_ptr;
7423
                                    TCHAR_T *q = end_ptr + insert * thousep_len;
7424
                                    while (p > digits_end_ptr)
7425
                                      *--q = *--p;
7426
                                    const signed char *g = grouping;
7427
                                    for (;;)
7428
                                      {
7429
                                        int h = *g;
7430
                                        if (h <= 0)
7431
                                          abort ();
7432
                                        int i = h;
7433
                                        do
7434
                                          *--q = *--p;
7435
                                        while (--i > 0);
7436
# if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
7437
                                        *--q = *thousep;
7438
# else
7439
                                        q -= thousep_len;
7440
                                        memcpy (q, thousep, thousep_len);
7441
# endif
7442
                                        insert--;
7443
                                        if (insert == 0)
7444
                                          break;
7445
                                        if (g[1] != 0)
7446
                                          g++;
7447
                                      }
7448
                                    /* Here q == p.  Done with the insertions.  */
7449
                                  }
7450
                              }
7451
                          }
7452
                          break;
7453
                        }
7454
#endif
7455
7456
#if !USE_SNPRINTF
7457
                    if (count >= tmp_length)
7458
                      /* tmp_length was incorrectly calculated - fix the
7459
                         code above!  */
7460
                      abort ();
7461
#endif
7462
7463
#if !DCHAR_IS_TCHAR
7464
                    /* Convert from TCHAR_T[] to DCHAR_T[].  */
7465
                    if (dp->conversion == 'c' || dp->conversion == 's'
7466
                        || (flags & FLAG_GROUP)
7467
# if __GLIBC__ >= 2 && !defined __UCLIBC__
7468
                        || (flags & FLAG_LOCALIZED)
7469
# endif
7470
                       )
7471
                      {
7472
                        /* The result string is not guaranteed to be ASCII.  */
7473
                        /* This code assumes that TCHAR_T is 'char'.  */
7474
                        static_assert (sizeof (TCHAR_T) == 1);
7475
                        const TCHAR_T *tmpsrc;
7476
# if USE_SNPRINTF
7477
                        tmpsrc = (TCHAR_T *) (result + length);
7478
# else
7479
                        tmpsrc = tmp;
7480
# endif
7481
                        DCHAR_T *tmpdst;
7482
                        size_t tmpdst_len;
7483
# if WIDE_CHAR_VERSION
7484
                        /* Convert tmpsrc[0..count-1] to a freshly allocated
7485
                           wide character array.  */
7486
                        mbstate_t state;
7487
7488
                        mbszero (&state);
7489
                        tmpdst_len = 0;
7490
                        {
7491
                          const TCHAR_T *src = tmpsrc;
7492
                          size_t srclen = count;
7493
7494
                          for (; srclen > 0; tmpdst_len++)
7495
                            {
7496
                              /* Parse the next multibyte character.  */
7497
                              size_t ret = mbrtowc (NULL, src, srclen, &state);
7498
                              if (ret == (size_t)(-2) || ret == (size_t)(-1))
7499
                                goto fail_with_EILSEQ;
7500
                              if (ret == 0)
7501
                                ret = 1;
7502
                              src += ret;
7503
                              srclen -= ret;
7504
                            }
7505
                        }
7506
7507
                        tmpdst =
7508
                          (wchar_t *) malloc ((tmpdst_len + 1) * sizeof (wchar_t));
7509
                        if (tmpdst == NULL)
7510
                          goto out_of_memory;
7511
7512
                        mbszero (&state);
7513
                        {
7514
                          DCHAR_T *destptr = tmpdst;
7515
                          const TCHAR_T *src = tmpsrc;
7516
                          size_t srclen = count;
7517
7518
                          for (; srclen > 0; destptr++)
7519
                            {
7520
                              /* Parse the next multibyte character.  */
7521
                              size_t ret = mbrtowc (destptr, src, srclen, &state);
7522
                              if (ret == (size_t)(-2) || ret == (size_t)(-1))
7523
                                /* Should already have been caught in the first
7524
                                   loop, above.  */
7525
                                abort ();
7526
                              if (ret == 0)
7527
                                ret = 1;
7528
                              src += ret;
7529
                              srclen -= ret;
7530
                            }
7531
                        }
7532
# else
7533
                        tmpdst =
7534
                          DCHAR_CONV_FROM_ENCODING (locale_charset (),
7535
                                                    iconveh_question_mark,
7536
                                                    tmpsrc, count,
7537
                                                    NULL,
7538
                                                    NULL, &tmpdst_len);
7539
                        if (tmpdst == NULL)
7540
                          goto fail_with_errno;
7541
# endif
7542
                        ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
7543
                          { free (tmpdst); goto out_of_memory; });
7544
                        DCHAR_CPY (result + length, tmpdst, tmpdst_len);
7545
                        free (tmpdst);
7546
                        count = tmpdst_len;
7547
                      }
7548
                    else
7549
                      {
7550
                        /* The result string is ASCII.
7551
                           Simple 1:1 conversion.  */
7552
# if USE_SNPRINTF
7553
                        /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
7554
                           no-op conversion, in-place on the array starting
7555
                           at (result + length).  */
7556
                        if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
7557
# endif
7558
                          {
7559
                            const TCHAR_T *tmpsrc;
7560
# if USE_SNPRINTF
7561
                            if (result == resultbuf)
7562
                              {
7563
                                tmpsrc = (TCHAR_T *) (result + length);
7564
                                /* ENSURE_ALLOCATION will not move tmpsrc
7565
                                   (because it's part of resultbuf).  */
7566
                                ENSURE_ALLOCATION (xsum (length, count));
7567
                              }
7568
                            else
7569
                              {
7570
                                /* ENSURE_ALLOCATION will move the array
7571
                                   (because it uses realloc().  */
7572
                                ENSURE_ALLOCATION (xsum (length, count));
7573
                                tmpsrc = (TCHAR_T *) (result + length);
7574
                              }
7575
# else
7576
                            tmpsrc = tmp;
7577
                            ENSURE_ALLOCATION (xsum (length, count));
7578
# endif
7579
                            DCHAR_T *tmpdst = result + length;
7580
                            /* Copy backwards, because of overlapping.  */
7581
                            tmpsrc += count;
7582
                            tmpdst += count;
7583
                            for (size_t n = count; n > 0; n--)
7584
                              *--tmpdst = *--tmpsrc;
7585
                          }
7586
                      }
7587
#endif
7588
7589
#if DCHAR_IS_TCHAR && !USE_SNPRINTF
7590
                    /* Make room for the result.  */
7591
                    if (count > allocated - length)
7592
                      {
7593
                        /* Need at least count elements.  But allocate
7594
                           proportionally.  */
7595
                        size_t n =
7596
                          xmax (xsum (length, count), xtimes (allocated, 2));
7597
7598
                        ENSURE_ALLOCATION (n);
7599
                      }
7600
#endif
7601
7602
                    /* Here count <= allocated - length.  */
7603
7604
                    /* Perform padding.  */
7605
#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
7606
                    if (pad_ourselves && has_width)
7607
                      {
7608
                        size_t w;
7609
# if ENABLE_UNISTDIO
7610
                        /* Outside POSIX, it's preferable to compare the width
7611
                           against the number of _characters_ of the converted
7612
                           value.  */
7613
                        w = DCHAR_MBSNLEN (result + length, count);
7614
# elif __GLIBC__ >= 2
7615
                        /* glibc prefers to compare the width against the number
7616
                           of characters as well, but only for numeric conversion
7617
                           specifiers.  See
7618
                           <https://sourceware.org/PR28943>
7619
                           <https://sourceware.org/PR30883>
7620
                           <https://sourceware.org/PR31542>  */
7621
                        switch (dp->conversion)
7622
                          {
7623
                          case 'd': case 'i': case 'u':
7624
                          case 'f': case 'F': case 'g': case 'G':
7625
                            w = DCHAR_MBSNLEN (result + length, count);
7626
                            break;
7627
                          default:
7628
                            w = count;
7629
                            break;
7630
                          }
7631
# else
7632
                        /* The width is compared against the number of _bytes_
7633
                           of the converted value, says POSIX.  */
7634
                        w = count;
7635
# endif
7636
                        if (w < width)
7637
                          {
7638
                            size_t pad = width - w;
7639
7640
                            /* Make room for the result.  */
7641
                            if (xsum (count, pad) > allocated - length)
7642
                              {
7643
                                /* Need at least count + pad elements.  But
7644
                                   allocate proportionally.  */
7645
                                size_t n =
7646
                                  xmax (xsum3 (length, count, pad),
7647
                                        xtimes (allocated, 2));
7648
7649
# if USE_SNPRINTF
7650
                                length += count;
7651
                                ENSURE_ALLOCATION (n);
7652
                                length -= count;
7653
# else
7654
                                ENSURE_ALLOCATION (n);
7655
# endif
7656
                              }
7657
                            /* Here count + pad <= allocated - length.  */
7658
7659
                            {
7660
# if !DCHAR_IS_TCHAR || USE_SNPRINTF
7661
                              DCHAR_T * const rp = result + length;
7662
# else
7663
                              DCHAR_T * const rp = tmp;
7664
# endif
7665
                              DCHAR_T *p = rp + count;
7666
                              DCHAR_T *end = p + pad;
7667
                              DCHAR_T *pad_ptr;
7668
# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
7669
                              if (dp->conversion == 'c'
7670
                                  || dp->conversion == 's')
7671
                                /* No zero-padding for string directives.  */
7672
                                pad_ptr = NULL;
7673
                              else
7674
# endif
7675
                                {
7676
                                  pad_ptr = (*rp == '-' ? rp + 1 : rp);
7677
                                  /* No zero-padding of "inf" and "nan".  */
7678
                                  if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
7679
                                      || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
7680
                                    pad_ptr = NULL;
7681
                                  else
7682
                                    /* Do the zero-padding after the "0x" or
7683
                                       "0b" prefix, not before.  */
7684
                                    if (p - rp >= 2
7685
                                        && *rp == '0'
7686
                                        && (((dp->conversion == 'a'
7687
                                              || dp->conversion == 'x')
7688
                                             && rp[1] == 'x')
7689
                                            || ((dp->conversion == 'A'
7690
                                                 || dp->conversion == 'X')
7691
                                                && rp[1] == 'X')
7692
                                            || (dp->conversion == 'b'
7693
                                                && rp[1] == 'b')
7694
                                            || (dp->conversion == 'B'
7695
                                                && rp[1] == 'B')))
7696
                                      pad_ptr += 2;
7697
                                }
7698
                              /* The generated string now extends from rp to p,
7699
                                 with the zero padding insertion point being at
7700
                                 pad_ptr.  */
7701
7702
                              count = count + pad; /* = end - rp */
7703
7704
                              if (flags & FLAG_LEFT)
7705
                                {
7706
                                  /* Pad with spaces on the right.  */
7707
                                  for (; pad > 0; pad--)
7708
                                    *p++ = ' ';
7709
                                }
7710
                              else if ((flags & FLAG_ZERO) && pad_ptr != NULL
7711
                                       /* ISO C says: "For d, i, o, u, x, and X
7712
                                          conversions, if a precision is
7713
                                          specified, the 0 flag is ignored.  */
7714
                                       && !(has_precision
7715
                                            && (dp->conversion == 'd'
7716
                                                || dp->conversion == 'i'
7717
                                                || dp->conversion == 'o'
7718
                                                || dp->conversion == 'u'
7719
                                                || dp->conversion == 'x'
7720
                                                || dp->conversion == 'X'
7721
                                                /* Although ISO C does not
7722
                                                   require it, treat 'b' and 'B'
7723
                                                   like 'x' and 'X'.  */
7724
                                                || dp->conversion == 'b'
7725
                                                || dp->conversion == 'B')))
7726
                                {
7727
                                  /* Pad with zeroes.  */
7728
                                  DCHAR_T *q = end;
7729
7730
                                  while (p > pad_ptr)
7731
                                    *--q = *--p;
7732
                                  for (; pad > 0; pad--)
7733
                                    *p++ = '0';
7734
                                }
7735
                              else
7736
                                {
7737
                                  /* Pad with spaces on the left.  */
7738
                                  DCHAR_T *q = end;
7739
7740
                                  while (p > rp)
7741
                                    *--q = *--p;
7742
                                  for (; pad > 0; pad--)
7743
                                    *p++ = ' ';
7744
                                }
7745
                            }
7746
                          }
7747
                      }
7748
#endif
7749
7750
                    /* Here still count <= allocated - length.  */
7751
7752
0
#if !DCHAR_IS_TCHAR || USE_SNPRINTF
7753
                    /* The snprintf() result did fit.  */
7754
#else
7755
                    /* Append the sprintf() result.  */
7756
                    memcpy (result + length, tmp, count * sizeof (DCHAR_T));
7757
#endif
7758
#if !USE_SNPRINTF
7759
                    if (tmp != tmpbuf)
7760
                      free (tmp);
7761
#endif
7762
7763
#if NEED_PRINTF_DIRECTIVE_F
7764
                    if (dp->conversion == 'F')
7765
                      {
7766
                        /* Convert the %f result to upper case for %F.  */
7767
                        DCHAR_T *rp = result + length;
7768
                        for (size_t rc = count; rc > 0; rc--, rp++)
7769
                          if (*rp >= 'a' && *rp <= 'z')
7770
                            *rp = *rp - 'a' + 'A';
7771
                      }
7772
#endif
7773
7774
0
                    length += count;
7775
0
                    break;
7776
0
                  }
7777
0
                errno = orig_errno;
7778
0
#undef pad_ourselves
7779
0
#undef prec_ourselves
7780
0
              }
7781
9.16k
          }
7782
9.16k
      }
7783
7784
    /* Add the final NUL.  */
7785
9.16k
    ENSURE_ALLOCATION (xsum (length, 1));
7786
9.16k
    result[length] = '\0';
7787
7788
9.16k
    if (result != resultbuf && length + 1 < allocated)
7789
8.68k
      {
7790
        /* Shrink the allocated memory if possible.  */
7791
8.68k
        DCHAR_T *memory =
7792
8.68k
          (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
7793
8.68k
        if (memory != NULL)
7794
8.68k
          result = memory;
7795
8.68k
      }
7796
7797
9.16k
    if (buf_malloced != NULL)
7798
9.16k
      free (buf_malloced);
7799
9.16k
    CLEANUP ();
7800
9.16k
    *lengthp = length;
7801
    /* Note that we can produce a big string of a length > INT_MAX.  POSIX
7802
       says that snprintf() fails with errno = EOVERFLOW in this case, but
7803
       that's only because snprintf() returns an 'int'.  This function does
7804
       not have this limitation.  */
7805
9.16k
    return result;
7806
7807
0
  overflow:
7808
0
    errno = EOVERFLOW;
7809
0
    goto fail_with_errno;
7810
7811
0
  out_of_memory:
7812
0
    errno = ENOMEM;
7813
0
    goto fail_with_errno;
7814
7815
0
#if ENABLE_UNISTDIO || (WIDE_CHAR_VERSION || !USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION) || (NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION)
7816
0
  fail_with_EILSEQ:
7817
0
    errno = EILSEQ;
7818
0
    goto fail_with_errno;
7819
0
#endif
7820
7821
0
  fail_with_errno:
7822
0
    if (result != resultbuf)
7823
0
      free (result);
7824
0
    if (buf_malloced != NULL)
7825
0
      free (buf_malloced);
7826
0
    CLEANUP ();
7827
0
    return NULL;
7828
9.16k
  }
7829
7830
0
 out_of_memory_1:
7831
0
  errno = ENOMEM;
7832
0
  goto fail_1_with_errno;
7833
7834
0
 fail_1_with_EINVAL:
7835
0
  errno = EINVAL;
7836
0
  goto fail_1_with_errno;
7837
7838
0
 fail_1_with_errno:
7839
0
  CLEANUP ();
7840
  return NULL;
7841
9.16k
}
7842
7843
#undef MAX_ROOM_NEEDED
7844
#undef TCHARS_PER_DCHAR
7845
#undef SNPRINTF
7846
#undef USE_SNPRINTF
7847
#undef DCHAR_SET
7848
#undef DCHAR_CPY
7849
#undef PRINTF_PARSE
7850
#undef DIRECTIVES
7851
#undef DIRECTIVE
7852
#undef DCHAR_IS_TCHAR
7853
#undef TCHAR_T
7854
#undef DCHAR_T
7855
#undef FCHAR_T
7856
#undef VASNPRINTF