Coverage Report

Created: 2026-01-25 07:18

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