Line data Source code
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 : # define DCHAR_T char
152 : # define TCHAR_T char
153 : # define DCHAR_IS_TCHAR 1
154 : # define DIRECTIVE char_directive
155 : # define DIRECTIVES char_directives
156 : # define PRINTF_PARSE printf_parse
157 : # define DCHAR_CPY memcpy
158 : # 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 : # 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 : # 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 : # 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 : # 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 14391 : VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
2496 : const FCHAR_T *format, va_list args)
2497 : {
2498 : DIRECTIVES d;
2499 : arguments a;
2500 :
2501 14391 : 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 : #define CLEANUP() \
2507 : if (d.dir != d.direct_alloc_dir) \
2508 : free (d.dir); \
2509 : if (a.arg != a.direct_alloc_arg) \
2510 : free (a.arg);
2511 :
2512 14391 : if (PRINTF_FETCHARGS (args, &a) < 0)
2513 0 : goto fail_1_with_EINVAL;
2514 :
2515 : {
2516 : size_t buf_neededlength;
2517 : TCHAR_T *buf;
2518 : TCHAR_T *buf_malloced;
2519 : const FCHAR_T *cp;
2520 : size_t di;
2521 : DIRECTIVE *dp;
2522 : /* Output string accumulator. */
2523 : DCHAR_T *result;
2524 : size_t allocated;
2525 : size_t length;
2526 :
2527 : /* Allocate a small buffer that will hold a directive passed to
2528 : sprintf or snprintf. */
2529 : buf_neededlength =
2530 14391 : xsum4 (7, d.max_width_length, d.max_precision_length, 6);
2531 : #if HAVE_ALLOCA
2532 14391 : if (buf_neededlength < 4000 / sizeof (TCHAR_T))
2533 : {
2534 14391 : buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
2535 14391 : buf_malloced = NULL;
2536 : }
2537 : else
2538 : #endif
2539 : {
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 : }
2548 :
2549 14391 : result = resultbuf;
2550 14391 : allocated = (resultbuf != NULL ? *lengthp : 0);
2551 14391 : 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 : #define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \
2560 : if ((needed) > allocated) \
2561 : { \
2562 : size_t memory_size; \
2563 : DCHAR_T *memory; \
2564 : \
2565 : allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
2566 : if ((needed) > allocated) \
2567 : allocated = (needed); \
2568 : memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
2569 : if (size_overflow_p (memory_size)) \
2570 : oom_statement \
2571 : if (result == resultbuf) \
2572 : memory = (DCHAR_T *) malloc (memory_size); \
2573 : else \
2574 : memory = (DCHAR_T *) realloc (result, memory_size); \
2575 : if (memory == NULL) \
2576 : oom_statement \
2577 : if (result == resultbuf && length > 0) \
2578 : DCHAR_CPY (memory, result, length); \
2579 : result = memory; \
2580 : }
2581 : #define ENSURE_ALLOCATION(needed) \
2582 : ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; )
2583 :
2584 29798 : for (cp = format, di = 0, dp = &d.dir[0]; ; cp = dp->dir_end, di++, dp++)
2585 : {
2586 29798 : if (cp != dp->dir_start)
2587 : {
2588 4477 : size_t n = dp->dir_start - cp;
2589 4477 : size_t augmented_length = xsum (length, n);
2590 :
2591 4477 : 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 : if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
2596 : {
2597 4477 : DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
2598 4477 : length = augmented_length;
2599 : }
2600 : else
2601 : {
2602 : do
2603 : result[length++] = *cp++;
2604 : while (--n > 0);
2605 : }
2606 : }
2607 29798 : if (di == d.count)
2608 14391 : break;
2609 :
2610 : /* Execute a single directive. */
2611 15407 : if (dp->conversion == '%')
2612 : {
2613 : size_t augmented_length;
2614 :
2615 160 : if (!(dp->arg_index == ARG_NONE))
2616 0 : abort ();
2617 160 : augmented_length = xsum (length, 1);
2618 160 : ENSURE_ALLOCATION (augmented_length);
2619 160 : result[length] = '%';
2620 160 : length = augmented_length;
2621 : }
2622 : else
2623 : {
2624 15247 : if (!(dp->arg_index != ARG_NONE))
2625 0 : abort ();
2626 :
2627 15247 : if (dp->conversion == 'n')
2628 : {
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 : #endif
2677 : }
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 : #if !WIDE_CHAR_VERSION && (PTRDIFF_MAX > INT_MAX)
3069 15247 : else if (dp->conversion == 's'
3070 713 : && a.arg[dp->arg_index].type != TYPE_WIDE_STRING)
3071 713 : {
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 713 : int flags = dp->flags;
3077 : int has_width;
3078 : size_t width;
3079 : int has_precision;
3080 : size_t precision;
3081 :
3082 713 : has_width = 0;
3083 713 : width = 0;
3084 713 : if (dp->width_start != dp->width_end)
3085 : {
3086 0 : if (dp->width_arg_index != ARG_NONE)
3087 : {
3088 : 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 : {
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 : }
3101 : }
3102 : else
3103 : {
3104 0 : const FCHAR_T *digitp = dp->width_start;
3105 :
3106 : do
3107 0 : width = xsum (xtimes (width, 10), *digitp++ - '0');
3108 0 : while (digitp != dp->width_end);
3109 : }
3110 0 : if (width > (size_t) INT_MAX)
3111 0 : goto overflow;
3112 0 : has_width = 1;
3113 : }
3114 :
3115 713 : has_precision = 0;
3116 713 : precision = 6;
3117 713 : if (dp->precision_start != dp->precision_end)
3118 : {
3119 0 : if (dp->precision_arg_index != ARG_NONE)
3120 : {
3121 : 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 : {
3130 0 : precision = arg;
3131 0 : has_precision = 1;
3132 : }
3133 : }
3134 : else
3135 : {
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 : }
3143 : }
3144 :
3145 : {
3146 713 : const char *arg = a.arg[dp->arg_index].a.a_string;
3147 : 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 : size_t w;
3158 :
3159 713 : if (has_precision)
3160 : {
3161 : /* Use only at most PRECISION bytes, from the left. */
3162 0 : bytes = local_strnlen (arg, precision);
3163 : }
3164 : else
3165 : {
3166 : /* Use the entire string, and count the number of
3167 : bytes. */
3168 713 : bytes = strlen (arg);
3169 : }
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 713 : if (has_width)
3195 : {
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 : # endif
3210 : }
3211 : else
3212 : /* w doesn't matter. */
3213 713 : w = 0;
3214 :
3215 : {
3216 : # if DCHAR_IS_TCHAR
3217 713 : size_t total = bytes + (w < width ? width - w : 0);
3218 713 : 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 713 : if (w < width && !(flags & FLAG_LEFT))
3226 : {
3227 0 : size_t n = width - w;
3228 0 : DCHAR_SET (result + length, ' ', n);
3229 0 : length += n;
3230 : }
3231 :
3232 : # if DCHAR_IS_TCHAR
3233 713 : memcpy (result + length, arg, bytes);
3234 713 : length += bytes;
3235 : # else
3236 : DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3237 : free (tmpdst);
3238 : length += tmpdst_len;
3239 : # endif
3240 :
3241 713 : if (w < width && (flags & FLAG_LEFT))
3242 : {
3243 0 : size_t n = width - w;
3244 0 : DCHAR_SET (result + length, ' ', n);
3245 0 : length += n;
3246 : }
3247 : }
3248 : }
3249 : }
3250 : #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 : #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 14534 : 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 : # endif
3403 : )
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 : int has_width;
3417 : size_t width;
3418 : int has_precision;
3419 : size_t precision;
3420 :
3421 0 : has_width = 0;
3422 0 : width = 0;
3423 0 : if (dp->width_start != dp->width_end)
3424 : {
3425 0 : if (dp->width_arg_index != ARG_NONE)
3426 : {
3427 : 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 : {
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 : }
3440 : }
3441 : else
3442 : {
3443 0 : const FCHAR_T *digitp = dp->width_start;
3444 :
3445 : do
3446 0 : width = xsum (xtimes (width, 10), *digitp++ - '0');
3447 0 : while (digitp != dp->width_end);
3448 : }
3449 0 : if (width > (size_t) INT_MAX)
3450 0 : goto overflow;
3451 0 : has_width = 1;
3452 : }
3453 :
3454 0 : has_precision = 0;
3455 0 : precision = 6;
3456 0 : if (dp->precision_start != dp->precision_end)
3457 : {
3458 0 : if (dp->precision_arg_index != ARG_NONE)
3459 : {
3460 : 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 : {
3469 0 : precision = arg;
3470 0 : has_precision = 1;
3471 : }
3472 : }
3473 : else
3474 : {
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 : }
3482 : }
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 : {
3629 0 : const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
3630 : const wchar_t *arg_end;
3631 : 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 : size_t w;
3642 :
3643 0 : if (has_precision)
3644 : {
3645 : /* Use only as many wide characters as needed to produce
3646 : at most PRECISION bytes, from the left. */
3647 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3648 : mbstate_t state;
3649 0 : mbszero (&state);
3650 : # 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 : {
3658 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3659 : 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 : }
3677 : }
3678 : # if DCHAR_IS_TCHAR
3679 0 : else if (has_width)
3680 : # else
3681 : else
3682 : # endif
3683 : {
3684 : /* Use the entire string, and count the number of
3685 : bytes. */
3686 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3687 : mbstate_t state;
3688 0 : mbszero (&state);
3689 : # endif
3690 0 : arg_end = arg;
3691 0 : bytes = 0;
3692 : # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
3693 : characters = 0;
3694 : # endif
3695 : for (;;)
3696 0 : {
3697 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3698 : 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 : }
3713 : }
3714 : # if DCHAR_IS_TCHAR
3715 : else
3716 : {
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 : }
3726 : # 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 : {
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 : # endif
3795 : }
3796 : else
3797 : /* w doesn't matter. */
3798 0 : w = 0;
3799 :
3800 0 : if (w < width && !(flags & FLAG_LEFT))
3801 : {
3802 0 : size_t n = width - w;
3803 : # 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 : }
3812 :
3813 : # if DCHAR_IS_TCHAR
3814 0 : if (has_precision || has_width)
3815 0 : {
3816 : /* We know the number of bytes in advance. */
3817 : size_t remaining;
3818 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3819 : mbstate_t state;
3820 0 : mbszero (&state);
3821 : # endif
3822 0 : ENSURE_ALLOCATION (xsum (length, bytes));
3823 0 : for (remaining = bytes; remaining > 0; )
3824 : {
3825 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3826 : 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 : }
3839 0 : if (!(arg == arg_end))
3840 0 : abort ();
3841 : }
3842 : else
3843 : {
3844 : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3845 : mbstate_t state;
3846 0 : mbszero (&state);
3847 : # endif
3848 0 : while (arg < arg_end)
3849 : {
3850 : char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3851 : 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 : }
3864 : }
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 : {
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 : }
3880 : }
3881 : # endif
3882 : }
3883 : #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 : #if NEED_PRINTF_DIRECTIVE_B || NEED_PRINTF_DIRECTIVE_UPPERCASE_B
4174 14534 : else if (0
4175 : # if NEED_PRINTF_DIRECTIVE_B
4176 14534 : || (dp->conversion == 'b')
4177 : # endif
4178 : # if NEED_PRINTF_DIRECTIVE_UPPERCASE_B
4179 : || (dp->conversion == 'B')
4180 : # endif
4181 : )
4182 : {
4183 0 : arg_type type = a.arg[dp->arg_index].type;
4184 0 : int flags = dp->flags;
4185 : int has_width;
4186 : size_t width;
4187 : int has_precision;
4188 : size_t precision;
4189 : size_t tmp_length;
4190 : size_t count;
4191 : DCHAR_T tmpbuf[700];
4192 : DCHAR_T *tmp;
4193 : DCHAR_T *tmp_end;
4194 : DCHAR_T *tmp_start;
4195 : DCHAR_T *pad_ptr;
4196 : DCHAR_T *p;
4197 :
4198 0 : has_width = 0;
4199 0 : width = 0;
4200 0 : if (dp->width_start != dp->width_end)
4201 : {
4202 0 : if (dp->width_arg_index != ARG_NONE)
4203 : {
4204 : 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 : {
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 : }
4217 : }
4218 : else
4219 : {
4220 0 : const FCHAR_T *digitp = dp->width_start;
4221 :
4222 : do
4223 0 : width = xsum (xtimes (width, 10), *digitp++ - '0');
4224 0 : while (digitp != dp->width_end);
4225 : }
4226 0 : if (width > (size_t) INT_MAX)
4227 0 : goto overflow;
4228 0 : has_width = 1;
4229 : }
4230 :
4231 0 : has_precision = 0;
4232 0 : precision = 1;
4233 0 : if (dp->precision_start != dp->precision_end)
4234 : {
4235 0 : if (dp->precision_arg_index != ARG_NONE)
4236 : {
4237 : 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 : {
4246 0 : precision = arg;
4247 0 : has_precision = 1;
4248 : }
4249 : }
4250 : else
4251 : {
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 : }
4259 : }
4260 :
4261 : /* Allocate a temporary buffer of sufficient size. */
4262 0 : switch (type)
4263 : {
4264 0 : default:
4265 0 : tmp_length =
4266 : (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
4267 : + 1; /* turn floor into ceil */
4268 0 : break;
4269 0 : case TYPE_ULONGINT:
4270 0 : tmp_length =
4271 : (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
4272 : + 1; /* turn floor into ceil */
4273 0 : break;
4274 0 : case TYPE_ULONGLONGINT:
4275 0 : tmp_length =
4276 : (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
4277 : + 1; /* turn floor into ceil */
4278 0 : break;
4279 0 : case TYPE_UINT8_T:
4280 0 : tmp_length =
4281 : (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
4282 : + 1; /* turn floor into ceil */
4283 0 : break;
4284 0 : case TYPE_UINT16_T:
4285 0 : tmp_length =
4286 : (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
4287 : + 1; /* turn floor into ceil */
4288 0 : break;
4289 0 : case TYPE_UINT32_T:
4290 0 : tmp_length =
4291 : (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
4292 : + 1; /* turn floor into ceil */
4293 0 : break;
4294 0 : case TYPE_UINT64_T:
4295 0 : tmp_length =
4296 : (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
4297 : + 1; /* turn floor into ceil */
4298 0 : break;
4299 0 : case TYPE_UINT_FAST8_T:
4300 0 : tmp_length =
4301 : (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
4302 : + 1; /* turn floor into ceil */
4303 0 : break;
4304 0 : case TYPE_UINT_FAST16_T:
4305 0 : tmp_length =
4306 : (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
4307 : + 1; /* turn floor into ceil */
4308 0 : break;
4309 0 : case TYPE_UINT_FAST32_T:
4310 0 : tmp_length =
4311 : (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
4312 : + 1; /* turn floor into ceil */
4313 0 : break;
4314 0 : case TYPE_UINT_FAST64_T:
4315 0 : tmp_length =
4316 : (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
4317 : + 1; /* turn floor into ceil */
4318 0 : break;
4319 : }
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 : else
4331 : {
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 : }
4342 :
4343 0 : tmp_end = tmp + tmp_length;
4344 :
4345 : unsigned long long arg;
4346 0 : switch (type)
4347 : {
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 : }
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 : {
4397 : do
4398 : {
4399 0 : *--p = '0' + (arg & 1);
4400 0 : arg = arg >> 1;
4401 : }
4402 0 : while (arg != 0);
4403 : }
4404 :
4405 0 : if (has_precision)
4406 : {
4407 0 : DCHAR_T *digits_start = tmp_end - precision;
4408 0 : while (p > digits_start)
4409 0 : *--p = '0';
4410 : }
4411 :
4412 0 : pad_ptr = p;
4413 :
4414 0 : if (need_prefix)
4415 : {
4416 : # 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 : }
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 : {
4434 0 : size_t pad = width - count;
4435 :
4436 0 : if (flags & FLAG_LEFT)
4437 : {
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 : }
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 : {
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 : }
4457 : else
4458 : {
4459 : /* Pad with spaces on the left. */
4460 0 : for (p = tmp_start - pad; p < tmp_start; p++)
4461 0 : *p = ' ';
4462 : }
4463 :
4464 0 : tmp_start = tmp_start - pad;
4465 : }
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 : {
4477 0 : size_t n = xsum (length, count);
4478 :
4479 0 : ENSURE_ALLOCATION_ELSE (n,
4480 : { if (tmp != tmpbuf) free (tmp); goto out_of_memory; });
4481 : }
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 : }
4489 : #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 : else
6473 : {
6474 14534 : arg_type type = a.arg[dp->arg_index].type;
6475 14534 : 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 : # define prec_ourselves 0
6490 : #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 : # define group_ourselves 0
6495 : #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 : # define pad_ourselves 0
6502 : #endif
6503 : TCHAR_T *fbp;
6504 : unsigned int prefix_count;
6505 : int prefixes[2] IF_LINT (= { 0 });
6506 : 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
6652 : /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
6653 : to perform the padding after this conversion. Functions
6654 : with unistdio extensions perform the padding based on
6655 : character count rather than element count. */
6656 : case 'c': case 's':
6657 : # endif
6658 : # if NEED_PRINTF_FLAG_ZERO
6659 : case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
6660 : case 'a': case 'A':
6661 : # endif
6662 : pad_ourselves = 1;
6663 : break;
6664 : default:
6665 : pad_ourselves = prec_ourselves | group_ourselves;
6666 : break;
6667 : }
6668 : #endif
6669 :
6670 : #if !USE_SNPRINTF
6671 : /* Allocate a temporary buffer of sufficient size for calling
6672 : sprintf. */
6673 : tmp_length =
6674 : MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
6675 : flags, width, has_precision, precision,
6676 : pad_ourselves);
6677 :
6678 : if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
6679 : tmp = tmpbuf;
6680 : else
6681 : {
6682 : size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
6683 :
6684 : if (size_overflow_p (tmp_memsize))
6685 : /* Overflow, would lead to out of memory. */
6686 : goto out_of_memory;
6687 : tmp = (TCHAR_T *) malloc (tmp_memsize);
6688 : if (tmp == NULL)
6689 : /* Out of memory. */
6690 : goto out_of_memory;
6691 : }
6692 : #endif
6693 :
6694 : /* Construct the format string for calling snprintf or
6695 : sprintf. */
6696 14534 : fbp = buf;
6697 14534 : *fbp++ = '%';
6698 14534 : if ((flags & FLAG_GROUP) && !group_ourselves)
6699 0 : *fbp++ = '\'';
6700 14534 : if (flags & FLAG_LEFT)
6701 0 : *fbp++ = '-';
6702 14534 : if (flags & FLAG_SHOWSIGN)
6703 0 : *fbp++ = '+';
6704 14534 : if (flags & FLAG_SPACE)
6705 0 : *fbp++ = ' ';
6706 14534 : if (flags & FLAG_ALT)
6707 0 : *fbp++ = '#';
6708 : #if __GLIBC__ >= 2 && !defined __UCLIBC__
6709 14534 : if (flags & FLAG_LOCALIZED)
6710 0 : *fbp++ = 'I';
6711 : #endif
6712 : if (!pad_ourselves)
6713 : {
6714 14534 : if (flags & FLAG_ZERO)
6715 13625 : *fbp++ = '0';
6716 14534 : if (dp->width_start != dp->width_end)
6717 : {
6718 13625 : size_t n = dp->width_end - dp->width_start;
6719 : #if !WIDTH_IS_CHECKED
6720 : size_t width;
6721 : /* Reject an out-of-range width.
6722 : The underlying SNPRINTF already does this on some
6723 : platforms (glibc, musl, macOS, FreeBSD, NetBSD,
6724 : OpenBSD, Cygwin, Solaris, MSVC). However, on others
6725 : (AIX, mingw), it doesn't; thus this vasnprintf
6726 : invocation would succeed and produce a wrong result.
6727 : So, this is redundant on some platforms, but it's a
6728 : quick check anyway. */
6729 13625 : if (dp->width_arg_index != ARG_NONE)
6730 : {
6731 : int arg;
6732 :
6733 0 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
6734 0 : abort ();
6735 0 : arg = a.arg[dp->width_arg_index].a.a_int;
6736 0 : width = arg;
6737 0 : if (arg < 0)
6738 : {
6739 : /* "A negative field width is taken as a '-' flag
6740 : followed by a positive field width." */
6741 0 : width = -width;
6742 : }
6743 : }
6744 : else
6745 : {
6746 13625 : const FCHAR_T *digitp = dp->width_start;
6747 :
6748 13625 : width = 0;
6749 : do
6750 13625 : width = xsum (xtimes (width, 10), *digitp++ - '0');
6751 13625 : while (digitp != dp->width_end);
6752 : }
6753 13625 : if (width > (size_t) INT_MAX)
6754 0 : goto overflow;
6755 : #endif
6756 : /* The width specification is known to consist only
6757 : of standard ASCII characters. */
6758 : if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
6759 : {
6760 13625 : memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
6761 13625 : fbp += n;
6762 : }
6763 : else
6764 : {
6765 : const FCHAR_T *mp = dp->width_start;
6766 : do
6767 : *fbp++ = *mp++;
6768 : while (--n > 0);
6769 : }
6770 : }
6771 : }
6772 : if (!prec_ourselves)
6773 : {
6774 14534 : if (dp->precision_start != dp->precision_end)
6775 : {
6776 10 : size_t n = dp->precision_end - dp->precision_start;
6777 : /* The precision specification is known to consist only
6778 : of standard ASCII characters. */
6779 : if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
6780 : {
6781 10 : memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
6782 10 : fbp += n;
6783 : }
6784 : else
6785 : {
6786 : const FCHAR_T *mp = dp->precision_start;
6787 : do
6788 : *fbp++ = *mp++;
6789 : while (--n > 0);
6790 : }
6791 : }
6792 : }
6793 :
6794 14534 : switch (+type)
6795 : {
6796 0 : case TYPE_LONGLONGINT:
6797 : case TYPE_ULONGLONGINT:
6798 : #if INT8_WIDTH > LONG_WIDTH
6799 : case TYPE_INT8_T:
6800 : #endif
6801 : #if UINT8_WIDTH > LONG_WIDTH
6802 : case TYPE_UINT8_T:
6803 : #endif
6804 : #if INT16_WIDTH > LONG_WIDTH
6805 : case TYPE_INT16_T:
6806 : #endif
6807 : #if UINT16_WIDTH > LONG_WIDTH
6808 : case TYPE_UINT16_T:
6809 : #endif
6810 : #if INT32_WIDTH > LONG_WIDTH
6811 : case TYPE_INT32_T:
6812 : #endif
6813 : #if UINT32_WIDTH > LONG_WIDTH
6814 : case TYPE_UINT32_T:
6815 : #endif
6816 : #if INT64_WIDTH > LONG_WIDTH
6817 : case TYPE_INT64_T:
6818 : #endif
6819 : #if UINT64_WIDTH > LONG_WIDTH
6820 : case TYPE_UINT64_T:
6821 : #endif
6822 : #if INT_FAST8_WIDTH > LONG_WIDTH
6823 : case TYPE_INT_FAST8_T:
6824 : #endif
6825 : #if UINT_FAST8_WIDTH > LONG_WIDTH
6826 : case TYPE_UINT_FAST8_T:
6827 : #endif
6828 : #if INT_FAST16_WIDTH > LONG_WIDTH
6829 : case TYPE_INT_FAST16_T:
6830 : #endif
6831 : #if UINT_FAST16_WIDTH > LONG_WIDTH
6832 : case TYPE_UINT_FAST16_T:
6833 : #endif
6834 : #if INT_FAST32_WIDTH > LONG_WIDTH
6835 : case TYPE_INT3_FAST2_T:
6836 : #endif
6837 : #if UINT_FAST32_WIDTH > LONG_WIDTH
6838 : case TYPE_UINT_FAST32_T:
6839 : #endif
6840 : #if INT_FAST64_WIDTH > LONG_WIDTH
6841 : case TYPE_INT_FAST64_T:
6842 : #endif
6843 : #if UINT_FAST64_WIDTH > LONG_WIDTH
6844 : case TYPE_UINT_FAST64_T:
6845 : #endif
6846 : #if defined _WIN32 && ! defined __CYGWIN__
6847 : *fbp++ = 'I';
6848 : *fbp++ = '6';
6849 : *fbp++ = '4';
6850 : break;
6851 : #else
6852 0 : *fbp++ = 'l';
6853 : #endif
6854 : FALLTHROUGH;
6855 0 : case TYPE_LONGINT:
6856 : case TYPE_ULONGINT:
6857 : #if INT8_WIDTH > INT_WIDTH && INT8_WIDTH <= LONG_WIDTH
6858 : case TYPE_INT8_T:
6859 : #endif
6860 : #if UINT8_WIDTH > INT_WIDTH && UINT8_WIDTH <= LONG_WIDTH
6861 : case TYPE_UINT8_T:
6862 : #endif
6863 : #if INT16_WIDTH > INT_WIDTH && INT16_WIDTH <= LONG_WIDTH
6864 : case TYPE_INT16_T:
6865 : #endif
6866 : #if UINT16_WIDTH > INT_WIDTH && UINT16_WIDTH <= LONG_WIDTH
6867 : case TYPE_UINT16_T:
6868 : #endif
6869 : #if INT32_WIDTH > INT_WIDTH && INT32_WIDTH <= LONG_WIDTH
6870 : case TYPE_INT32_T:
6871 : #endif
6872 : #if UINT32_WIDTH > INT_WIDTH && UINT32_WIDTH <= LONG_WIDTH
6873 : case TYPE_UINT32_T:
6874 : #endif
6875 : #if INT64_WIDTH > INT_WIDTH && INT64_WIDTH <= LONG_WIDTH
6876 : case TYPE_INT64_T:
6877 : #endif
6878 : #if UINT64_WIDTH > INT_WIDTH && UINT64_WIDTH <= LONG_WIDTH
6879 : case TYPE_UINT64_T:
6880 : #endif
6881 : #if INT_FAST8_WIDTH > INT_WIDTH && INT_FAST8_WIDTH <= LONG_WIDTH
6882 : case TYPE_INT_FAST8_T:
6883 : #endif
6884 : #if UINT_FAST8_WIDTH > INT_WIDTH && UINT_FAST8_WIDTH <= LONG_WIDTH
6885 : case TYPE_UINT_FAST8_T:
6886 : #endif
6887 : #if INT_FAST16_WIDTH > INT_WIDTH && INT_FAST16_WIDTH <= LONG_WIDTH
6888 : case TYPE_INT_FAST16_T:
6889 : #endif
6890 : #if UINT_FAST16_WIDTH > INT_WIDTH && UINT_FAST16_WIDTH <= LONG_WIDTH
6891 : case TYPE_UINT_FAST16_T:
6892 : #endif
6893 : #if INT_FAST32_WIDTH > INT_WIDTH && INT_FAST32_WIDTH <= LONG_WIDTH
6894 : case TYPE_INT_FAST32_T:
6895 : #endif
6896 : #if UINT_FAST32_WIDTH > INT_WIDTH && UINT_FAST32_WIDTH <= LONG_WIDTH
6897 : case TYPE_UINT_FAST32_T:
6898 : #endif
6899 : #if INT_FAST64_WIDTH > INT_WIDTH && INT_FAST64_WIDTH <= LONG_WIDTH
6900 : case TYPE_INT_FAST64_T:
6901 : #endif
6902 : #if UINT_FAST64_WIDTH > INT_WIDTH && UINT_FAST64_WIDTH <= LONG_WIDTH
6903 : case TYPE_UINT_FAST64_T:
6904 : #endif
6905 : #if HAVE_WINT_T
6906 : case TYPE_WIDE_CHAR:
6907 : #endif
6908 : case TYPE_WIDE_STRING:
6909 0 : *fbp++ = 'l';
6910 0 : break;
6911 0 : case TYPE_LONGDOUBLE:
6912 0 : *fbp++ = 'L';
6913 0 : break;
6914 14534 : default:
6915 14534 : break;
6916 : }
6917 : #if NEED_PRINTF_DIRECTIVE_F
6918 : if (dp->conversion == 'F')
6919 : *fbp = 'f';
6920 : else
6921 : #endif
6922 14534 : *fbp = dp->conversion;
6923 : #if USE_SNPRINTF
6924 : /* Decide whether to pass %n in the format string
6925 : to SNPRINTF. */
6926 : # if (((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR) \
6927 : && (HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99)) \
6928 : || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
6929 : && !defined __UCLIBC__) \
6930 : || (defined __APPLE__ && defined __MACH__) \
6931 : || defined __OpenBSD__ \
6932 : || defined __ANDROID__ \
6933 : || (defined _WIN32 && ! defined __CYGWIN__)) \
6934 : || (WIDE_CHAR_VERSION && MUSL_LIBC)
6935 : /* We can avoid passing %n and instead rely on SNPRINTF's
6936 : return value if
6937 : - !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR, because otherwise,
6938 : when WIDE_CHAR_VERSION && DCHAR_IS_TCHAR,
6939 : snwprintf()/_snwprintf() (Windows) and swprintf() (Unix)
6940 : don't return the needed buffer size,
6941 : and
6942 : - we're compiling for a system where we know
6943 : - that snprintf's return value conforms to ISO C 99
6944 : (HAVE_SNPRINTF_RETVAL_C99) and
6945 : - that snprintf always produces NUL-terminated strings
6946 : (HAVE_SNPRINTF_TRUNCATION_C99).
6947 : And it is desirable to do so, because more and more platforms
6948 : no longer support %n, for "security reasons". */
6949 : /* On specific platforms, listed below, we *must* avoid %n.
6950 : In the case
6951 : !WIDE_CHAR_VERSION && HAVE_SNPRINTF_RETVAL_C99 && !USE_MSVC__SNPRINTF
6952 : we can rely on the return value of snprintf instead. Whereas
6953 : in the opposite case
6954 : WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
6955 : we need to make room based on an estimation, computed by
6956 : MAX_ROOM_NEEDED. */
6957 : /* The following platforms forbid %n:
6958 : - On glibc2 systems from 2004-10-18 or newer, the use of
6959 : %n in format strings in writable memory may crash the
6960 : program (if compiled with _FORTIFY_SOURCE=2).
6961 : - On macOS 10.13 or newer, the use of %n in format
6962 : strings in writable memory by default crashes the
6963 : program.
6964 : - On OpenBSD, since 2021-08-30, the use of %n in format
6965 : strings produces an abort (see
6966 : <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfprintf.c.diff?r1=1.79&r2=1.80&f=h>,
6967 : <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfwprintf.c.diff?r1=1.20&r2=1.21&f=h>).
6968 : - On Android, starting on 2018-03-07, the use of %n in
6969 : format strings produces a fatal error (see
6970 : <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
6971 : - On native Windows systems (such as mingw) where the OS is
6972 : Windows Vista, the use of %n in format strings by default
6973 : crashes the program. See
6974 : <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
6975 : <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
6976 : On the first four of these platforms, if !WIDE_CHAR_VERSION,
6977 : it is not a big deal to avoid %n, because on these platforms,
6978 : HAVE_SNPRINTF_RETVAL_C99 and HAVE_SNPRINTF_TRUNCATION_C99 are
6979 : 1.
6980 : On native Windows, if !WIDE_CHAR_VERSION, it's not a big deal
6981 : either because:
6982 : - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
6983 : snprintf does not write more than the specified number
6984 : of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
6985 : '4', '5', '6' into buf, not '4', '5', '\0'.)
6986 : - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
6987 : allows us to recognize the case of an insufficient
6988 : buffer size: it returns -1 in this case. */
6989 : /* Additionally, in the WIDE_CHAR_VERSION case, we cannot use %n
6990 : on musl libc because we would run into an swprintf() bug.
6991 : See <https://www.openwall.com/lists/musl/2023/03/19/1>. */
6992 14534 : fbp[1] = '\0';
6993 : # else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
6994 : fbp[1] = '%';
6995 : fbp[2] = 'n';
6996 : fbp[3] = '\0';
6997 : # endif
6998 : #else
6999 : fbp[1] = '\0';
7000 : #endif
7001 :
7002 : /* Construct the arguments for calling snprintf or sprintf. */
7003 14534 : prefix_count = 0;
7004 14534 : if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
7005 : {
7006 0 : if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
7007 0 : abort ();
7008 0 : prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
7009 : }
7010 14534 : if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
7011 : {
7012 0 : if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
7013 0 : abort ();
7014 0 : prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
7015 : }
7016 :
7017 : #if USE_SNPRINTF
7018 : /* The SNPRINTF result is appended after result[0..length].
7019 : The latter is an array of DCHAR_T; SNPRINTF appends an
7020 : array of TCHAR_T to it. This is possible because
7021 : sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
7022 : alignof (TCHAR_T) <= alignof (DCHAR_T). */
7023 : # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
7024 : /* Ensure that maxlen below will be >= 2. Needed on BeOS,
7025 : where an snprintf() with maxlen==1 acts like sprintf(). */
7026 14534 : ENSURE_ALLOCATION (xsum (length,
7027 : (2 + TCHARS_PER_DCHAR - 1)
7028 : / TCHARS_PER_DCHAR));
7029 : /* Prepare checking whether snprintf returns the count
7030 : via %n. */
7031 14534 : *(TCHAR_T *) (result + length) = '\0';
7032 : #endif
7033 :
7034 14534 : orig_errno = errno;
7035 :
7036 : for (;;)
7037 0 : {
7038 14534 : int count = -1;
7039 :
7040 : #if USE_SNPRINTF
7041 14534 : int retcount = 0;
7042 14534 : size_t maxlen = allocated - length;
7043 : /* SNPRINTF can fail if its second argument is
7044 : > INT_MAX. */
7045 14534 : if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
7046 0 : maxlen = INT_MAX / TCHARS_PER_DCHAR;
7047 14534 : maxlen = maxlen * TCHARS_PER_DCHAR;
7048 : # define SNPRINTF_BUF(arg) \
7049 : switch (prefix_count) \
7050 : { \
7051 : case 0: \
7052 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
7053 : maxlen, buf, \
7054 : arg, &count); \
7055 : break; \
7056 : case 1: \
7057 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
7058 : maxlen, buf, \
7059 : prefixes[0], arg, &count); \
7060 : break; \
7061 : case 2: \
7062 : retcount = SNPRINTF ((TCHAR_T *) (result + length), \
7063 : maxlen, buf, \
7064 : prefixes[0], prefixes[1], arg, \
7065 : &count); \
7066 : break; \
7067 : default: \
7068 : abort (); \
7069 : }
7070 : #else
7071 : # define SNPRINTF_BUF(arg) \
7072 : switch (prefix_count) \
7073 : { \
7074 : case 0: \
7075 : count = sprintf (tmp, buf, arg); \
7076 : break; \
7077 : case 1: \
7078 : count = sprintf (tmp, buf, prefixes[0], arg); \
7079 : break; \
7080 : case 2: \
7081 : count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
7082 : arg); \
7083 : break; \
7084 : default: \
7085 : abort (); \
7086 : }
7087 : #endif
7088 :
7089 14534 : errno = 0;
7090 14534 : switch (+type)
7091 : {
7092 0 : case TYPE_SCHAR:
7093 : {
7094 0 : int arg = a.arg[dp->arg_index].a.a_schar;
7095 0 : SNPRINTF_BUF (arg);
7096 : }
7097 0 : break;
7098 0 : case TYPE_UCHAR:
7099 : {
7100 0 : unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
7101 0 : SNPRINTF_BUF (arg);
7102 : }
7103 0 : break;
7104 0 : case TYPE_SHORT:
7105 : {
7106 0 : int arg = a.arg[dp->arg_index].a.a_short;
7107 0 : SNPRINTF_BUF (arg);
7108 : }
7109 0 : break;
7110 0 : case TYPE_USHORT:
7111 : {
7112 0 : unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
7113 0 : SNPRINTF_BUF (arg);
7114 : }
7115 0 : break;
7116 755 : case TYPE_INT:
7117 : {
7118 755 : int arg = a.arg[dp->arg_index].a.a_int;
7119 755 : SNPRINTF_BUF (arg);
7120 : }
7121 755 : break;
7122 13705 : case TYPE_UINT:
7123 : {
7124 13705 : unsigned int arg = a.arg[dp->arg_index].a.a_uint;
7125 13705 : SNPRINTF_BUF (arg);
7126 : }
7127 13705 : break;
7128 0 : case TYPE_LONGINT:
7129 : {
7130 0 : long int arg = a.arg[dp->arg_index].a.a_longint;
7131 0 : SNPRINTF_BUF (arg);
7132 : }
7133 0 : break;
7134 0 : case TYPE_ULONGINT:
7135 : {
7136 0 : unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
7137 0 : SNPRINTF_BUF (arg);
7138 : }
7139 0 : break;
7140 0 : case TYPE_LONGLONGINT:
7141 : {
7142 0 : long long int arg = a.arg[dp->arg_index].a.a_longlongint;
7143 0 : SNPRINTF_BUF (arg);
7144 : }
7145 0 : break;
7146 0 : case TYPE_ULONGLONGINT:
7147 : {
7148 0 : unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
7149 0 : SNPRINTF_BUF (arg);
7150 : }
7151 0 : break;
7152 0 : case TYPE_INT8_T:
7153 : {
7154 0 : int8_t arg = a.arg[dp->arg_index].a.a_int8_t;
7155 0 : SNPRINTF_BUF (arg);
7156 : }
7157 0 : break;
7158 0 : case TYPE_UINT8_T:
7159 : {
7160 0 : uint8_t arg = a.arg[dp->arg_index].a.a_uint8_t;
7161 0 : SNPRINTF_BUF (arg);
7162 : }
7163 0 : break;
7164 0 : case TYPE_INT16_T:
7165 : {
7166 0 : int16_t arg = a.arg[dp->arg_index].a.a_int16_t;
7167 0 : SNPRINTF_BUF (arg);
7168 : }
7169 0 : break;
7170 0 : case TYPE_UINT16_T:
7171 : {
7172 0 : uint16_t arg = a.arg[dp->arg_index].a.a_uint16_t;
7173 0 : SNPRINTF_BUF (arg);
7174 : }
7175 0 : break;
7176 0 : case TYPE_INT32_T:
7177 : {
7178 0 : int32_t arg = a.arg[dp->arg_index].a.a_int32_t;
7179 0 : SNPRINTF_BUF (arg);
7180 : }
7181 0 : break;
7182 0 : case TYPE_UINT32_T:
7183 : {
7184 0 : uint32_t arg = a.arg[dp->arg_index].a.a_uint32_t;
7185 0 : SNPRINTF_BUF (arg);
7186 : }
7187 0 : break;
7188 0 : case TYPE_INT64_T:
7189 : {
7190 0 : int64_t arg = a.arg[dp->arg_index].a.a_int64_t;
7191 0 : SNPRINTF_BUF (arg);
7192 : }
7193 0 : break;
7194 0 : case TYPE_UINT64_T:
7195 : {
7196 0 : uint64_t arg = a.arg[dp->arg_index].a.a_uint64_t;
7197 0 : SNPRINTF_BUF (arg);
7198 : }
7199 0 : break;
7200 0 : case TYPE_INT_FAST8_T:
7201 : {
7202 0 : int_fast8_t arg = a.arg[dp->arg_index].a.a_int_fast8_t;
7203 0 : SNPRINTF_BUF (arg);
7204 : }
7205 0 : break;
7206 0 : case TYPE_UINT_FAST8_T:
7207 : {
7208 0 : uint_fast8_t arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
7209 0 : SNPRINTF_BUF (arg);
7210 : }
7211 0 : break;
7212 0 : case TYPE_INT_FAST16_T:
7213 : {
7214 0 : int_fast16_t arg = a.arg[dp->arg_index].a.a_int_fast16_t;
7215 0 : SNPRINTF_BUF (arg);
7216 : }
7217 0 : break;
7218 0 : case TYPE_UINT_FAST16_T:
7219 : {
7220 0 : uint_fast16_t arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
7221 0 : SNPRINTF_BUF (arg);
7222 : }
7223 0 : break;
7224 0 : case TYPE_INT_FAST32_T:
7225 : {
7226 0 : int_fast32_t arg = a.arg[dp->arg_index].a.a_int_fast32_t;
7227 0 : SNPRINTF_BUF (arg);
7228 : }
7229 0 : break;
7230 0 : case TYPE_UINT_FAST32_T:
7231 : {
7232 0 : uint_fast32_t arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
7233 0 : SNPRINTF_BUF (arg);
7234 : }
7235 0 : break;
7236 0 : case TYPE_INT_FAST64_T:
7237 : {
7238 0 : int_fast64_t arg = a.arg[dp->arg_index].a.a_int_fast64_t;
7239 0 : SNPRINTF_BUF (arg);
7240 : }
7241 0 : break;
7242 0 : case TYPE_UINT_FAST64_T:
7243 : {
7244 0 : uint_fast64_t arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
7245 0 : SNPRINTF_BUF (arg);
7246 : }
7247 0 : break;
7248 43 : case TYPE_DOUBLE:
7249 : {
7250 43 : double arg = a.arg[dp->arg_index].a.a_double;
7251 43 : SNPRINTF_BUF (arg);
7252 : }
7253 43 : break;
7254 0 : case TYPE_LONGDOUBLE:
7255 : {
7256 0 : long double arg = a.arg[dp->arg_index].a.a_longdouble;
7257 0 : SNPRINTF_BUF (arg);
7258 : }
7259 0 : break;
7260 31 : case TYPE_CHAR:
7261 : {
7262 31 : int arg = a.arg[dp->arg_index].a.a_char;
7263 31 : SNPRINTF_BUF (arg);
7264 : }
7265 31 : break;
7266 : #if HAVE_WINT_T
7267 0 : case TYPE_WIDE_CHAR:
7268 : {
7269 0 : wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
7270 0 : SNPRINTF_BUF (arg);
7271 : }
7272 0 : break;
7273 : #endif
7274 0 : case TYPE_STRING:
7275 : {
7276 0 : const char *arg = a.arg[dp->arg_index].a.a_string;
7277 0 : SNPRINTF_BUF (arg);
7278 : }
7279 0 : break;
7280 0 : case TYPE_WIDE_STRING:
7281 : {
7282 0 : const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
7283 0 : SNPRINTF_BUF (arg);
7284 : }
7285 0 : break;
7286 0 : case TYPE_POINTER:
7287 : {
7288 0 : void *arg = a.arg[dp->arg_index].a.a_pointer;
7289 0 : SNPRINTF_BUF (arg);
7290 : }
7291 0 : break;
7292 0 : default:
7293 0 : abort ();
7294 : }
7295 :
7296 : #if USE_SNPRINTF
7297 : /* Portability: Not all implementations of snprintf()
7298 : are ISO C 99 compliant. Determine the number of
7299 : bytes that snprintf() has produced or would have
7300 : produced. */
7301 14534 : if (count >= 0)
7302 : {
7303 : /* Verify that snprintf() has NUL-terminated its
7304 : result. */
7305 0 : if ((unsigned int) count < maxlen
7306 0 : && ((TCHAR_T *) (result + length)) [count] != '\0')
7307 0 : abort ();
7308 : /* Portability hack. */
7309 0 : if (retcount > count)
7310 0 : count = retcount;
7311 : }
7312 : else
7313 : {
7314 : /* snprintf() doesn't understand the '%n'
7315 : directive. */
7316 14534 : if (fbp[1] != '\0')
7317 : {
7318 : /* Don't use the '%n' directive; instead, look
7319 : at the snprintf() return value. */
7320 0 : fbp[1] = '\0';
7321 0 : continue;
7322 : }
7323 : else
7324 : {
7325 : /* Look at the snprintf() return value. */
7326 14534 : if (retcount < 0)
7327 : {
7328 : # if (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
7329 : /* HP-UX 10.20 snprintf() is doubly deficient:
7330 : It doesn't understand the '%n' directive,
7331 : *and* it returns -1 (rather than the length
7332 : that would have been required) when the
7333 : buffer is too small.
7334 : Likewise, in case of
7335 : WIDE_CHAR_VERSION && DCHAR_IS_TCHAR, the
7336 : functions snwprintf()/_snwprintf() (Windows)
7337 : or swprintf() (Unix).
7338 : But a failure at this point can also come
7339 : from other reasons than a too small buffer,
7340 : such as an invalid wide string argument to
7341 : the %ls directive, or possibly an invalid
7342 : floating-point argument. */
7343 : size_t tmp_length =
7344 : MAX_ROOM_NEEDED (&a, dp->arg_index,
7345 : dp->conversion, type, flags,
7346 : width,
7347 : has_precision,
7348 : precision, pad_ourselves);
7349 :
7350 : if (maxlen < tmp_length)
7351 : {
7352 : /* Make more room. But try to do through
7353 : this reallocation only once. */
7354 : size_t bigger_need =
7355 : xsum (length,
7356 : xsum (tmp_length,
7357 : TCHARS_PER_DCHAR - 1)
7358 : / TCHARS_PER_DCHAR);
7359 : /* And always grow proportionally.
7360 : (There may be several arguments, each
7361 : needing a little more room than the
7362 : previous one.) */
7363 : size_t bigger_need2 =
7364 : xsum (xtimes (allocated, 2), 12);
7365 : if (bigger_need < bigger_need2)
7366 : bigger_need = bigger_need2;
7367 : ENSURE_ALLOCATION (bigger_need);
7368 : continue;
7369 : }
7370 : # endif
7371 : }
7372 : else
7373 : {
7374 14534 : count = retcount;
7375 : # if WIDE_CHAR_VERSION && defined __MINGW32__
7376 : if (count == 0 && dp->conversion == 'c')
7377 : /* snwprintf returned 0 instead of 1. But it
7378 : wrote a null wide character. */
7379 : count = 1;
7380 : # endif
7381 : }
7382 : }
7383 : }
7384 : #endif
7385 :
7386 : /* Attempt to handle failure. */
7387 14534 : if (count < 0)
7388 : {
7389 : /* SNPRINTF or sprintf failed. Use the errno that it
7390 : has set, if any. */
7391 0 : if (errno == 0)
7392 : {
7393 0 : if (dp->conversion == 'c' || dp->conversion == 's')
7394 0 : errno = EILSEQ;
7395 : else
7396 0 : errno = EINVAL;
7397 : }
7398 :
7399 0 : goto fail_with_errno;
7400 : }
7401 :
7402 : #if USE_SNPRINTF
7403 : /* Handle overflow of the allocated buffer.
7404 : If such an overflow occurs, a C99 compliant snprintf()
7405 : returns a count >= maxlen. However, a non-compliant
7406 : snprintf() function returns only count = maxlen - 1. To
7407 : cover both cases, test whether count >= maxlen - 1. */
7408 14534 : if ((unsigned int) count + 1 >= maxlen)
7409 : {
7410 : /* If maxlen already has attained its allowed maximum,
7411 : allocating more memory will not increase maxlen.
7412 : Instead of looping, bail out. */
7413 0 : if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
7414 0 : goto overflow;
7415 : else
7416 : {
7417 : /* Need at least (count + 1) * sizeof (TCHAR_T)
7418 : bytes. (The +1 is for the trailing NUL.)
7419 : But ask for (count + 2) * sizeof (TCHAR_T)
7420 : bytes, so that in the next round, we likely get
7421 : maxlen > (unsigned int) count + 1
7422 : and so we don't get here again.
7423 : And allocate proportionally, to avoid looping
7424 : eternally if snprintf() reports a too small
7425 : count. */
7426 : size_t n =
7427 0 : xmax (xsum (length,
7428 0 : ((unsigned int) count + 2
7429 : + TCHARS_PER_DCHAR - 1)
7430 : / TCHARS_PER_DCHAR),
7431 0 : xtimes (allocated, 2));
7432 :
7433 0 : ENSURE_ALLOCATION (n);
7434 0 : continue;
7435 : }
7436 : }
7437 : #endif
7438 :
7439 : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
7440 : if (prec_ourselves)
7441 : {
7442 : /* Handle the precision. */
7443 : TCHAR_T *prec_ptr =
7444 : # if USE_SNPRINTF
7445 : (TCHAR_T *) (result + length);
7446 : # else
7447 : tmp;
7448 : # endif
7449 : size_t prefix_count;
7450 : size_t move;
7451 :
7452 : prefix_count = 0;
7453 : /* Put the additional zeroes after the sign. */
7454 : if (count >= 1
7455 : && (*prec_ptr == '-' || *prec_ptr == '+'
7456 : || *prec_ptr == ' '))
7457 : prefix_count = 1;
7458 : /* Put the additional zeroes after the 0x prefix if
7459 : (flags & FLAG_ALT) || (dp->conversion == 'p'), or
7460 : after the 0b prefix if (flags & FLAG_ALT). */
7461 : else if (count >= 2
7462 : && prec_ptr[0] == '0'
7463 : && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'
7464 : || prec_ptr[1] == 'b'
7465 : || prec_ptr[1] == 'B'))
7466 : prefix_count = 2;
7467 :
7468 : move = count - prefix_count;
7469 : if (precision > move)
7470 : {
7471 : /* Insert zeroes. */
7472 : size_t insert = precision - move;
7473 : TCHAR_T *prec_end;
7474 :
7475 : # if USE_SNPRINTF
7476 : size_t n =
7477 : xsum (length,
7478 : (count + insert + TCHARS_PER_DCHAR - 1)
7479 : / TCHARS_PER_DCHAR);
7480 : length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7481 : ENSURE_ALLOCATION (n);
7482 : length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7483 : prec_ptr = (TCHAR_T *) (result + length);
7484 : # endif
7485 :
7486 : prec_end = prec_ptr + count;
7487 : prec_ptr += prefix_count;
7488 :
7489 : while (prec_end > prec_ptr)
7490 : {
7491 : prec_end--;
7492 : prec_end[insert] = prec_end[0];
7493 : }
7494 :
7495 : prec_end += insert;
7496 : do
7497 : *--prec_end = '0';
7498 : while (prec_end > prec_ptr);
7499 :
7500 : count += insert;
7501 : }
7502 : # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
7503 : else if (precision == 0
7504 : && move == 1
7505 : && prec_ptr[prefix_count] == '0')
7506 : {
7507 : /* Replace the "0" result with an empty string. */
7508 : count = prefix_count;
7509 : }
7510 : # endif
7511 : }
7512 : #endif
7513 :
7514 : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
7515 : if (group_ourselves) /* implies (flags & FLAG_GROUP) */
7516 : /* Handle the grouping. */
7517 : switch (dp->conversion)
7518 : {
7519 : /* These are the only conversion to which grouping
7520 : applies. */
7521 : case 'd': case 'i': case 'u':
7522 : case 'f': case 'F': case 'g': case 'G':
7523 : {
7524 : /* Determine the thousands separator of the current
7525 : locale. */
7526 : const TCHAR_T *thousep;
7527 : TCHAR_T thousep_buf[10];
7528 :
7529 : # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
7530 : /* TCHAR_T is wchar_t. */
7531 : thousep = thousands_separator_wchar (thousep_buf);
7532 : # else
7533 : /* TCHAR_T is char. */
7534 : thousep = thousands_separator_char (thousep_buf);
7535 : # endif
7536 :
7537 : /* Nothing to do in locales where thousep is the empty
7538 : string. */
7539 : if (*thousep != 0)
7540 : {
7541 : /* Since FLAG_LOCALIZED is only supported on glibc
7542 : systems, here we can assume that all digits are
7543 : the ASCII digits '0'..'9'. */
7544 : TCHAR_T *number_ptr =
7545 : # if USE_SNPRINTF
7546 : (TCHAR_T *) (result + length);
7547 : # else
7548 : tmp;
7549 : # endif
7550 : TCHAR_T *end_ptr = number_ptr + count;
7551 :
7552 : /* Find where the leading digits start. */
7553 : TCHAR_T *digits_ptr = number_ptr;
7554 : if (count >= 1
7555 : && (*digits_ptr == '-' || *digits_ptr == '+'
7556 : || *digits_ptr == ' '))
7557 : digits_ptr++;
7558 :
7559 : /* Find where the leading digits end. */
7560 : TCHAR_T *digits_end_ptr;
7561 : switch (dp->conversion)
7562 : {
7563 : case 'd': case 'i': case 'u':
7564 : digits_end_ptr = end_ptr;
7565 : break;
7566 : case 'f': case 'F': case 'g': case 'G':
7567 : {
7568 : TCHAR_T decimal_point = decimal_point_char ();
7569 : for (digits_end_ptr = digits_ptr;
7570 : digits_end_ptr < end_ptr;
7571 : digits_end_ptr++)
7572 : if (*digits_end_ptr == decimal_point
7573 : || *digits_end_ptr == 'e')
7574 : break;
7575 : }
7576 : break;
7577 : }
7578 :
7579 : /* Determine the number of thousands separators
7580 : to insert. */
7581 : const signed char *grouping = grouping_rule ();
7582 : size_t insert =
7583 : num_thousands_separators (grouping, digits_end_ptr - digits_ptr);
7584 : if (insert > 0)
7585 : {
7586 : # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
7587 : # define thousep_len 1
7588 : # else
7589 : size_t thousep_len = strlen (thousep);
7590 : # endif
7591 : # if USE_SNPRINTF
7592 : size_t digits_offset = digits_ptr - number_ptr;
7593 : size_t digits_end_offset = digits_end_ptr - number_ptr;
7594 : size_t n =
7595 : xsum (length,
7596 : (count + insert * thousep_len + TCHARS_PER_DCHAR - 1)
7597 : / TCHARS_PER_DCHAR);
7598 : length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7599 : ENSURE_ALLOCATION (n);
7600 : length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
7601 : number_ptr = (TCHAR_T *) (result + length);
7602 : end_ptr = number_ptr + count;
7603 : digits_ptr = number_ptr + digits_offset;
7604 : digits_end_ptr = number_ptr + digits_end_offset;
7605 : # endif
7606 :
7607 : count += insert * thousep_len;
7608 :
7609 : const TCHAR_T *p = end_ptr;
7610 : TCHAR_T *q = end_ptr + insert * thousep_len;
7611 : while (p > digits_end_ptr)
7612 : *--q = *--p;
7613 : const signed char *g = grouping;
7614 : for (;;)
7615 : {
7616 : int h = *g;
7617 : if (h <= 0)
7618 : abort ();
7619 : int i = h;
7620 : do
7621 : *--q = *--p;
7622 : while (--i > 0);
7623 : # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
7624 : *--q = *thousep;
7625 : # else
7626 : q -= thousep_len;
7627 : memcpy (q, thousep, thousep_len);
7628 : # endif
7629 : insert--;
7630 : if (insert == 0)
7631 : break;
7632 : if (g[1] != 0)
7633 : g++;
7634 : }
7635 : /* Here q == p. Done with the insertions. */
7636 : }
7637 : }
7638 : }
7639 : break;
7640 : }
7641 : #endif
7642 :
7643 : #if !USE_SNPRINTF
7644 : if (count >= tmp_length)
7645 : /* tmp_length was incorrectly calculated - fix the
7646 : code above! */
7647 : abort ();
7648 : #endif
7649 :
7650 : #if !DCHAR_IS_TCHAR
7651 : /* Convert from TCHAR_T[] to DCHAR_T[]. */
7652 : if (dp->conversion == 'c' || dp->conversion == 's'
7653 : || (flags & FLAG_GROUP)
7654 : # if __GLIBC__ >= 2 && !defined __UCLIBC__
7655 : || (flags & FLAG_LOCALIZED)
7656 : # endif
7657 : )
7658 : {
7659 : /* The result string is not guaranteed to be ASCII. */
7660 : const TCHAR_T *tmpsrc;
7661 : DCHAR_T *tmpdst;
7662 : size_t tmpdst_len;
7663 : /* This code assumes that TCHAR_T is 'char'. */
7664 : static_assert (sizeof (TCHAR_T) == 1);
7665 : # if USE_SNPRINTF
7666 : tmpsrc = (TCHAR_T *) (result + length);
7667 : # else
7668 : tmpsrc = tmp;
7669 : # endif
7670 : # if WIDE_CHAR_VERSION
7671 : /* Convert tmpsrc[0..count-1] to a freshly allocated
7672 : wide character array. */
7673 : mbstate_t state;
7674 :
7675 : mbszero (&state);
7676 : tmpdst_len = 0;
7677 : {
7678 : const TCHAR_T *src = tmpsrc;
7679 : size_t srclen = count;
7680 :
7681 : for (; srclen > 0; tmpdst_len++)
7682 : {
7683 : /* Parse the next multibyte character. */
7684 : size_t ret = mbrtowc (NULL, src, srclen, &state);
7685 : if (ret == (size_t)(-2) || ret == (size_t)(-1))
7686 : goto fail_with_EILSEQ;
7687 : if (ret == 0)
7688 : ret = 1;
7689 : src += ret;
7690 : srclen -= ret;
7691 : }
7692 : }
7693 :
7694 : tmpdst =
7695 : (wchar_t *) malloc ((tmpdst_len + 1) * sizeof (wchar_t));
7696 : if (tmpdst == NULL)
7697 : goto out_of_memory;
7698 :
7699 : mbszero (&state);
7700 : {
7701 : DCHAR_T *destptr = tmpdst;
7702 : const TCHAR_T *src = tmpsrc;
7703 : size_t srclen = count;
7704 :
7705 : for (; srclen > 0; destptr++)
7706 : {
7707 : /* Parse the next multibyte character. */
7708 : size_t ret = mbrtowc (destptr, src, srclen, &state);
7709 : if (ret == (size_t)(-2) || ret == (size_t)(-1))
7710 : /* Should already have been caught in the first
7711 : loop, above. */
7712 : abort ();
7713 : if (ret == 0)
7714 : ret = 1;
7715 : src += ret;
7716 : srclen -= ret;
7717 : }
7718 : }
7719 : # else
7720 : tmpdst =
7721 : DCHAR_CONV_FROM_ENCODING (locale_charset (),
7722 : iconveh_question_mark,
7723 : tmpsrc, count,
7724 : NULL,
7725 : NULL, &tmpdst_len);
7726 : if (tmpdst == NULL)
7727 : goto fail_with_errno;
7728 : # endif
7729 : ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
7730 : { free (tmpdst); goto out_of_memory; });
7731 : DCHAR_CPY (result + length, tmpdst, tmpdst_len);
7732 : free (tmpdst);
7733 : count = tmpdst_len;
7734 : }
7735 : else
7736 : {
7737 : /* The result string is ASCII.
7738 : Simple 1:1 conversion. */
7739 : # if USE_SNPRINTF
7740 : /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
7741 : no-op conversion, in-place on the array starting
7742 : at (result + length). */
7743 : if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
7744 : # endif
7745 : {
7746 : const TCHAR_T *tmpsrc;
7747 : DCHAR_T *tmpdst;
7748 : size_t n;
7749 :
7750 : # if USE_SNPRINTF
7751 : if (result == resultbuf)
7752 : {
7753 : tmpsrc = (TCHAR_T *) (result + length);
7754 : /* ENSURE_ALLOCATION will not move tmpsrc
7755 : (because it's part of resultbuf). */
7756 : ENSURE_ALLOCATION (xsum (length, count));
7757 : }
7758 : else
7759 : {
7760 : /* ENSURE_ALLOCATION will move the array
7761 : (because it uses realloc(). */
7762 : ENSURE_ALLOCATION (xsum (length, count));
7763 : tmpsrc = (TCHAR_T *) (result + length);
7764 : }
7765 : # else
7766 : tmpsrc = tmp;
7767 : ENSURE_ALLOCATION (xsum (length, count));
7768 : # endif
7769 : tmpdst = result + length;
7770 : /* Copy backwards, because of overlapping. */
7771 : tmpsrc += count;
7772 : tmpdst += count;
7773 : for (n = count; n > 0; n--)
7774 : *--tmpdst = *--tmpsrc;
7775 : }
7776 : }
7777 : #endif
7778 :
7779 : #if DCHAR_IS_TCHAR && !USE_SNPRINTF
7780 : /* Make room for the result. */
7781 : if (count > allocated - length)
7782 : {
7783 : /* Need at least count elements. But allocate
7784 : proportionally. */
7785 : size_t n =
7786 : xmax (xsum (length, count), xtimes (allocated, 2));
7787 :
7788 : ENSURE_ALLOCATION (n);
7789 : }
7790 : #endif
7791 :
7792 : /* Here count <= allocated - length. */
7793 :
7794 : /* Perform padding. */
7795 : #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
7796 : if (pad_ourselves && has_width)
7797 : {
7798 : size_t w;
7799 : # if ENABLE_UNISTDIO
7800 : /* Outside POSIX, it's preferable to compare the width
7801 : against the number of _characters_ of the converted
7802 : value. */
7803 : w = DCHAR_MBSNLEN (result + length, count);
7804 : # elif __GLIBC__ >= 2
7805 : /* glibc prefers to compare the width against the number
7806 : of characters as well, but only for numeric conversion
7807 : specifiers. See
7808 : <https://sourceware.org/bugzilla/show_bug.cgi?id=28943>
7809 : <https://sourceware.org/bugzilla/show_bug.cgi?id=30883>
7810 : <https://sourceware.org/bugzilla/show_bug.cgi?id=31542> */
7811 : switch (dp->conversion)
7812 : {
7813 : case 'd': case 'i': case 'u':
7814 : case 'f': case 'F': case 'g': case 'G':
7815 : w = DCHAR_MBSNLEN (result + length, count);
7816 : break;
7817 : default:
7818 : w = count;
7819 : break;
7820 : }
7821 : # else
7822 : /* The width is compared against the number of _bytes_
7823 : of the converted value, says POSIX. */
7824 : w = count;
7825 : # endif
7826 : if (w < width)
7827 : {
7828 : size_t pad = width - w;
7829 :
7830 : /* Make room for the result. */
7831 : if (xsum (count, pad) > allocated - length)
7832 : {
7833 : /* Need at least count + pad elements. But
7834 : allocate proportionally. */
7835 : size_t n =
7836 : xmax (xsum3 (length, count, pad),
7837 : xtimes (allocated, 2));
7838 :
7839 : # if USE_SNPRINTF
7840 : length += count;
7841 : ENSURE_ALLOCATION (n);
7842 : length -= count;
7843 : # else
7844 : ENSURE_ALLOCATION (n);
7845 : # endif
7846 : }
7847 : /* Here count + pad <= allocated - length. */
7848 :
7849 : {
7850 : # if !DCHAR_IS_TCHAR || USE_SNPRINTF
7851 : DCHAR_T * const rp = result + length;
7852 : # else
7853 : DCHAR_T * const rp = tmp;
7854 : # endif
7855 : DCHAR_T *p = rp + count;
7856 : DCHAR_T *end = p + pad;
7857 : DCHAR_T *pad_ptr;
7858 : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
7859 : if (dp->conversion == 'c'
7860 : || dp->conversion == 's')
7861 : /* No zero-padding for string directives. */
7862 : pad_ptr = NULL;
7863 : else
7864 : # endif
7865 : {
7866 : pad_ptr = (*rp == '-' ? rp + 1 : rp);
7867 : /* No zero-padding of "inf" and "nan". */
7868 : if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
7869 : || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
7870 : pad_ptr = NULL;
7871 : else
7872 : /* Do the zero-padding after the "0x" or
7873 : "0b" prefix, not before. */
7874 : if (p - rp >= 2
7875 : && *rp == '0'
7876 : && (((dp->conversion == 'a'
7877 : || dp->conversion == 'x')
7878 : && rp[1] == 'x')
7879 : || ((dp->conversion == 'A'
7880 : || dp->conversion == 'X')
7881 : && rp[1] == 'X')
7882 : || (dp->conversion == 'b'
7883 : && rp[1] == 'b')
7884 : || (dp->conversion == 'B'
7885 : && rp[1] == 'B')))
7886 : pad_ptr += 2;
7887 : }
7888 : /* The generated string now extends from rp to p,
7889 : with the zero padding insertion point being at
7890 : pad_ptr. */
7891 :
7892 : count = count + pad; /* = end - rp */
7893 :
7894 : if (flags & FLAG_LEFT)
7895 : {
7896 : /* Pad with spaces on the right. */
7897 : for (; pad > 0; pad--)
7898 : *p++ = ' ';
7899 : }
7900 : else if ((flags & FLAG_ZERO) && pad_ptr != NULL
7901 : /* ISO C says: "For d, i, o, u, x, and X
7902 : conversions, if a precision is
7903 : specified, the 0 flag is ignored. */
7904 : && !(has_precision
7905 : && (dp->conversion == 'd'
7906 : || dp->conversion == 'i'
7907 : || dp->conversion == 'o'
7908 : || dp->conversion == 'u'
7909 : || dp->conversion == 'x'
7910 : || dp->conversion == 'X'
7911 : /* Although ISO C does not
7912 : require it, treat 'b' and 'B'
7913 : like 'x' and 'X'. */
7914 : || dp->conversion == 'b'
7915 : || dp->conversion == 'B')))
7916 : {
7917 : /* Pad with zeroes. */
7918 : DCHAR_T *q = end;
7919 :
7920 : while (p > pad_ptr)
7921 : *--q = *--p;
7922 : for (; pad > 0; pad--)
7923 : *p++ = '0';
7924 : }
7925 : else
7926 : {
7927 : /* Pad with spaces on the left. */
7928 : DCHAR_T *q = end;
7929 :
7930 : while (p > rp)
7931 : *--q = *--p;
7932 : for (; pad > 0; pad--)
7933 : *p++ = ' ';
7934 : }
7935 : }
7936 : }
7937 : }
7938 : #endif
7939 :
7940 : /* Here still count <= allocated - length. */
7941 :
7942 : #if !DCHAR_IS_TCHAR || USE_SNPRINTF
7943 : /* The snprintf() result did fit. */
7944 : #else
7945 : /* Append the sprintf() result. */
7946 : memcpy (result + length, tmp, count * sizeof (DCHAR_T));
7947 : #endif
7948 : #if !USE_SNPRINTF
7949 : if (tmp != tmpbuf)
7950 : free (tmp);
7951 : #endif
7952 :
7953 : #if NEED_PRINTF_DIRECTIVE_F
7954 : if (dp->conversion == 'F')
7955 : {
7956 : /* Convert the %f result to upper case for %F. */
7957 : DCHAR_T *rp = result + length;
7958 : size_t rc;
7959 : for (rc = count; rc > 0; rc--, rp++)
7960 : if (*rp >= 'a' && *rp <= 'z')
7961 : *rp = *rp - 'a' + 'A';
7962 : }
7963 : #endif
7964 :
7965 14534 : length += count;
7966 14534 : break;
7967 : }
7968 14534 : errno = orig_errno;
7969 : #undef pad_ourselves
7970 : #undef prec_ourselves
7971 : }
7972 : }
7973 : }
7974 :
7975 : /* Add the final NUL. */
7976 14391 : ENSURE_ALLOCATION (xsum (length, 1));
7977 14391 : result[length] = '\0';
7978 :
7979 14391 : if (result != resultbuf && length + 1 < allocated)
7980 : {
7981 : /* Shrink the allocated memory if possible. */
7982 : DCHAR_T *memory;
7983 :
7984 0 : memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
7985 0 : if (memory != NULL)
7986 0 : result = memory;
7987 : }
7988 :
7989 14391 : if (buf_malloced != NULL)
7990 0 : free (buf_malloced);
7991 14391 : CLEANUP ();
7992 14391 : *lengthp = length;
7993 : /* Note that we can produce a big string of a length > INT_MAX. POSIX
7994 : says that snprintf() fails with errno = EOVERFLOW in this case, but
7995 : that's only because snprintf() returns an 'int'. This function does
7996 : not have this limitation. */
7997 14391 : return result;
7998 :
7999 0 : overflow:
8000 0 : errno = EOVERFLOW;
8001 0 : goto fail_with_errno;
8002 :
8003 0 : out_of_memory:
8004 0 : errno = ENOMEM;
8005 0 : goto fail_with_errno;
8006 :
8007 : #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)
8008 0 : fail_with_EILSEQ:
8009 0 : errno = EILSEQ;
8010 0 : goto fail_with_errno;
8011 : #endif
8012 :
8013 0 : fail_with_errno:
8014 0 : if (result != resultbuf)
8015 0 : free (result);
8016 0 : if (buf_malloced != NULL)
8017 0 : free (buf_malloced);
8018 0 : CLEANUP ();
8019 0 : return NULL;
8020 : }
8021 :
8022 0 : out_of_memory_1:
8023 0 : errno = ENOMEM;
8024 0 : goto fail_1_with_errno;
8025 :
8026 0 : fail_1_with_EINVAL:
8027 0 : errno = EINVAL;
8028 0 : goto fail_1_with_errno;
8029 :
8030 0 : fail_1_with_errno:
8031 0 : CLEANUP ();
8032 0 : return NULL;
8033 : }
8034 :
8035 : #undef MAX_ROOM_NEEDED
8036 : #undef TCHARS_PER_DCHAR
8037 : #undef SNPRINTF
8038 : #undef USE_SNPRINTF
8039 : #undef DCHAR_SET
8040 : #undef DCHAR_CPY
8041 : #undef PRINTF_PARSE
8042 : #undef DIRECTIVES
8043 : #undef DIRECTIVE
8044 : #undef DCHAR_IS_TCHAR
8045 : #undef TCHAR_T
8046 : #undef DCHAR_T
8047 : #undef FCHAR_T
8048 : #undef VASNPRINTF
|