diff options
Diffstat (limited to 'gl/vasnprintf.c')
| -rw-r--r-- | gl/vasnprintf.c | 1668 |
1 files changed, 1455 insertions, 213 deletions
diff --git a/gl/vasnprintf.c b/gl/vasnprintf.c index 277c39e3..de204458 100644 --- a/gl/vasnprintf.c +++ b/gl/vasnprintf.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* vsprintf with automatic memory allocation. | 1 | /* vsprintf with automatic memory allocation. |
| 2 | Copyright (C) 1999, 2002-2023 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2002-2024 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 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 | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -83,9 +83,9 @@ | |||
| 83 | #include <stdio.h> /* snprintf(), sprintf() */ | 83 | #include <stdio.h> /* snprintf(), sprintf() */ |
| 84 | #include <stdlib.h> /* abort(), malloc(), realloc(), free() */ | 84 | #include <stdlib.h> /* abort(), malloc(), realloc(), free() */ |
| 85 | #include <string.h> /* memcpy(), strlen() */ | 85 | #include <string.h> /* memcpy(), strlen() */ |
| 86 | #include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb() */ | 86 | #include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb(), mbszero() */ |
| 87 | #include <errno.h> /* errno */ | 87 | #include <errno.h> /* errno */ |
| 88 | #include <limits.h> /* CHAR_BIT */ | 88 | #include <limits.h> /* CHAR_BIT, INT_WIDTH, LONG_WIDTH */ |
| 89 | #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */ | 89 | #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */ |
| 90 | #if HAVE_NL_LANGINFO | 90 | #if HAVE_NL_LANGINFO |
| 91 | # include <langinfo.h> | 91 | # include <langinfo.h> |
| @@ -103,29 +103,29 @@ | |||
| 103 | 103 | ||
| 104 | #include "attribute.h" | 104 | #include "attribute.h" |
| 105 | 105 | ||
| 106 | #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL | 106 | #if NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) |
| 107 | # include <math.h> | 107 | # include <math.h> |
| 108 | # include "float+.h" | 108 | # include "float+.h" |
| 109 | #endif | 109 | #endif |
| 110 | 110 | ||
| 111 | #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL | 111 | #if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE |
| 112 | # include <math.h> | 112 | # include <math.h> |
| 113 | # include "isnand-nolibm.h" | 113 | # include "isnand-nolibm.h" |
| 114 | #endif | 114 | #endif |
| 115 | 115 | ||
| 116 | #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL | 116 | #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) |
| 117 | # include <math.h> | 117 | # include <math.h> |
| 118 | # include "isnanl-nolibm.h" | 118 | # include "isnanl-nolibm.h" |
| 119 | # include "fpucw.h" | 119 | # include "fpucw.h" |
| 120 | #endif | 120 | #endif |
| 121 | 121 | ||
| 122 | #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL | 122 | #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE |
| 123 | # include <math.h> | 123 | # include <math.h> |
| 124 | # include "isnand-nolibm.h" | 124 | # include "isnand-nolibm.h" |
| 125 | # include "printf-frexp.h" | 125 | # include "printf-frexp.h" |
| 126 | #endif | 126 | #endif |
| 127 | 127 | ||
| 128 | #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL | 128 | #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) |
| 129 | # include <math.h> | 129 | # include <math.h> |
| 130 | # include "isnanl-nolibm.h" | 130 | # include "isnanl-nolibm.h" |
| 131 | # include "printf-frexpl.h" | 131 | # include "printf-frexpl.h" |
| @@ -138,8 +138,6 @@ | |||
| 138 | # define VASNPRINTF vasnwprintf | 138 | # define VASNPRINTF vasnwprintf |
| 139 | # define FCHAR_T wchar_t | 139 | # define FCHAR_T wchar_t |
| 140 | # define DCHAR_T wchar_t | 140 | # define DCHAR_T wchar_t |
| 141 | # define TCHAR_T wchar_t | ||
| 142 | # define DCHAR_IS_TCHAR 1 | ||
| 143 | # define DIRECTIVE wchar_t_directive | 141 | # define DIRECTIVE wchar_t_directive |
| 144 | # define DIRECTIVES wchar_t_directives | 142 | # define DIRECTIVES wchar_t_directives |
| 145 | # define PRINTF_PARSE wprintf_parse | 143 | # define PRINTF_PARSE wprintf_parse |
| @@ -159,24 +157,32 @@ | |||
| 159 | # endif | 157 | # endif |
| 160 | #endif | 158 | #endif |
| 161 | #if WIDE_CHAR_VERSION | 159 | #if WIDE_CHAR_VERSION |
| 162 | /* TCHAR_T is wchar_t. */ | 160 | /* DCHAR_T is wchar_t. */ |
| 163 | # define USE_SNPRINTF 1 | 161 | # if HAVE_DECL__SNWPRINTF || (HAVE_SWPRINTF && HAVE_WORKING_SWPRINTF) |
| 164 | # if HAVE_DECL__SNWPRINTF | 162 | # define TCHAR_T wchar_t |
| 165 | /* On Windows, the function swprintf() has a different signature than | 163 | # define DCHAR_IS_TCHAR 1 |
| 166 | on Unix; we use the function _snwprintf() or - on mingw - snwprintf() | 164 | # define USE_SNPRINTF 1 |
| 167 | instead. The mingw function snwprintf() has fewer bugs than the | 165 | # if HAVE_DECL__SNWPRINTF |
| 168 | MSVCRT function _snwprintf(), so prefer that. */ | 166 | /* On Windows, the function swprintf() has a different signature than |
| 169 | # if defined __MINGW32__ | 167 | on Unix; we use the function _snwprintf() or - on mingw - snwprintf() |
| 170 | # define SNPRINTF snwprintf | 168 | instead. The mingw function snwprintf() has fewer bugs than the |
| 169 | MSVCRT function _snwprintf(), so prefer that. */ | ||
| 170 | # if defined __MINGW32__ | ||
| 171 | # define SNPRINTF snwprintf | ||
| 172 | # else | ||
| 173 | # define SNPRINTF _snwprintf | ||
| 174 | # define USE_MSVC__SNPRINTF 1 | ||
| 175 | # endif | ||
| 171 | # else | 176 | # else |
| 172 | # define SNPRINTF _snwprintf | 177 | /* Unix. */ |
| 173 | # define USE_MSVC__SNPRINTF 1 | 178 | # define SNPRINTF swprintf |
| 174 | # endif | 179 | # endif |
| 175 | # else | 180 | # else |
| 176 | /* Unix. */ | 181 | /* Old platforms such as NetBSD 3.0, OpenBSD 3.8, HP-UX 11.00, IRIX 6.5. */ |
| 177 | # define SNPRINTF swprintf | 182 | # define TCHAR_T char |
| 178 | # endif | 183 | # endif |
| 179 | #else | 184 | #endif |
| 185 | #if !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR | ||
| 180 | /* TCHAR_T is char. */ | 186 | /* TCHAR_T is char. */ |
| 181 | /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. | 187 | /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. |
| 182 | But don't use it on BeOS, since BeOS snprintf produces no output if the | 188 | But don't use it on BeOS, since BeOS snprintf produces no output if the |
| @@ -241,7 +247,7 @@ local_strnlen (const char *string, size_t maxlen) | |||
| 241 | # endif | 247 | # endif |
| 242 | #endif | 248 | #endif |
| 243 | 249 | ||
| 244 | #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T | 250 | #if (((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_WPRINTF_DIRECTIVE_LC) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T |
| 245 | # if HAVE_WCSLEN | 251 | # if HAVE_WCSLEN |
| 246 | # define local_wcslen wcslen | 252 | # define local_wcslen wcslen |
| 247 | # else | 253 | # else |
| @@ -264,8 +270,8 @@ local_wcslen (const wchar_t *s) | |||
| 264 | # endif | 270 | # endif |
| 265 | #endif | 271 | #endif |
| 266 | 272 | ||
| 267 | #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION | 273 | #if (!USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION |
| 268 | # if HAVE_WCSNLEN | 274 | # if HAVE_WCSNLEN && HAVE_DECL_WCSNLEN |
| 269 | # define local_wcsnlen wcsnlen | 275 | # define local_wcsnlen wcsnlen |
| 270 | # else | 276 | # else |
| 271 | # ifndef local_wcsnlen_defined | 277 | # ifndef local_wcsnlen_defined |
| @@ -283,12 +289,12 @@ local_wcsnlen (const wchar_t *s, size_t maxlen) | |||
| 283 | # endif | 289 | # endif |
| 284 | #endif | 290 | #endif |
| 285 | 291 | ||
| 286 | #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || (ENABLE_WCHAR_FALLBACK && HAVE_WINT_T)) && !WIDE_CHAR_VERSION | 292 | #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T)) && !WIDE_CHAR_VERSION |
| 287 | # if ENABLE_WCHAR_FALLBACK | 293 | # if ENABLE_WCHAR_FALLBACK |
| 288 | static size_t | 294 | static size_t |
| 289 | wctomb_fallback (char *s, wchar_t wc) | 295 | wctomb_fallback (char *s, wchar_t wc) |
| 290 | { | 296 | { |
| 291 | static char hex[16] = "0123456789ABCDEF"; | 297 | static char const hex[16] = "0123456789ABCDEF"; |
| 292 | 298 | ||
| 293 | s[0] = '\\'; | 299 | s[0] = '\\'; |
| 294 | if (sizeof (wchar_t) > 2 && wc > 0xffff) | 300 | if (sizeof (wchar_t) > 2 && wc > 0xffff) |
| @@ -351,7 +357,7 @@ local_wctomb (char *s, wchar_t wc) | |||
| 351 | # endif | 357 | # endif |
| 352 | #endif | 358 | #endif |
| 353 | 359 | ||
| 354 | #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL | 360 | #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) |
| 355 | /* Determine the decimal-point character according to the current locale. */ | 361 | /* Determine the decimal-point character according to the current locale. */ |
| 356 | # ifndef decimal_point_char_defined | 362 | # ifndef decimal_point_char_defined |
| 357 | # define decimal_point_char_defined 1 | 363 | # define decimal_point_char_defined 1 |
| @@ -378,7 +384,7 @@ decimal_point_char (void) | |||
| 378 | # endif | 384 | # endif |
| 379 | #endif | 385 | #endif |
| 380 | 386 | ||
| 381 | #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL | 387 | #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE |
| 382 | 388 | ||
| 383 | /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ | 389 | /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ |
| 384 | static int | 390 | static int |
| @@ -389,7 +395,7 @@ is_infinite_or_zero (double x) | |||
| 389 | 395 | ||
| 390 | #endif | 396 | #endif |
| 391 | 397 | ||
| 392 | #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL | 398 | #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE |
| 393 | 399 | ||
| 394 | /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ | 400 | /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ |
| 395 | static int | 401 | static int |
| @@ -400,7 +406,7 @@ is_infinite_or_zerol (long double x) | |||
| 400 | 406 | ||
| 401 | #endif | 407 | #endif |
| 402 | 408 | ||
| 403 | #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL | 409 | #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE |
| 404 | 410 | ||
| 405 | /* Converting 'long double' to decimal without rare rounding bugs requires | 411 | /* Converting 'long double' to decimal without rare rounding bugs requires |
| 406 | real bignums. We use the naming conventions of GNU gmp, but vastly simpler | 412 | real bignums. We use the naming conventions of GNU gmp, but vastly simpler |
| @@ -921,6 +927,14 @@ divide (mpn_t a, mpn_t b, mpn_t *q) | |||
| 921 | return roomptr; | 927 | return roomptr; |
| 922 | } | 928 | } |
| 923 | 929 | ||
| 930 | /* Avoid pointless GCC warning "argument 1 value '18446744073709551615' exceeds | ||
| 931 | maximum object size 9223372036854775807", triggered by the use of xsum as | ||
| 932 | argument of malloc. */ | ||
| 933 | # if __GNUC__ >= 7 | ||
| 934 | # pragma GCC diagnostic push | ||
| 935 | # pragma GCC diagnostic ignored "-Walloc-size-larger-than=" | ||
| 936 | # endif | ||
| 937 | |||
| 924 | /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal | 938 | /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal |
| 925 | representation. | 939 | representation. |
| 926 | Destroys the contents of a. | 940 | Destroys the contents of a. |
| @@ -977,6 +991,10 @@ convert_to_decimal (mpn_t a, size_t extra_zeroes) | |||
| 977 | return c_ptr; | 991 | return c_ptr; |
| 978 | } | 992 | } |
| 979 | 993 | ||
| 994 | # if __GNUC__ >= 7 | ||
| 995 | # pragma GCC diagnostic pop | ||
| 996 | # endif | ||
| 997 | |||
| 980 | # if NEED_PRINTF_LONG_DOUBLE | 998 | # if NEED_PRINTF_LONG_DOUBLE |
| 981 | 999 | ||
| 982 | /* Assuming x is finite and >= 0: | 1000 | /* Assuming x is finite and >= 0: |
| @@ -1171,8 +1189,6 @@ scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) | |||
| 1171 | void *z_memory; | 1189 | void *z_memory; |
| 1172 | char *digits; | 1190 | char *digits; |
| 1173 | 1191 | ||
| 1174 | if (memory == NULL) | ||
| 1175 | return NULL; | ||
| 1176 | /* x = 2^e * m, hence | 1192 | /* x = 2^e * m, hence |
| 1177 | y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m) | 1193 | y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m) |
| 1178 | = round (2^s * 5^n * m). */ | 1194 | = round (2^s * 5^n * m). */ |
| @@ -1380,10 +1396,13 @@ scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) | |||
| 1380 | static char * | 1396 | static char * |
| 1381 | scale10_round_decimal_long_double (long double x, int n) | 1397 | scale10_round_decimal_long_double (long double x, int n) |
| 1382 | { | 1398 | { |
| 1383 | int e IF_LINT(= 0); | 1399 | int e; |
| 1384 | mpn_t m; | 1400 | mpn_t m; |
| 1385 | void *memory = decode_long_double (x, &e, &m); | 1401 | void *memory = decode_long_double (x, &e, &m); |
| 1386 | return scale10_round_decimal_decoded (e, m, memory, n); | 1402 | if (memory != NULL) |
| 1403 | return scale10_round_decimal_decoded (e, m, memory, n); | ||
| 1404 | else | ||
| 1405 | return NULL; | ||
| 1387 | } | 1406 | } |
| 1388 | 1407 | ||
| 1389 | # endif | 1408 | # endif |
| @@ -1398,10 +1417,13 @@ scale10_round_decimal_long_double (long double x, int n) | |||
| 1398 | static char * | 1417 | static char * |
| 1399 | scale10_round_decimal_double (double x, int n) | 1418 | scale10_round_decimal_double (double x, int n) |
| 1400 | { | 1419 | { |
| 1401 | int e IF_LINT(= 0); | 1420 | int e; |
| 1402 | mpn_t m; | 1421 | mpn_t m; |
| 1403 | void *memory = decode_double (x, &e, &m); | 1422 | void *memory = decode_double (x, &e, &m); |
| 1404 | return scale10_round_decimal_decoded (e, m, memory, n); | 1423 | if (memory != NULL) |
| 1424 | return scale10_round_decimal_decoded (e, m, memory, n); | ||
| 1425 | else | ||
| 1426 | return NULL; | ||
| 1405 | } | 1427 | } |
| 1406 | 1428 | ||
| 1407 | # endif | 1429 | # endif |
| @@ -1604,7 +1626,7 @@ is_borderline (const char *digits, size_t precision) | |||
| 1604 | 1626 | ||
| 1605 | #endif | 1627 | #endif |
| 1606 | 1628 | ||
| 1607 | #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF | 1629 | #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF |
| 1608 | 1630 | ||
| 1609 | /* Use a different function name, to make it possible that the 'wchar_t' | 1631 | /* Use a different function name, to make it possible that the 'wchar_t' |
| 1610 | parametrization and the 'char' parametrization get compiled in the same | 1632 | parametrization and the 'char' parametrization get compiled in the same |
| @@ -1627,24 +1649,156 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 1627 | switch (conversion) | 1649 | switch (conversion) |
| 1628 | { | 1650 | { |
| 1629 | case 'd': case 'i': case 'u': | 1651 | case 'd': case 'i': case 'u': |
| 1630 | if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) | 1652 | switch (type) |
| 1631 | tmp_length = | 1653 | { |
| 1632 | (unsigned int) (sizeof (unsigned long long) * CHAR_BIT | 1654 | default: |
| 1633 | * 0.30103 /* binary -> decimal */ | 1655 | tmp_length = |
| 1634 | ) | 1656 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT |
| 1635 | + 1; /* turn floor into ceil */ | 1657 | * 0.30103 /* binary -> decimal */ |
| 1636 | else if (type == TYPE_LONGINT || type == TYPE_ULONGINT) | 1658 | ) |
| 1637 | tmp_length = | 1659 | + 1; /* turn floor into ceil */ |
| 1638 | (unsigned int) (sizeof (unsigned long) * CHAR_BIT | 1660 | break; |
| 1639 | * 0.30103 /* binary -> decimal */ | 1661 | case TYPE_LONGINT: |
| 1640 | ) | 1662 | tmp_length = |
| 1641 | + 1; /* turn floor into ceil */ | 1663 | (unsigned int) (sizeof (long int) * CHAR_BIT |
| 1642 | else | 1664 | * 0.30103 /* binary -> decimal */ |
| 1643 | tmp_length = | 1665 | ) |
| 1644 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT | 1666 | + 1; /* turn floor into ceil */ |
| 1645 | * 0.30103 /* binary -> decimal */ | 1667 | break; |
| 1646 | ) | 1668 | case TYPE_ULONGINT: |
| 1647 | + 1; /* turn floor into ceil */ | 1669 | tmp_length = |
| 1670 | (unsigned int) (sizeof (unsigned long int) * CHAR_BIT | ||
| 1671 | * 0.30103 /* binary -> decimal */ | ||
| 1672 | ) | ||
| 1673 | + 1; /* turn floor into ceil */ | ||
| 1674 | break; | ||
| 1675 | case TYPE_LONGLONGINT: | ||
| 1676 | tmp_length = | ||
| 1677 | (unsigned int) (sizeof (long long int) * CHAR_BIT | ||
| 1678 | * 0.30103 /* binary -> decimal */ | ||
| 1679 | ) | ||
| 1680 | + 1; /* turn floor into ceil */ | ||
| 1681 | break; | ||
| 1682 | case TYPE_ULONGLONGINT: | ||
| 1683 | tmp_length = | ||
| 1684 | (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT | ||
| 1685 | * 0.30103 /* binary -> decimal */ | ||
| 1686 | ) | ||
| 1687 | + 1; /* turn floor into ceil */ | ||
| 1688 | break; | ||
| 1689 | case TYPE_INT8_T: | ||
| 1690 | tmp_length = | ||
| 1691 | (unsigned int) (sizeof (int8_t) * CHAR_BIT | ||
| 1692 | * 0.30103 /* binary -> decimal */ | ||
| 1693 | ) | ||
| 1694 | + 1; /* turn floor into ceil */ | ||
| 1695 | break; | ||
| 1696 | case TYPE_UINT8_T: | ||
| 1697 | tmp_length = | ||
| 1698 | (unsigned int) (sizeof (uint8_t) * CHAR_BIT | ||
| 1699 | * 0.30103 /* binary -> decimal */ | ||
| 1700 | ) | ||
| 1701 | + 1; /* turn floor into ceil */ | ||
| 1702 | break; | ||
| 1703 | case TYPE_INT16_T: | ||
| 1704 | tmp_length = | ||
| 1705 | (unsigned int) (sizeof (int16_t) * CHAR_BIT | ||
| 1706 | * 0.30103 /* binary -> decimal */ | ||
| 1707 | ) | ||
| 1708 | + 1; /* turn floor into ceil */ | ||
| 1709 | break; | ||
| 1710 | case TYPE_UINT16_T: | ||
| 1711 | tmp_length = | ||
| 1712 | (unsigned int) (sizeof (uint16_t) * CHAR_BIT | ||
| 1713 | * 0.30103 /* binary -> decimal */ | ||
| 1714 | ) | ||
| 1715 | + 1; /* turn floor into ceil */ | ||
| 1716 | break; | ||
| 1717 | case TYPE_INT32_T: | ||
| 1718 | tmp_length = | ||
| 1719 | (unsigned int) (sizeof (int32_t) * CHAR_BIT | ||
| 1720 | * 0.30103 /* binary -> decimal */ | ||
| 1721 | ) | ||
| 1722 | + 1; /* turn floor into ceil */ | ||
| 1723 | break; | ||
| 1724 | case TYPE_UINT32_T: | ||
| 1725 | tmp_length = | ||
| 1726 | (unsigned int) (sizeof (uint32_t) * CHAR_BIT | ||
| 1727 | * 0.30103 /* binary -> decimal */ | ||
| 1728 | ) | ||
| 1729 | + 1; /* turn floor into ceil */ | ||
| 1730 | break; | ||
| 1731 | case TYPE_INT64_T: | ||
| 1732 | tmp_length = | ||
| 1733 | (unsigned int) (sizeof (int64_t) * CHAR_BIT | ||
| 1734 | * 0.30103 /* binary -> decimal */ | ||
| 1735 | ) | ||
| 1736 | + 1; /* turn floor into ceil */ | ||
| 1737 | break; | ||
| 1738 | case TYPE_UINT64_T: | ||
| 1739 | tmp_length = | ||
| 1740 | (unsigned int) (sizeof (uint64_t) * CHAR_BIT | ||
| 1741 | * 0.30103 /* binary -> decimal */ | ||
| 1742 | ) | ||
| 1743 | + 1; /* turn floor into ceil */ | ||
| 1744 | break; | ||
| 1745 | case TYPE_INT_FAST8_T: | ||
| 1746 | tmp_length = | ||
| 1747 | (unsigned int) (sizeof (int_fast8_t) * CHAR_BIT | ||
| 1748 | * 0.30103 /* binary -> decimal */ | ||
| 1749 | ) | ||
| 1750 | + 1; /* turn floor into ceil */ | ||
| 1751 | break; | ||
| 1752 | case TYPE_UINT_FAST8_T: | ||
| 1753 | tmp_length = | ||
| 1754 | (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT | ||
| 1755 | * 0.30103 /* binary -> decimal */ | ||
| 1756 | ) | ||
| 1757 | + 1; /* turn floor into ceil */ | ||
| 1758 | break; | ||
| 1759 | case TYPE_INT_FAST16_T: | ||
| 1760 | tmp_length = | ||
| 1761 | (unsigned int) (sizeof (int_fast16_t) * CHAR_BIT | ||
| 1762 | * 0.30103 /* binary -> decimal */ | ||
| 1763 | ) | ||
| 1764 | + 1; /* turn floor into ceil */ | ||
| 1765 | break; | ||
| 1766 | case TYPE_UINT_FAST16_T: | ||
| 1767 | tmp_length = | ||
| 1768 | (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT | ||
| 1769 | * 0.30103 /* binary -> decimal */ | ||
| 1770 | ) | ||
| 1771 | + 1; /* turn floor into ceil */ | ||
| 1772 | break; | ||
| 1773 | case TYPE_INT_FAST32_T: | ||
| 1774 | tmp_length = | ||
| 1775 | (unsigned int) (sizeof (int_fast32_t) * CHAR_BIT | ||
| 1776 | * 0.30103 /* binary -> decimal */ | ||
| 1777 | ) | ||
| 1778 | + 1; /* turn floor into ceil */ | ||
| 1779 | break; | ||
| 1780 | case TYPE_UINT_FAST32_T: | ||
| 1781 | tmp_length = | ||
| 1782 | (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT | ||
| 1783 | * 0.30103 /* binary -> decimal */ | ||
| 1784 | ) | ||
| 1785 | + 1; /* turn floor into ceil */ | ||
| 1786 | break; | ||
| 1787 | case TYPE_INT_FAST64_T: | ||
| 1788 | tmp_length = | ||
| 1789 | (unsigned int) (sizeof (int_fast64_t) * CHAR_BIT | ||
| 1790 | * 0.30103 /* binary -> decimal */ | ||
| 1791 | ) | ||
| 1792 | + 1; /* turn floor into ceil */ | ||
| 1793 | break; | ||
| 1794 | case TYPE_UINT_FAST64_T: | ||
| 1795 | tmp_length = | ||
| 1796 | (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT | ||
| 1797 | * 0.30103 /* binary -> decimal */ | ||
| 1798 | ) | ||
| 1799 | + 1; /* turn floor into ceil */ | ||
| 1800 | break; | ||
| 1801 | } | ||
| 1648 | if (tmp_length < precision) | 1802 | if (tmp_length < precision) |
| 1649 | tmp_length = precision; | 1803 | tmp_length = precision; |
| 1650 | /* Multiply by 2, as an estimate for FLAG_GROUP. */ | 1804 | /* Multiply by 2, as an estimate for FLAG_GROUP. */ |
| @@ -1653,25 +1807,156 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 1653 | tmp_length = xsum (tmp_length, 1); | 1807 | tmp_length = xsum (tmp_length, 1); |
| 1654 | break; | 1808 | break; |
| 1655 | 1809 | ||
| 1810 | case 'b': | ||
| 1811 | #if SUPPORT_GNU_PRINTF_DIRECTIVES \ | ||
| 1812 | || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2) | ||
| 1813 | case 'B': | ||
| 1814 | #endif | ||
| 1815 | switch (type) | ||
| 1816 | { | ||
| 1817 | default: | ||
| 1818 | tmp_length = | ||
| 1819 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT) | ||
| 1820 | + 1; /* turn floor into ceil */ | ||
| 1821 | break; | ||
| 1822 | case TYPE_ULONGINT: | ||
| 1823 | tmp_length = | ||
| 1824 | (unsigned int) (sizeof (unsigned long int) * CHAR_BIT) | ||
| 1825 | + 1; /* turn floor into ceil */ | ||
| 1826 | break; | ||
| 1827 | case TYPE_ULONGLONGINT: | ||
| 1828 | tmp_length = | ||
| 1829 | (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT) | ||
| 1830 | + 1; /* turn floor into ceil */ | ||
| 1831 | break; | ||
| 1832 | case TYPE_UINT8_T: | ||
| 1833 | tmp_length = | ||
| 1834 | (unsigned int) (sizeof (uint8_t) * CHAR_BIT) | ||
| 1835 | + 1; /* turn floor into ceil */ | ||
| 1836 | break; | ||
| 1837 | case TYPE_UINT16_T: | ||
| 1838 | tmp_length = | ||
| 1839 | (unsigned int) (sizeof (uint16_t) * CHAR_BIT) | ||
| 1840 | + 1; /* turn floor into ceil */ | ||
| 1841 | break; | ||
| 1842 | case TYPE_UINT32_T: | ||
| 1843 | tmp_length = | ||
| 1844 | (unsigned int) (sizeof (uint32_t) * CHAR_BIT) | ||
| 1845 | + 1; /* turn floor into ceil */ | ||
| 1846 | break; | ||
| 1847 | case TYPE_UINT64_T: | ||
| 1848 | tmp_length = | ||
| 1849 | (unsigned int) (sizeof (uint64_t) * CHAR_BIT) | ||
| 1850 | + 1; /* turn floor into ceil */ | ||
| 1851 | break; | ||
| 1852 | case TYPE_UINT_FAST8_T: | ||
| 1853 | tmp_length = | ||
| 1854 | (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT) | ||
| 1855 | + 1; /* turn floor into ceil */ | ||
| 1856 | break; | ||
| 1857 | case TYPE_UINT_FAST16_T: | ||
| 1858 | tmp_length = | ||
| 1859 | (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT) | ||
| 1860 | + 1; /* turn floor into ceil */ | ||
| 1861 | break; | ||
| 1862 | case TYPE_UINT_FAST32_T: | ||
| 1863 | tmp_length = | ||
| 1864 | (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT) | ||
| 1865 | + 1; /* turn floor into ceil */ | ||
| 1866 | break; | ||
| 1867 | case TYPE_UINT_FAST64_T: | ||
| 1868 | tmp_length = | ||
| 1869 | (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT) | ||
| 1870 | + 1; /* turn floor into ceil */ | ||
| 1871 | break; | ||
| 1872 | } | ||
| 1873 | if (tmp_length < precision) | ||
| 1874 | tmp_length = precision; | ||
| 1875 | /* Add 2, to account for a prefix from the alternate form. */ | ||
| 1876 | tmp_length = xsum (tmp_length, 2); | ||
| 1877 | break; | ||
| 1878 | |||
| 1656 | case 'o': | 1879 | case 'o': |
| 1657 | if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) | 1880 | switch (type) |
| 1658 | tmp_length = | 1881 | { |
| 1659 | (unsigned int) (sizeof (unsigned long long) * CHAR_BIT | 1882 | default: |
| 1660 | * 0.333334 /* binary -> octal */ | 1883 | tmp_length = |
| 1661 | ) | 1884 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT |
| 1662 | + 1; /* turn floor into ceil */ | 1885 | * 0.333334 /* binary -> octal */ |
| 1663 | else if (type == TYPE_LONGINT || type == TYPE_ULONGINT) | 1886 | ) |
| 1664 | tmp_length = | 1887 | + 1; /* turn floor into ceil */ |
| 1665 | (unsigned int) (sizeof (unsigned long) * CHAR_BIT | 1888 | break; |
| 1666 | * 0.333334 /* binary -> octal */ | 1889 | case TYPE_ULONGINT: |
| 1667 | ) | 1890 | tmp_length = |
| 1668 | + 1; /* turn floor into ceil */ | 1891 | (unsigned int) (sizeof (unsigned long int) * CHAR_BIT |
| 1669 | else | 1892 | * 0.333334 /* binary -> octal */ |
| 1670 | tmp_length = | 1893 | ) |
| 1671 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT | 1894 | + 1; /* turn floor into ceil */ |
| 1672 | * 0.333334 /* binary -> octal */ | 1895 | break; |
| 1673 | ) | 1896 | case TYPE_ULONGLONGINT: |
| 1674 | + 1; /* turn floor into ceil */ | 1897 | tmp_length = |
| 1898 | (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT | ||
| 1899 | * 0.333334 /* binary -> octal */ | ||
| 1900 | ) | ||
| 1901 | + 1; /* turn floor into ceil */ | ||
| 1902 | break; | ||
| 1903 | case TYPE_UINT8_T: | ||
| 1904 | tmp_length = | ||
| 1905 | (unsigned int) (sizeof (uint8_t) * CHAR_BIT | ||
| 1906 | * 0.333334 /* binary -> octal */ | ||
| 1907 | ) | ||
| 1908 | + 1; /* turn floor into ceil */ | ||
| 1909 | break; | ||
| 1910 | case TYPE_UINT16_T: | ||
| 1911 | tmp_length = | ||
| 1912 | (unsigned int) (sizeof (uint16_t) * CHAR_BIT | ||
| 1913 | * 0.333334 /* binary -> octal */ | ||
| 1914 | ) | ||
| 1915 | + 1; /* turn floor into ceil */ | ||
| 1916 | break; | ||
| 1917 | case TYPE_UINT32_T: | ||
| 1918 | tmp_length = | ||
| 1919 | (unsigned int) (sizeof (uint32_t) * CHAR_BIT | ||
| 1920 | * 0.333334 /* binary -> octal */ | ||
| 1921 | ) | ||
| 1922 | + 1; /* turn floor into ceil */ | ||
| 1923 | break; | ||
| 1924 | case TYPE_UINT64_T: | ||
| 1925 | tmp_length = | ||
| 1926 | (unsigned int) (sizeof (uint64_t) * CHAR_BIT | ||
| 1927 | * 0.333334 /* binary -> octal */ | ||
| 1928 | ) | ||
| 1929 | + 1; /* turn floor into ceil */ | ||
| 1930 | break; | ||
| 1931 | case TYPE_UINT_FAST8_T: | ||
| 1932 | tmp_length = | ||
| 1933 | (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT | ||
| 1934 | * 0.333334 /* binary -> octal */ | ||
| 1935 | ) | ||
| 1936 | + 1; /* turn floor into ceil */ | ||
| 1937 | break; | ||
| 1938 | case TYPE_UINT_FAST16_T: | ||
| 1939 | tmp_length = | ||
| 1940 | (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT | ||
| 1941 | * 0.333334 /* binary -> octal */ | ||
| 1942 | ) | ||
| 1943 | + 1; /* turn floor into ceil */ | ||
| 1944 | break; | ||
| 1945 | case TYPE_UINT_FAST32_T: | ||
| 1946 | tmp_length = | ||
| 1947 | (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT | ||
| 1948 | * 0.333334 /* binary -> octal */ | ||
| 1949 | ) | ||
| 1950 | + 1; /* turn floor into ceil */ | ||
| 1951 | break; | ||
| 1952 | case TYPE_UINT_FAST64_T: | ||
| 1953 | tmp_length = | ||
| 1954 | (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT | ||
| 1955 | * 0.333334 /* binary -> octal */ | ||
| 1956 | ) | ||
| 1957 | + 1; /* turn floor into ceil */ | ||
| 1958 | break; | ||
| 1959 | } | ||
| 1675 | if (tmp_length < precision) | 1960 | if (tmp_length < precision) |
| 1676 | tmp_length = precision; | 1961 | tmp_length = precision; |
| 1677 | /* Add 1, to account for a leading sign. */ | 1962 | /* Add 1, to account for a leading sign. */ |
| @@ -1679,27 +1964,89 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 1679 | break; | 1964 | break; |
| 1680 | 1965 | ||
| 1681 | case 'x': case 'X': | 1966 | case 'x': case 'X': |
| 1682 | if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) | 1967 | switch (type) |
| 1683 | tmp_length = | 1968 | { |
| 1684 | (unsigned int) (sizeof (unsigned long long) * CHAR_BIT | 1969 | default: |
| 1685 | * 0.25 /* binary -> hexadecimal */ | 1970 | tmp_length = |
| 1686 | ) | 1971 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT |
| 1687 | + 1; /* turn floor into ceil */ | 1972 | * 0.25 /* binary -> hexadecimal */ |
| 1688 | else if (type == TYPE_LONGINT || type == TYPE_ULONGINT) | 1973 | ) |
| 1689 | tmp_length = | 1974 | + 1; /* turn floor into ceil */ |
| 1690 | (unsigned int) (sizeof (unsigned long) * CHAR_BIT | 1975 | break; |
| 1691 | * 0.25 /* binary -> hexadecimal */ | 1976 | case TYPE_ULONGINT: |
| 1692 | ) | 1977 | tmp_length = |
| 1693 | + 1; /* turn floor into ceil */ | 1978 | (unsigned int) (sizeof (unsigned long int) * CHAR_BIT |
| 1694 | else | 1979 | * 0.25 /* binary -> hexadecimal */ |
| 1695 | tmp_length = | 1980 | ) |
| 1696 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT | 1981 | + 1; /* turn floor into ceil */ |
| 1697 | * 0.25 /* binary -> hexadecimal */ | 1982 | break; |
| 1698 | ) | 1983 | case TYPE_ULONGLONGINT: |
| 1699 | + 1; /* turn floor into ceil */ | 1984 | tmp_length = |
| 1985 | (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT | ||
| 1986 | * 0.25 /* binary -> hexadecimal */ | ||
| 1987 | ) | ||
| 1988 | + 1; /* turn floor into ceil */ | ||
| 1989 | break; | ||
| 1990 | case TYPE_UINT8_T: | ||
| 1991 | tmp_length = | ||
| 1992 | (unsigned int) (sizeof (uint8_t) * CHAR_BIT | ||
| 1993 | * 0.25 /* binary -> hexadecimal */ | ||
| 1994 | ) | ||
| 1995 | + 1; /* turn floor into ceil */ | ||
| 1996 | break; | ||
| 1997 | case TYPE_UINT16_T: | ||
| 1998 | tmp_length = | ||
| 1999 | (unsigned int) (sizeof (uint16_t) * CHAR_BIT | ||
| 2000 | * 0.25 /* binary -> hexadecimal */ | ||
| 2001 | ) | ||
| 2002 | + 1; /* turn floor into ceil */ | ||
| 2003 | break; | ||
| 2004 | case TYPE_UINT32_T: | ||
| 2005 | tmp_length = | ||
| 2006 | (unsigned int) (sizeof (uint32_t) * CHAR_BIT | ||
| 2007 | * 0.25 /* binary -> hexadecimal */ | ||
| 2008 | ) | ||
| 2009 | + 1; /* turn floor into ceil */ | ||
| 2010 | break; | ||
| 2011 | case TYPE_UINT64_T: | ||
| 2012 | tmp_length = | ||
| 2013 | (unsigned int) (sizeof (uint64_t) * CHAR_BIT | ||
| 2014 | * 0.25 /* binary -> hexadecimal */ | ||
| 2015 | ) | ||
| 2016 | + 1; /* turn floor into ceil */ | ||
| 2017 | break; | ||
| 2018 | case TYPE_UINT_FAST8_T: | ||
| 2019 | tmp_length = | ||
| 2020 | (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT | ||
| 2021 | * 0.25 /* binary -> hexadecimal */ | ||
| 2022 | ) | ||
| 2023 | + 1; /* turn floor into ceil */ | ||
| 2024 | break; | ||
| 2025 | case TYPE_UINT_FAST16_T: | ||
| 2026 | tmp_length = | ||
| 2027 | (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT | ||
| 2028 | * 0.25 /* binary -> hexadecimal */ | ||
| 2029 | ) | ||
| 2030 | + 1; /* turn floor into ceil */ | ||
| 2031 | break; | ||
| 2032 | case TYPE_UINT_FAST32_T: | ||
| 2033 | tmp_length = | ||
| 2034 | (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT | ||
| 2035 | * 0.25 /* binary -> hexadecimal */ | ||
| 2036 | ) | ||
| 2037 | + 1; /* turn floor into ceil */ | ||
| 2038 | break; | ||
| 2039 | case TYPE_UINT_FAST64_T: | ||
| 2040 | tmp_length = | ||
| 2041 | (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT | ||
| 2042 | * 0.25 /* binary -> hexadecimal */ | ||
| 2043 | ) | ||
| 2044 | + 1; /* turn floor into ceil */ | ||
| 2045 | break; | ||
| 2046 | } | ||
| 1700 | if (tmp_length < precision) | 2047 | if (tmp_length < precision) |
| 1701 | tmp_length = precision; | 2048 | tmp_length = precision; |
| 1702 | /* Add 2, to account for a leading sign or alternate form. */ | 2049 | /* Add 2, to account for a prefix from the alternate form. */ |
| 1703 | tmp_length = xsum (tmp_length, 2); | 2050 | tmp_length = xsum (tmp_length, 2); |
| 1704 | break; | 2051 | break; |
| 1705 | 2052 | ||
| @@ -1988,6 +2335,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 1988 | 2335 | ||
| 1989 | if (dp->conversion == 'n') | 2336 | if (dp->conversion == 'n') |
| 1990 | { | 2337 | { |
| 2338 | #if NEED_PRINTF_WITH_N_DIRECTIVE | ||
| 1991 | switch (a.arg[dp->arg_index].type) | 2339 | switch (a.arg[dp->arg_index].type) |
| 1992 | { | 2340 | { |
| 1993 | case TYPE_COUNT_SCHAR_POINTER: | 2341 | case TYPE_COUNT_SCHAR_POINTER: |
| @@ -2005,9 +2353,36 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2005 | case TYPE_COUNT_LONGLONGINT_POINTER: | 2353 | case TYPE_COUNT_LONGLONGINT_POINTER: |
| 2006 | *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; | 2354 | *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; |
| 2007 | break; | 2355 | break; |
| 2356 | case TYPE_COUNT_INT8_T_POINTER: | ||
| 2357 | *a.arg[dp->arg_index].a.a_count_int8_t_pointer = length; | ||
| 2358 | break; | ||
| 2359 | case TYPE_COUNT_INT16_T_POINTER: | ||
| 2360 | *a.arg[dp->arg_index].a.a_count_int16_t_pointer = length; | ||
| 2361 | break; | ||
| 2362 | case TYPE_COUNT_INT32_T_POINTER: | ||
| 2363 | *a.arg[dp->arg_index].a.a_count_int32_t_pointer = length; | ||
| 2364 | break; | ||
| 2365 | case TYPE_COUNT_INT64_T_POINTER: | ||
| 2366 | *a.arg[dp->arg_index].a.a_count_int64_t_pointer = length; | ||
| 2367 | break; | ||
| 2368 | case TYPE_COUNT_INT_FAST8_T_POINTER: | ||
| 2369 | *a.arg[dp->arg_index].a.a_count_int_fast8_t_pointer = length; | ||
| 2370 | break; | ||
| 2371 | case TYPE_COUNT_INT_FAST16_T_POINTER: | ||
| 2372 | *a.arg[dp->arg_index].a.a_count_int_fast16_t_pointer = length; | ||
| 2373 | break; | ||
| 2374 | case TYPE_COUNT_INT_FAST32_T_POINTER: | ||
| 2375 | *a.arg[dp->arg_index].a.a_count_int_fast32_t_pointer = length; | ||
| 2376 | break; | ||
| 2377 | case TYPE_COUNT_INT_FAST64_T_POINTER: | ||
| 2378 | *a.arg[dp->arg_index].a.a_count_int_fast64_t_pointer = length; | ||
| 2379 | break; | ||
| 2008 | default: | 2380 | default: |
| 2009 | abort (); | 2381 | abort (); |
| 2010 | } | 2382 | } |
| 2383 | #else | ||
| 2384 | abort (); | ||
| 2385 | #endif | ||
| 2011 | } | 2386 | } |
| 2012 | #if ENABLE_UNISTDIO | 2387 | #if ENABLE_UNISTDIO |
| 2013 | /* The unistdio extensions. */ | 2388 | /* The unistdio extensions. */ |
| @@ -2130,7 +2505,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2130 | characters = 0; | 2505 | characters = 0; |
| 2131 | } | 2506 | } |
| 2132 | 2507 | ||
| 2133 | if (characters < width && !(dp->flags & FLAG_LEFT)) | 2508 | if (characters < width && !(flags & FLAG_LEFT)) |
| 2134 | { | 2509 | { |
| 2135 | size_t n = width - characters; | 2510 | size_t n = width - characters; |
| 2136 | ENSURE_ALLOCATION (xsum (length, n)); | 2511 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2175,7 +2550,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2175 | } | 2550 | } |
| 2176 | # endif | 2551 | # endif |
| 2177 | 2552 | ||
| 2178 | if (characters < width && (dp->flags & FLAG_LEFT)) | 2553 | if (characters < width && (flags & FLAG_LEFT)) |
| 2179 | { | 2554 | { |
| 2180 | size_t n = width - characters; | 2555 | size_t n = width - characters; |
| 2181 | ENSURE_ALLOCATION (xsum (length, n)); | 2556 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2232,7 +2607,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2232 | characters = 0; | 2607 | characters = 0; |
| 2233 | } | 2608 | } |
| 2234 | 2609 | ||
| 2235 | if (characters < width && !(dp->flags & FLAG_LEFT)) | 2610 | if (characters < width && !(flags & FLAG_LEFT)) |
| 2236 | { | 2611 | { |
| 2237 | size_t n = width - characters; | 2612 | size_t n = width - characters; |
| 2238 | ENSURE_ALLOCATION (xsum (length, n)); | 2613 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2277,7 +2652,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2277 | } | 2652 | } |
| 2278 | # endif | 2653 | # endif |
| 2279 | 2654 | ||
| 2280 | if (characters < width && (dp->flags & FLAG_LEFT)) | 2655 | if (characters < width && (flags & FLAG_LEFT)) |
| 2281 | { | 2656 | { |
| 2282 | size_t n = width - characters; | 2657 | size_t n = width - characters; |
| 2283 | ENSURE_ALLOCATION (xsum (length, n)); | 2658 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2334,7 +2709,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2334 | characters = 0; | 2709 | characters = 0; |
| 2335 | } | 2710 | } |
| 2336 | 2711 | ||
| 2337 | if (characters < width && !(dp->flags & FLAG_LEFT)) | 2712 | if (characters < width && !(flags & FLAG_LEFT)) |
| 2338 | { | 2713 | { |
| 2339 | size_t n = width - characters; | 2714 | size_t n = width - characters; |
| 2340 | ENSURE_ALLOCATION (xsum (length, n)); | 2715 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2379,7 +2754,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2379 | } | 2754 | } |
| 2380 | # endif | 2755 | # endif |
| 2381 | 2756 | ||
| 2382 | if (characters < width && (dp->flags & FLAG_LEFT)) | 2757 | if (characters < width && (flags & FLAG_LEFT)) |
| 2383 | { | 2758 | { |
| 2384 | size_t n = width - characters; | 2759 | size_t n = width - characters; |
| 2385 | ENSURE_ALLOCATION (xsum (length, n)); | 2760 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2394,7 +2769,150 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2394 | } | 2769 | } |
| 2395 | } | 2770 | } |
| 2396 | #endif | 2771 | #endif |
| 2397 | #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T | 2772 | #if WIDE_CHAR_VERSION && (!DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC) |
| 2773 | else if ((dp->conversion == 's' | ||
| 2774 | && a.arg[dp->arg_index].type == TYPE_WIDE_STRING) | ||
| 2775 | || (dp->conversion == 'c' | ||
| 2776 | && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)) | ||
| 2777 | { | ||
| 2778 | /* %ls or %lc in vasnwprintf. See the specification of | ||
| 2779 | fwprintf. */ | ||
| 2780 | /* It would be silly to use snprintf ("%ls", ...) and then | ||
| 2781 | convert back the result from a char[] to a wchar_t[]. | ||
| 2782 | Instead, just copy the argument wchar_t[] to the result. */ | ||
| 2783 | int flags = dp->flags; | ||
| 2784 | size_t width; | ||
| 2785 | |||
| 2786 | width = 0; | ||
| 2787 | if (dp->width_start != dp->width_end) | ||
| 2788 | { | ||
| 2789 | if (dp->width_arg_index != ARG_NONE) | ||
| 2790 | { | ||
| 2791 | int arg; | ||
| 2792 | |||
| 2793 | if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) | ||
| 2794 | abort (); | ||
| 2795 | arg = a.arg[dp->width_arg_index].a.a_int; | ||
| 2796 | width = arg; | ||
| 2797 | if (arg < 0) | ||
| 2798 | { | ||
| 2799 | /* "A negative field width is taken as a '-' flag | ||
| 2800 | followed by a positive field width." */ | ||
| 2801 | flags |= FLAG_LEFT; | ||
| 2802 | width = -width; | ||
| 2803 | } | ||
| 2804 | } | ||
| 2805 | else | ||
| 2806 | { | ||
| 2807 | const FCHAR_T *digitp = dp->width_start; | ||
| 2808 | |||
| 2809 | do | ||
| 2810 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | ||
| 2811 | while (digitp != dp->width_end); | ||
| 2812 | } | ||
| 2813 | } | ||
| 2814 | |||
| 2815 | { | ||
| 2816 | const wchar_t *ls_arg; | ||
| 2817 | wchar_t lc_arg[1]; | ||
| 2818 | size_t characters; | ||
| 2819 | |||
| 2820 | if (dp->conversion == 's') | ||
| 2821 | { | ||
| 2822 | int has_precision; | ||
| 2823 | size_t precision; | ||
| 2824 | |||
| 2825 | has_precision = 0; | ||
| 2826 | precision = 6; | ||
| 2827 | if (dp->precision_start != dp->precision_end) | ||
| 2828 | { | ||
| 2829 | if (dp->precision_arg_index != ARG_NONE) | ||
| 2830 | { | ||
| 2831 | int arg; | ||
| 2832 | |||
| 2833 | if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) | ||
| 2834 | abort (); | ||
| 2835 | arg = a.arg[dp->precision_arg_index].a.a_int; | ||
| 2836 | /* "A negative precision is taken as if the precision | ||
| 2837 | were omitted." */ | ||
| 2838 | if (arg >= 0) | ||
| 2839 | { | ||
| 2840 | precision = arg; | ||
| 2841 | has_precision = 1; | ||
| 2842 | } | ||
| 2843 | } | ||
| 2844 | else | ||
| 2845 | { | ||
| 2846 | const FCHAR_T *digitp = dp->precision_start + 1; | ||
| 2847 | |||
| 2848 | precision = 0; | ||
| 2849 | while (digitp != dp->precision_end) | ||
| 2850 | precision = xsum (xtimes (precision, 10), *digitp++ - '0'); | ||
| 2851 | has_precision = 1; | ||
| 2852 | } | ||
| 2853 | } | ||
| 2854 | |||
| 2855 | ls_arg = a.arg[dp->arg_index].a.a_wide_string; | ||
| 2856 | |||
| 2857 | if (has_precision) | ||
| 2858 | { | ||
| 2859 | /* Use only at most PRECISION wide characters, from | ||
| 2860 | the left. */ | ||
| 2861 | const wchar_t *ls_arg_end; | ||
| 2862 | |||
| 2863 | ls_arg_end = ls_arg; | ||
| 2864 | characters = 0; | ||
| 2865 | for (; precision > 0; precision--) | ||
| 2866 | { | ||
| 2867 | if (*ls_arg_end == 0) | ||
| 2868 | /* Found the terminating null wide character. */ | ||
| 2869 | break; | ||
| 2870 | ls_arg_end++; | ||
| 2871 | characters++; | ||
| 2872 | } | ||
| 2873 | } | ||
| 2874 | else | ||
| 2875 | { | ||
| 2876 | /* Use the entire string, and count the number of wide | ||
| 2877 | characters. */ | ||
| 2878 | characters = local_wcslen (ls_arg); | ||
| 2879 | } | ||
| 2880 | } | ||
| 2881 | else /* dp->conversion == 'c' */ | ||
| 2882 | { | ||
| 2883 | lc_arg[0] = (wchar_t) a.arg[dp->arg_index].a.a_wide_char; | ||
| 2884 | ls_arg = lc_arg; | ||
| 2885 | characters = 1; | ||
| 2886 | } | ||
| 2887 | |||
| 2888 | { | ||
| 2889 | size_t total = (characters < width ? width : characters); | ||
| 2890 | ENSURE_ALLOCATION (xsum (length, total)); | ||
| 2891 | |||
| 2892 | if (characters < width && !(flags & FLAG_LEFT)) | ||
| 2893 | { | ||
| 2894 | size_t n = width - characters; | ||
| 2895 | DCHAR_SET (result + length, ' ', n); | ||
| 2896 | length += n; | ||
| 2897 | } | ||
| 2898 | |||
| 2899 | if (characters > 0) | ||
| 2900 | { | ||
| 2901 | DCHAR_CPY (result + length, ls_arg, characters); | ||
| 2902 | length += characters; | ||
| 2903 | } | ||
| 2904 | |||
| 2905 | if (characters < width && (flags & FLAG_LEFT)) | ||
| 2906 | { | ||
| 2907 | size_t n = width - characters; | ||
| 2908 | DCHAR_SET (result + length, ' ', n); | ||
| 2909 | length += n; | ||
| 2910 | } | ||
| 2911 | } | ||
| 2912 | } | ||
| 2913 | } | ||
| 2914 | #endif | ||
| 2915 | #if (!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T | ||
| 2398 | else if (dp->conversion == 's' | 2916 | else if (dp->conversion == 's' |
| 2399 | # if WIDE_CHAR_VERSION | 2917 | # if WIDE_CHAR_VERSION |
| 2400 | && a.arg[dp->arg_index].type != TYPE_WIDE_STRING | 2918 | && a.arg[dp->arg_index].type != TYPE_WIDE_STRING |
| @@ -2493,7 +3011,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2493 | wide characters, from the left. */ | 3011 | wide characters, from the left. */ |
| 2494 | # if HAVE_MBRTOWC | 3012 | # if HAVE_MBRTOWC |
| 2495 | mbstate_t state; | 3013 | mbstate_t state; |
| 2496 | memset (&state, '\0', sizeof (mbstate_t)); | 3014 | mbszero (&state); |
| 2497 | # endif | 3015 | # endif |
| 2498 | arg_end = arg; | 3016 | arg_end = arg; |
| 2499 | characters = 0; | 3017 | characters = 0; |
| @@ -2521,7 +3039,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2521 | characters. */ | 3039 | characters. */ |
| 2522 | # if HAVE_MBRTOWC | 3040 | # if HAVE_MBRTOWC |
| 2523 | mbstate_t state; | 3041 | mbstate_t state; |
| 2524 | memset (&state, '\0', sizeof (mbstate_t)); | 3042 | mbszero (&state); |
| 2525 | # endif | 3043 | # endif |
| 2526 | arg_end = arg; | 3044 | arg_end = arg; |
| 2527 | characters = 0; | 3045 | characters = 0; |
| @@ -2551,7 +3069,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2551 | characters = 0; | 3069 | characters = 0; |
| 2552 | } | 3070 | } |
| 2553 | 3071 | ||
| 2554 | if (characters < width && !(dp->flags & FLAG_LEFT)) | 3072 | if (characters < width && !(flags & FLAG_LEFT)) |
| 2555 | { | 3073 | { |
| 2556 | size_t n = width - characters; | 3074 | size_t n = width - characters; |
| 2557 | ENSURE_ALLOCATION (xsum (length, n)); | 3075 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2565,7 +3083,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2565 | size_t remaining; | 3083 | size_t remaining; |
| 2566 | # if HAVE_MBRTOWC | 3084 | # if HAVE_MBRTOWC |
| 2567 | mbstate_t state; | 3085 | mbstate_t state; |
| 2568 | memset (&state, '\0', sizeof (mbstate_t)); | 3086 | mbszero (&state); |
| 2569 | # endif | 3087 | # endif |
| 2570 | ENSURE_ALLOCATION (xsum (length, characters)); | 3088 | ENSURE_ALLOCATION (xsum (length, characters)); |
| 2571 | for (remaining = characters; remaining > 0; remaining--) | 3089 | for (remaining = characters; remaining > 0; remaining--) |
| @@ -2591,7 +3109,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2591 | { | 3109 | { |
| 2592 | # if HAVE_MBRTOWC | 3110 | # if HAVE_MBRTOWC |
| 2593 | mbstate_t state; | 3111 | mbstate_t state; |
| 2594 | memset (&state, '\0', sizeof (mbstate_t)); | 3112 | mbszero (&state); |
| 2595 | # endif | 3113 | # endif |
| 2596 | while (arg < arg_end) | 3114 | while (arg < arg_end) |
| 2597 | { | 3115 | { |
| @@ -2602,17 +3120,19 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2602 | # else | 3120 | # else |
| 2603 | count = mbtowc (&wc, arg, arg_end - arg); | 3121 | count = mbtowc (&wc, arg, arg_end - arg); |
| 2604 | # endif | 3122 | # endif |
| 2605 | if (count <= 0) | 3123 | if (count == 0) |
| 2606 | /* mbrtowc not consistent with mbrlen, or mbtowc | 3124 | /* mbrtowc not consistent with strlen. */ |
| 2607 | not consistent with mblen. */ | ||
| 2608 | abort (); | 3125 | abort (); |
| 3126 | if (count < 0) | ||
| 3127 | /* Invalid or incomplete multibyte character. */ | ||
| 3128 | goto fail_with_EILSEQ; | ||
| 2609 | ENSURE_ALLOCATION (xsum (length, 1)); | 3129 | ENSURE_ALLOCATION (xsum (length, 1)); |
| 2610 | result[length++] = wc; | 3130 | result[length++] = wc; |
| 2611 | arg += count; | 3131 | arg += count; |
| 2612 | } | 3132 | } |
| 2613 | } | 3133 | } |
| 2614 | 3134 | ||
| 2615 | if (characters < width && (dp->flags & FLAG_LEFT)) | 3135 | if (characters < width && (flags & FLAG_LEFT)) |
| 2616 | { | 3136 | { |
| 2617 | size_t n = width - characters; | 3137 | size_t n = width - characters; |
| 2618 | ENSURE_ALLOCATION (xsum (length, n)); | 3138 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2641,7 +3161,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2641 | at most PRECISION bytes, from the left. */ | 3161 | at most PRECISION bytes, from the left. */ |
| 2642 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3162 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2643 | mbstate_t state; | 3163 | mbstate_t state; |
| 2644 | memset (&state, '\0', sizeof (mbstate_t)); | 3164 | mbszero (&state); |
| 2645 | # endif | 3165 | # endif |
| 2646 | arg_end = arg; | 3166 | arg_end = arg; |
| 2647 | characters = 0; | 3167 | characters = 0; |
| @@ -2674,7 +3194,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2674 | bytes. */ | 3194 | bytes. */ |
| 2675 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3195 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2676 | mbstate_t state; | 3196 | mbstate_t state; |
| 2677 | memset (&state, '\0', sizeof (mbstate_t)); | 3197 | mbszero (&state); |
| 2678 | # endif | 3198 | # endif |
| 2679 | arg_end = arg; | 3199 | arg_end = arg; |
| 2680 | characters = 0; | 3200 | characters = 0; |
| @@ -2714,7 +3234,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2714 | size_t remaining; | 3234 | size_t remaining; |
| 2715 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3235 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2716 | mbstate_t state; | 3236 | mbstate_t state; |
| 2717 | memset (&state, '\0', sizeof (mbstate_t)); | 3237 | mbszero (&state); |
| 2718 | # endif | 3238 | # endif |
| 2719 | for (remaining = characters; remaining > 0; ) | 3239 | for (remaining = characters; remaining > 0; ) |
| 2720 | { | 3240 | { |
| @@ -2768,7 +3288,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2768 | /* w doesn't matter. */ | 3288 | /* w doesn't matter. */ |
| 2769 | w = 0; | 3289 | w = 0; |
| 2770 | 3290 | ||
| 2771 | if (w < width && !(dp->flags & FLAG_LEFT)) | 3291 | if (w < width && !(flags & FLAG_LEFT)) |
| 2772 | { | 3292 | { |
| 2773 | size_t n = width - w; | 3293 | size_t n = width - w; |
| 2774 | ENSURE_ALLOCATION (xsum (length, n)); | 3294 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2783,7 +3303,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2783 | size_t remaining; | 3303 | size_t remaining; |
| 2784 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3304 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2785 | mbstate_t state; | 3305 | mbstate_t state; |
| 2786 | memset (&state, '\0', sizeof (mbstate_t)); | 3306 | mbszero (&state); |
| 2787 | # endif | 3307 | # endif |
| 2788 | ENSURE_ALLOCATION (xsum (length, characters)); | 3308 | ENSURE_ALLOCATION (xsum (length, characters)); |
| 2789 | for (remaining = characters; remaining > 0; ) | 3309 | for (remaining = characters; remaining > 0; ) |
| @@ -2809,7 +3329,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2809 | { | 3329 | { |
| 2810 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3330 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2811 | mbstate_t state; | 3331 | mbstate_t state; |
| 2812 | memset (&state, '\0', sizeof (mbstate_t)); | 3332 | mbszero (&state); |
| 2813 | # endif | 3333 | # endif |
| 2814 | while (arg < arg_end) | 3334 | while (arg < arg_end) |
| 2815 | { | 3335 | { |
| @@ -2836,7 +3356,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2836 | length += tmpdst_len; | 3356 | length += tmpdst_len; |
| 2837 | # endif | 3357 | # endif |
| 2838 | 3358 | ||
| 2839 | if (w < width && (dp->flags & FLAG_LEFT)) | 3359 | if (w < width && (flags & FLAG_LEFT)) |
| 2840 | { | 3360 | { |
| 2841 | size_t n = width - w; | 3361 | size_t n = width - w; |
| 2842 | ENSURE_ALLOCATION (xsum (length, n)); | 3362 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2847,12 +3367,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2847 | # endif | 3367 | # endif |
| 2848 | } | 3368 | } |
| 2849 | #endif | 3369 | #endif |
| 2850 | #if ENABLE_WCHAR_FALLBACK && HAVE_WINT_T && !WIDE_CHAR_VERSION | 3370 | #if (NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION |
| 2851 | else if (dp->conversion == 'c' | 3371 | else if (dp->conversion == 'c' |
| 2852 | && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR) | 3372 | && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR) |
| 2853 | { | 3373 | { |
| 2854 | /* Implement the 'lc' directive ourselves, in order to provide | 3374 | /* Implement the 'lc' directive ourselves, in order to provide |
| 2855 | the fallback that avoids EILSEQ. */ | 3375 | a correct behaviour for the null wint_t argument and/or the |
| 3376 | fallback that avoids EILSEQ. */ | ||
| 2856 | int flags = dp->flags; | 3377 | int flags = dp->flags; |
| 2857 | int has_width; | 3378 | int has_width; |
| 2858 | size_t width; | 3379 | size_t width; |
| @@ -2907,21 +3428,18 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2907 | { | 3428 | { |
| 2908 | /* Count the number of bytes. */ | 3429 | /* Count the number of bytes. */ |
| 2909 | characters = 0; | 3430 | characters = 0; |
| 2910 | if (arg != 0) | 3431 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| 2911 | { | 3432 | int count; |
| 2912 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | ||
| 2913 | int count; | ||
| 2914 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3433 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2915 | mbstate_t state; | 3434 | mbstate_t state; |
| 2916 | memset (&state, '\0', sizeof (mbstate_t)); | 3435 | mbszero (&state); |
| 2917 | # endif | 3436 | # endif |
| 2918 | 3437 | ||
| 2919 | count = local_wcrtomb (cbuf, arg, &state); | 3438 | count = local_wcrtomb (cbuf, arg, &state); |
| 2920 | if (count < 0) | 3439 | if (count < 0) |
| 2921 | /* Inconsistency. */ | 3440 | /* Cannot convert. */ |
| 2922 | abort (); | 3441 | goto fail_with_EILSEQ; |
| 2923 | characters = count; | 3442 | characters = count; |
| 2924 | } | ||
| 2925 | } | 3443 | } |
| 2926 | # if DCHAR_IS_TCHAR | 3444 | # if DCHAR_IS_TCHAR |
| 2927 | else | 3445 | else |
| @@ -2933,13 +3451,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2933 | 3451 | ||
| 2934 | # if !DCHAR_IS_TCHAR | 3452 | # if !DCHAR_IS_TCHAR |
| 2935 | /* Convert the string into a piece of temporary memory. */ | 3453 | /* Convert the string into a piece of temporary memory. */ |
| 2936 | if (characters > 0) /* implies arg != 0 */ | 3454 | if (characters > 0) |
| 2937 | { | 3455 | { |
| 2938 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | 3456 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| 2939 | int count; | 3457 | int count; |
| 2940 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3458 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2941 | mbstate_t state; | 3459 | mbstate_t state; |
| 2942 | memset (&state, '\0', sizeof (mbstate_t)); | 3460 | mbszero (&state); |
| 2943 | # endif | 3461 | # endif |
| 2944 | 3462 | ||
| 2945 | count = local_wcrtomb (cbuf, arg, &state); | 3463 | count = local_wcrtomb (cbuf, arg, &state); |
| @@ -2977,7 +3495,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2977 | /* w doesn't matter. */ | 3495 | /* w doesn't matter. */ |
| 2978 | w = 0; | 3496 | w = 0; |
| 2979 | 3497 | ||
| 2980 | if (w < width && !(dp->flags & FLAG_LEFT)) | 3498 | if (w < width && !(flags & FLAG_LEFT)) |
| 2981 | { | 3499 | { |
| 2982 | size_t n = width - w; | 3500 | size_t n = width - w; |
| 2983 | ENSURE_ALLOCATION (xsum (length, n)); | 3501 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -2990,12 +3508,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2990 | { | 3508 | { |
| 2991 | /* We know the number of bytes in advance. */ | 3509 | /* We know the number of bytes in advance. */ |
| 2992 | ENSURE_ALLOCATION (xsum (length, characters)); | 3510 | ENSURE_ALLOCATION (xsum (length, characters)); |
| 2993 | if (characters > 0) /* implies arg != 0 */ | 3511 | if (characters > 0) |
| 2994 | { | 3512 | { |
| 2995 | int count; | 3513 | int count; |
| 2996 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3514 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 2997 | mbstate_t state; | 3515 | mbstate_t state; |
| 2998 | memset (&state, '\0', sizeof (mbstate_t)); | 3516 | mbszero (&state); |
| 2999 | # endif | 3517 | # endif |
| 3000 | 3518 | ||
| 3001 | count = local_wcrtomb (result + length, arg, &state); | 3519 | count = local_wcrtomb (result + length, arg, &state); |
| @@ -3007,23 +3525,20 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3007 | } | 3525 | } |
| 3008 | else | 3526 | else |
| 3009 | { | 3527 | { |
| 3010 | if (arg != 0) | 3528 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| 3011 | { | 3529 | int count; |
| 3012 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | ||
| 3013 | int count; | ||
| 3014 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3530 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 3015 | mbstate_t state; | 3531 | mbstate_t state; |
| 3016 | memset (&state, '\0', sizeof (mbstate_t)); | 3532 | mbszero (&state); |
| 3017 | # endif | 3533 | # endif |
| 3018 | 3534 | ||
| 3019 | count = local_wcrtomb (cbuf, arg, &state); | 3535 | count = local_wcrtomb (cbuf, arg, &state); |
| 3020 | if (count <= 0) | 3536 | if (count < 0) |
| 3021 | /* Inconsistency. */ | 3537 | /* Cannot convert. */ |
| 3022 | abort (); | 3538 | goto fail_with_EILSEQ; |
| 3023 | ENSURE_ALLOCATION (xsum (length, count)); | 3539 | ENSURE_ALLOCATION (xsum (length, count)); |
| 3024 | memcpy (result + length, cbuf, count); | 3540 | memcpy (result + length, cbuf, count); |
| 3025 | length += count; | 3541 | length += count; |
| 3026 | } | ||
| 3027 | } | 3542 | } |
| 3028 | # else | 3543 | # else |
| 3029 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), | 3544 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), |
| @@ -3033,7 +3548,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3033 | length += tmpdst_len; | 3548 | length += tmpdst_len; |
| 3034 | # endif | 3549 | # endif |
| 3035 | 3550 | ||
| 3036 | if (w < width && (dp->flags & FLAG_LEFT)) | 3551 | if (w < width && (flags & FLAG_LEFT)) |
| 3037 | { | 3552 | { |
| 3038 | size_t n = width - w; | 3553 | size_t n = width - w; |
| 3039 | ENSURE_ALLOCATION (xsum (length, n)); | 3554 | ENSURE_ALLOCATION (xsum (length, n)); |
| @@ -3043,14 +3558,399 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3043 | } | 3558 | } |
| 3044 | } | 3559 | } |
| 3045 | #endif | 3560 | #endif |
| 3046 | #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL | 3561 | #if NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION |
| 3562 | else if (dp->conversion == 'c' | ||
| 3563 | && a.arg[dp->arg_index].type != TYPE_WIDE_CHAR) | ||
| 3564 | { | ||
| 3565 | /* Implement the 'c' directive ourselves, in order to avoid | ||
| 3566 | EILSEQ in the "C" locale. */ | ||
| 3567 | int flags = dp->flags; | ||
| 3568 | size_t width; | ||
| 3569 | |||
| 3570 | width = 0; | ||
| 3571 | if (dp->width_start != dp->width_end) | ||
| 3572 | { | ||
| 3573 | if (dp->width_arg_index != ARG_NONE) | ||
| 3574 | { | ||
| 3575 | int arg; | ||
| 3576 | |||
| 3577 | if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) | ||
| 3578 | abort (); | ||
| 3579 | arg = a.arg[dp->width_arg_index].a.a_int; | ||
| 3580 | width = arg; | ||
| 3581 | if (arg < 0) | ||
| 3582 | { | ||
| 3583 | /* "A negative field width is taken as a '-' flag | ||
| 3584 | followed by a positive field width." */ | ||
| 3585 | flags |= FLAG_LEFT; | ||
| 3586 | width = -width; | ||
| 3587 | } | ||
| 3588 | } | ||
| 3589 | else | ||
| 3590 | { | ||
| 3591 | const FCHAR_T *digitp = dp->width_start; | ||
| 3592 | |||
| 3593 | do | ||
| 3594 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | ||
| 3595 | while (digitp != dp->width_end); | ||
| 3596 | } | ||
| 3597 | } | ||
| 3598 | |||
| 3599 | /* %c in vasnwprintf. See the specification of fwprintf. */ | ||
| 3600 | { | ||
| 3601 | char arg = (char) a.arg[dp->arg_index].a.a_char; | ||
| 3602 | mbstate_t state; | ||
| 3603 | wchar_t wc; | ||
| 3604 | |||
| 3605 | mbszero (&state); | ||
| 3606 | int count = mbrtowc (&wc, &arg, 1, &state); | ||
| 3607 | if (count < 0) | ||
| 3608 | /* Invalid or incomplete multibyte character. */ | ||
| 3609 | goto fail_with_EILSEQ; | ||
| 3610 | |||
| 3611 | if (1 < width && !(flags & FLAG_LEFT)) | ||
| 3612 | { | ||
| 3613 | size_t n = width - 1; | ||
| 3614 | ENSURE_ALLOCATION (xsum (length, n)); | ||
| 3615 | DCHAR_SET (result + length, ' ', n); | ||
| 3616 | length += n; | ||
| 3617 | } | ||
| 3618 | |||
| 3619 | ENSURE_ALLOCATION (xsum (length, 1)); | ||
| 3620 | result[length++] = wc; | ||
| 3621 | |||
| 3622 | if (1 < width && (flags & FLAG_LEFT)) | ||
| 3623 | { | ||
| 3624 | size_t n = width - 1; | ||
| 3625 | ENSURE_ALLOCATION (xsum (length, n)); | ||
| 3626 | DCHAR_SET (result + length, ' ', n); | ||
| 3627 | length += n; | ||
| 3628 | } | ||
| 3629 | } | ||
| 3630 | } | ||
| 3631 | #endif | ||
| 3632 | #if NEED_PRINTF_DIRECTIVE_B || NEED_PRINTF_DIRECTIVE_UPPERCASE_B | ||
| 3633 | else if (0 | ||
| 3634 | # if NEED_PRINTF_DIRECTIVE_B | ||
| 3635 | || (dp->conversion == 'b') | ||
| 3636 | # endif | ||
| 3637 | # if NEED_PRINTF_DIRECTIVE_UPPERCASE_B | ||
| 3638 | || (dp->conversion == 'B') | ||
| 3639 | # endif | ||
| 3640 | ) | ||
| 3641 | { | ||
| 3642 | arg_type type = a.arg[dp->arg_index].type; | ||
| 3643 | int flags = dp->flags; | ||
| 3644 | int has_width; | ||
| 3645 | size_t width; | ||
| 3646 | int has_precision; | ||
| 3647 | size_t precision; | ||
| 3648 | size_t tmp_length; | ||
| 3649 | size_t count; | ||
| 3650 | DCHAR_T tmpbuf[700]; | ||
| 3651 | DCHAR_T *tmp; | ||
| 3652 | DCHAR_T *tmp_end; | ||
| 3653 | DCHAR_T *tmp_start; | ||
| 3654 | DCHAR_T *pad_ptr; | ||
| 3655 | DCHAR_T *p; | ||
| 3656 | |||
| 3657 | has_width = 0; | ||
| 3658 | width = 0; | ||
| 3659 | if (dp->width_start != dp->width_end) | ||
| 3660 | { | ||
| 3661 | if (dp->width_arg_index != ARG_NONE) | ||
| 3662 | { | ||
| 3663 | int arg; | ||
| 3664 | |||
| 3665 | if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) | ||
| 3666 | abort (); | ||
| 3667 | arg = a.arg[dp->width_arg_index].a.a_int; | ||
| 3668 | width = arg; | ||
| 3669 | if (arg < 0) | ||
| 3670 | { | ||
| 3671 | /* "A negative field width is taken as a '-' flag | ||
| 3672 | followed by a positive field width." */ | ||
| 3673 | flags |= FLAG_LEFT; | ||
| 3674 | width = -width; | ||
| 3675 | } | ||
| 3676 | } | ||
| 3677 | else | ||
| 3678 | { | ||
| 3679 | const FCHAR_T *digitp = dp->width_start; | ||
| 3680 | |||
| 3681 | do | ||
| 3682 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | ||
| 3683 | while (digitp != dp->width_end); | ||
| 3684 | } | ||
| 3685 | has_width = 1; | ||
| 3686 | } | ||
| 3687 | |||
| 3688 | has_precision = 0; | ||
| 3689 | precision = 1; | ||
| 3690 | if (dp->precision_start != dp->precision_end) | ||
| 3691 | { | ||
| 3692 | if (dp->precision_arg_index != ARG_NONE) | ||
| 3693 | { | ||
| 3694 | int arg; | ||
| 3695 | |||
| 3696 | if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) | ||
| 3697 | abort (); | ||
| 3698 | arg = a.arg[dp->precision_arg_index].a.a_int; | ||
| 3699 | /* "A negative precision is taken as if the precision | ||
| 3700 | were omitted." */ | ||
| 3701 | if (arg >= 0) | ||
| 3702 | { | ||
| 3703 | precision = arg; | ||
| 3704 | has_precision = 1; | ||
| 3705 | } | ||
| 3706 | } | ||
| 3707 | else | ||
| 3708 | { | ||
| 3709 | const FCHAR_T *digitp = dp->precision_start + 1; | ||
| 3710 | |||
| 3711 | precision = 0; | ||
| 3712 | while (digitp != dp->precision_end) | ||
| 3713 | precision = xsum (xtimes (precision, 10), *digitp++ - '0'); | ||
| 3714 | has_precision = 1; | ||
| 3715 | } | ||
| 3716 | } | ||
| 3717 | |||
| 3718 | /* Allocate a temporary buffer of sufficient size. */ | ||
| 3719 | switch (type) | ||
| 3720 | { | ||
| 3721 | default: | ||
| 3722 | tmp_length = | ||
| 3723 | (unsigned int) (sizeof (unsigned int) * CHAR_BIT) | ||
| 3724 | + 1; /* turn floor into ceil */ | ||
| 3725 | break; | ||
| 3726 | case TYPE_ULONGINT: | ||
| 3727 | tmp_length = | ||
| 3728 | (unsigned int) (sizeof (unsigned long int) * CHAR_BIT) | ||
| 3729 | + 1; /* turn floor into ceil */ | ||
| 3730 | break; | ||
| 3731 | case TYPE_ULONGLONGINT: | ||
| 3732 | tmp_length = | ||
| 3733 | (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT) | ||
| 3734 | + 1; /* turn floor into ceil */ | ||
| 3735 | break; | ||
| 3736 | case TYPE_UINT8_T: | ||
| 3737 | tmp_length = | ||
| 3738 | (unsigned int) (sizeof (uint8_t) * CHAR_BIT) | ||
| 3739 | + 1; /* turn floor into ceil */ | ||
| 3740 | break; | ||
| 3741 | case TYPE_UINT16_T: | ||
| 3742 | tmp_length = | ||
| 3743 | (unsigned int) (sizeof (uint16_t) * CHAR_BIT) | ||
| 3744 | + 1; /* turn floor into ceil */ | ||
| 3745 | break; | ||
| 3746 | case TYPE_UINT32_T: | ||
| 3747 | tmp_length = | ||
| 3748 | (unsigned int) (sizeof (uint32_t) * CHAR_BIT) | ||
| 3749 | + 1; /* turn floor into ceil */ | ||
| 3750 | break; | ||
| 3751 | case TYPE_UINT64_T: | ||
| 3752 | tmp_length = | ||
| 3753 | (unsigned int) (sizeof (uint64_t) * CHAR_BIT) | ||
| 3754 | + 1; /* turn floor into ceil */ | ||
| 3755 | break; | ||
| 3756 | case TYPE_UINT_FAST8_T: | ||
| 3757 | tmp_length = | ||
| 3758 | (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT) | ||
| 3759 | + 1; /* turn floor into ceil */ | ||
| 3760 | break; | ||
| 3761 | case TYPE_UINT_FAST16_T: | ||
| 3762 | tmp_length = | ||
| 3763 | (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT) | ||
| 3764 | + 1; /* turn floor into ceil */ | ||
| 3765 | break; | ||
| 3766 | case TYPE_UINT_FAST32_T: | ||
| 3767 | tmp_length = | ||
| 3768 | (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT) | ||
| 3769 | + 1; /* turn floor into ceil */ | ||
| 3770 | break; | ||
| 3771 | case TYPE_UINT_FAST64_T: | ||
| 3772 | tmp_length = | ||
| 3773 | (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT) | ||
| 3774 | + 1; /* turn floor into ceil */ | ||
| 3775 | break; | ||
| 3776 | } | ||
| 3777 | if (tmp_length < precision) | ||
| 3778 | tmp_length = precision; | ||
| 3779 | /* Add 2, to account for a prefix from the alternate form. */ | ||
| 3780 | tmp_length = xsum (tmp_length, 2); | ||
| 3781 | |||
| 3782 | if (tmp_length < width) | ||
| 3783 | tmp_length = width; | ||
| 3784 | |||
| 3785 | if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) | ||
| 3786 | tmp = tmpbuf; | ||
| 3787 | else | ||
| 3788 | { | ||
| 3789 | size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); | ||
| 3790 | |||
| 3791 | if (size_overflow_p (tmp_memsize)) | ||
| 3792 | /* Overflow, would lead to out of memory. */ | ||
| 3793 | goto out_of_memory; | ||
| 3794 | tmp = (DCHAR_T *) malloc (tmp_memsize); | ||
| 3795 | if (tmp == NULL) | ||
| 3796 | /* Out of memory. */ | ||
| 3797 | goto out_of_memory; | ||
| 3798 | } | ||
| 3799 | |||
| 3800 | tmp_end = tmp + tmp_length; | ||
| 3801 | |||
| 3802 | unsigned long long arg; | ||
| 3803 | switch (type) | ||
| 3804 | { | ||
| 3805 | case TYPE_UCHAR: | ||
| 3806 | arg = a.arg[dp->arg_index].a.a_uchar; | ||
| 3807 | break; | ||
| 3808 | case TYPE_USHORT: | ||
| 3809 | arg = a.arg[dp->arg_index].a.a_ushort; | ||
| 3810 | break; | ||
| 3811 | case TYPE_UINT: | ||
| 3812 | arg = a.arg[dp->arg_index].a.a_uint; | ||
| 3813 | break; | ||
| 3814 | case TYPE_ULONGINT: | ||
| 3815 | arg = a.arg[dp->arg_index].a.a_ulongint; | ||
| 3816 | break; | ||
| 3817 | case TYPE_ULONGLONGINT: | ||
| 3818 | arg = a.arg[dp->arg_index].a.a_ulonglongint; | ||
| 3819 | break; | ||
| 3820 | case TYPE_UINT8_T: | ||
| 3821 | arg = a.arg[dp->arg_index].a.a_uint8_t; | ||
| 3822 | break; | ||
| 3823 | case TYPE_UINT16_T: | ||
| 3824 | arg = a.arg[dp->arg_index].a.a_uint16_t; | ||
| 3825 | break; | ||
| 3826 | case TYPE_UINT32_T: | ||
| 3827 | arg = a.arg[dp->arg_index].a.a_uint32_t; | ||
| 3828 | break; | ||
| 3829 | case TYPE_UINT64_T: | ||
| 3830 | arg = a.arg[dp->arg_index].a.a_uint64_t; | ||
| 3831 | break; | ||
| 3832 | case TYPE_UINT_FAST8_T: | ||
| 3833 | arg = a.arg[dp->arg_index].a.a_uint_fast8_t; | ||
| 3834 | break; | ||
| 3835 | case TYPE_UINT_FAST16_T: | ||
| 3836 | arg = a.arg[dp->arg_index].a.a_uint_fast16_t; | ||
| 3837 | break; | ||
| 3838 | case TYPE_UINT_FAST32_T: | ||
| 3839 | arg = a.arg[dp->arg_index].a.a_uint_fast32_t; | ||
| 3840 | break; | ||
| 3841 | case TYPE_UINT_FAST64_T: | ||
| 3842 | arg = a.arg[dp->arg_index].a.a_uint_fast64_t; | ||
| 3843 | break; | ||
| 3844 | default: | ||
| 3845 | abort (); | ||
| 3846 | } | ||
| 3847 | int need_prefix = ((flags & FLAG_ALT) && arg != 0); | ||
| 3848 | |||
| 3849 | p = tmp_end; | ||
| 3850 | /* "The result of converting a zero value with a precision | ||
| 3851 | of zero is no characters." */ | ||
| 3852 | if (!(has_precision && precision == 0 && arg == 0)) | ||
| 3853 | { | ||
| 3854 | do | ||
| 3855 | { | ||
| 3856 | *--p = '0' + (arg & 1); | ||
| 3857 | arg = arg >> 1; | ||
| 3858 | } | ||
| 3859 | while (arg != 0); | ||
| 3860 | } | ||
| 3861 | |||
| 3862 | if (has_precision) | ||
| 3863 | { | ||
| 3864 | DCHAR_T *digits_start = tmp_end - precision; | ||
| 3865 | while (p > digits_start) | ||
| 3866 | *--p = '0'; | ||
| 3867 | } | ||
| 3868 | |||
| 3869 | pad_ptr = p; | ||
| 3870 | |||
| 3871 | if (need_prefix) | ||
| 3872 | { | ||
| 3873 | # if NEED_PRINTF_DIRECTIVE_B && !NEED_PRINTF_DIRECTIVE_UPPERCASE_B | ||
| 3874 | *--p = 'b'; | ||
| 3875 | # elif NEED_PRINTF_DIRECTIVE_UPPERCASE_B && !NEED_PRINTF_DIRECTIVE_B | ||
| 3876 | *--p = 'B'; | ||
| 3877 | # else | ||
| 3878 | *--p = dp->conversion; | ||
| 3879 | # endif | ||
| 3880 | *--p = '0'; | ||
| 3881 | } | ||
| 3882 | tmp_start = p; | ||
| 3883 | |||
| 3884 | /* The generated string now extends from tmp_start to tmp_end, | ||
| 3885 | with the zero padding insertion point being at pad_ptr, | ||
| 3886 | tmp_start <= pad_ptr <= tmp_end. */ | ||
| 3887 | count = tmp_end - tmp_start; | ||
| 3888 | |||
| 3889 | if (count < width) | ||
| 3890 | { | ||
| 3891 | size_t pad = width - count; | ||
| 3892 | |||
| 3893 | if (flags & FLAG_LEFT) | ||
| 3894 | { | ||
| 3895 | /* Pad with spaces on the right. */ | ||
| 3896 | for (p = tmp_start; p < tmp_end; p++) | ||
| 3897 | *(p - pad) = *p; | ||
| 3898 | for (p = tmp_end - pad; p < tmp_end; p++) | ||
| 3899 | *p = ' '; | ||
| 3900 | } | ||
| 3901 | else if ((flags & FLAG_ZERO) | ||
| 3902 | /* Neither ISO C nor POSIX specify that the '0' | ||
| 3903 | flag is ignored when a width and a precision | ||
| 3904 | are both present. But most implementations | ||
| 3905 | do so. */ | ||
| 3906 | && !(has_width && has_precision)) | ||
| 3907 | { | ||
| 3908 | /* Pad with zeroes. */ | ||
| 3909 | for (p = tmp_start; p < pad_ptr; p++) | ||
| 3910 | *(p - pad) = *p; | ||
| 3911 | for (p = pad_ptr - pad; p < pad_ptr; p++) | ||
| 3912 | *p = '0'; | ||
| 3913 | } | ||
| 3914 | else | ||
| 3915 | { | ||
| 3916 | /* Pad with spaces on the left. */ | ||
| 3917 | for (p = tmp_start - pad; p < tmp_start; p++) | ||
| 3918 | *p = ' '; | ||
| 3919 | } | ||
| 3920 | |||
| 3921 | tmp_start = tmp_start - pad; | ||
| 3922 | } | ||
| 3923 | |||
| 3924 | count = tmp_end - tmp_start; | ||
| 3925 | |||
| 3926 | if (count > tmp_length) | ||
| 3927 | /* tmp_length was incorrectly calculated - fix the | ||
| 3928 | code above! */ | ||
| 3929 | abort (); | ||
| 3930 | |||
| 3931 | /* Make room for the result. */ | ||
| 3932 | if (count >= allocated - length) | ||
| 3933 | { | ||
| 3934 | size_t n = xsum (length, count); | ||
| 3935 | |||
| 3936 | ENSURE_ALLOCATION (n); | ||
| 3937 | } | ||
| 3938 | |||
| 3939 | /* Append the result. */ | ||
| 3940 | memcpy (result + length, tmp_start, count * sizeof (DCHAR_T)); | ||
| 3941 | if (tmp != tmpbuf) | ||
| 3942 | free (tmp); | ||
| 3943 | length += count; | ||
| 3944 | } | ||
| 3945 | #endif | ||
| 3946 | #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) | ||
| 3047 | else if ((dp->conversion == 'a' || dp->conversion == 'A') | 3947 | else if ((dp->conversion == 'a' || dp->conversion == 'A') |
| 3048 | # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE)) | 3948 | # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE)) |
| 3049 | && (0 | 3949 | && (0 |
| 3050 | # if NEED_PRINTF_DOUBLE | 3950 | # if NEED_PRINTF_DOUBLE |
| 3051 | || a.arg[dp->arg_index].type == TYPE_DOUBLE | 3951 | || a.arg[dp->arg_index].type == TYPE_DOUBLE |
| 3052 | # endif | 3952 | # endif |
| 3053 | # if NEED_PRINTF_LONG_DOUBLE | 3953 | # if NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) |
| 3054 | || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE | 3954 | || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE |
| 3055 | # endif | 3955 | # endif |
| 3056 | ) | 3956 | ) |
| @@ -3170,7 +4070,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3170 | p = tmp; | 4070 | p = tmp; |
| 3171 | if (type == TYPE_LONGDOUBLE) | 4071 | if (type == TYPE_LONGDOUBLE) |
| 3172 | { | 4072 | { |
| 3173 | # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE | 4073 | # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) |
| 3174 | long double arg = a.arg[dp->arg_index].a.a_longdouble; | 4074 | long double arg = a.arg[dp->arg_index].a.a_longdouble; |
| 3175 | 4075 | ||
| 3176 | if (isnanl (arg)) | 4076 | if (isnanl (arg)) |
| @@ -3290,7 +4190,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3290 | } | 4190 | } |
| 3291 | } | 4191 | } |
| 3292 | *p++ = dp->conversion - 'A' + 'P'; | 4192 | *p++ = dp->conversion - 'A' + 'P'; |
| 3293 | # if WIDE_CHAR_VERSION | 4193 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR |
| 3294 | { | 4194 | { |
| 3295 | static const wchar_t decimal_format[] = | 4195 | static const wchar_t decimal_format[] = |
| 3296 | { '%', '+', 'd', '\0' }; | 4196 | { '%', '+', 'd', '\0' }; |
| @@ -3441,7 +4341,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3441 | } | 4341 | } |
| 3442 | } | 4342 | } |
| 3443 | *p++ = dp->conversion - 'A' + 'P'; | 4343 | *p++ = dp->conversion - 'A' + 'P'; |
| 3444 | # if WIDE_CHAR_VERSION | 4344 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR |
| 3445 | { | 4345 | { |
| 3446 | static const wchar_t decimal_format[] = | 4346 | static const wchar_t decimal_format[] = |
| 3447 | { '%', '+', 'd', '\0' }; | 4347 | { '%', '+', 'd', '\0' }; |
| @@ -3533,7 +4433,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3533 | length += count; | 4433 | length += count; |
| 3534 | } | 4434 | } |
| 3535 | #endif | 4435 | #endif |
| 3536 | #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL | 4436 | #if NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE |
| 3537 | else if ((dp->conversion == 'f' || dp->conversion == 'F' | 4437 | else if ((dp->conversion == 'f' || dp->conversion == 'F' |
| 3538 | || dp->conversion == 'e' || dp->conversion == 'E' | 4438 | || dp->conversion == 'e' || dp->conversion == 'E' |
| 3539 | || dp->conversion == 'g' || dp->conversion == 'G' | 4439 | || dp->conversion == 'g' || dp->conversion == 'G' |
| @@ -3901,7 +4801,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3901 | } | 4801 | } |
| 3902 | 4802 | ||
| 3903 | *p++ = dp->conversion; /* 'e' or 'E' */ | 4803 | *p++ = dp->conversion; /* 'e' or 'E' */ |
| 3904 | # if WIDE_CHAR_VERSION | 4804 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR |
| 3905 | { | 4805 | { |
| 3906 | static const wchar_t decimal_format[] = | 4806 | static const wchar_t decimal_format[] = |
| 3907 | { '%', '+', '.', '2', 'd', '\0' }; | 4807 | { '%', '+', '.', '2', 'd', '\0' }; |
| @@ -4082,7 +4982,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4082 | } | 4982 | } |
| 4083 | } | 4983 | } |
| 4084 | *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ | 4984 | *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ |
| 4085 | # if WIDE_CHAR_VERSION | 4985 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR |
| 4086 | { | 4986 | { |
| 4087 | static const wchar_t decimal_format[] = | 4987 | static const wchar_t decimal_format[] = |
| 4088 | { '%', '+', '.', '2', 'd', '\0' }; | 4988 | { '%', '+', '.', '2', 'd', '\0' }; |
| @@ -4359,7 +5259,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4359 | } | 5259 | } |
| 4360 | 5260 | ||
| 4361 | *p++ = dp->conversion; /* 'e' or 'E' */ | 5261 | *p++ = dp->conversion; /* 'e' or 'E' */ |
| 4362 | # if WIDE_CHAR_VERSION | 5262 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR |
| 4363 | { | 5263 | { |
| 4364 | static const wchar_t decimal_format[] = | 5264 | static const wchar_t decimal_format[] = |
| 4365 | /* Produce the same number of exponent digits | 5265 | /* Produce the same number of exponent digits |
| @@ -4552,7 +5452,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4552 | } | 5452 | } |
| 4553 | } | 5453 | } |
| 4554 | *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ | 5454 | *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ |
| 4555 | # if WIDE_CHAR_VERSION | 5455 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR |
| 4556 | { | 5456 | { |
| 4557 | static const wchar_t decimal_format[] = | 5457 | static const wchar_t decimal_format[] = |
| 4558 | /* Produce the same number of exponent digits | 5458 | /* Produce the same number of exponent digits |
| @@ -4720,24 +5620,24 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4720 | { | 5620 | { |
| 4721 | arg_type type = a.arg[dp->arg_index].type; | 5621 | arg_type type = a.arg[dp->arg_index].type; |
| 4722 | int flags = dp->flags; | 5622 | int flags = dp->flags; |
| 4723 | #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 5623 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4724 | int has_width; | 5624 | int has_width; |
| 4725 | #endif | 5625 | #endif |
| 4726 | #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 5626 | #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4727 | size_t width; | 5627 | size_t width; |
| 4728 | #endif | 5628 | #endif |
| 4729 | #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION | 5629 | #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4730 | int has_precision; | 5630 | int has_precision; |
| 4731 | size_t precision; | 5631 | size_t precision; |
| 4732 | #endif | 5632 | #endif |
| 4733 | #if NEED_PRINTF_UNBOUNDED_PRECISION | 5633 | #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4734 | int prec_ourselves; | 5634 | int prec_ourselves; |
| 4735 | #else | 5635 | #else |
| 4736 | # define prec_ourselves 0 | 5636 | # define prec_ourselves 0 |
| 4737 | #endif | 5637 | #endif |
| 4738 | #if NEED_PRINTF_FLAG_LEFTADJUST | 5638 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST |
| 4739 | # define pad_ourselves 1 | 5639 | # define pad_ourselves 1 |
| 4740 | #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 5640 | #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4741 | int pad_ourselves; | 5641 | int pad_ourselves; |
| 4742 | #else | 5642 | #else |
| 4743 | # define pad_ourselves 0 | 5643 | # define pad_ourselves 0 |
| @@ -4752,10 +5652,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4752 | TCHAR_T *tmp; | 5652 | TCHAR_T *tmp; |
| 4753 | #endif | 5653 | #endif |
| 4754 | 5654 | ||
| 4755 | #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 5655 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4756 | has_width = 0; | 5656 | has_width = 0; |
| 4757 | #endif | 5657 | #endif |
| 4758 | #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 5658 | #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4759 | width = 0; | 5659 | width = 0; |
| 4760 | if (dp->width_start != dp->width_end) | 5660 | if (dp->width_start != dp->width_end) |
| 4761 | { | 5661 | { |
| @@ -4783,13 +5683,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4783 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 5683 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 4784 | while (digitp != dp->width_end); | 5684 | while (digitp != dp->width_end); |
| 4785 | } | 5685 | } |
| 4786 | #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 5686 | # if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4787 | has_width = 1; | 5687 | has_width = 1; |
| 4788 | #endif | 5688 | # endif |
| 4789 | } | 5689 | } |
| 4790 | #endif | 5690 | #endif |
| 4791 | 5691 | ||
| 4792 | #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION | 5692 | #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4793 | has_precision = 0; | 5693 | has_precision = 0; |
| 4794 | precision = 6; | 5694 | precision = 6; |
| 4795 | if (dp->precision_start != dp->precision_end) | 5695 | if (dp->precision_start != dp->precision_end) |
| @@ -4822,14 +5722,32 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4822 | #endif | 5722 | #endif |
| 4823 | 5723 | ||
| 4824 | /* Decide whether to handle the precision ourselves. */ | 5724 | /* Decide whether to handle the precision ourselves. */ |
| 4825 | #if NEED_PRINTF_UNBOUNDED_PRECISION | 5725 | #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 4826 | switch (dp->conversion) | 5726 | switch (dp->conversion) |
| 4827 | { | 5727 | { |
| 5728 | # if NEED_PRINTF_UNBOUNDED_PRECISION | ||
| 4828 | case 'd': case 'i': case 'u': | 5729 | case 'd': case 'i': case 'u': |
| 5730 | case 'b': | ||
| 5731 | #if SUPPORT_GNU_PRINTF_DIRECTIVES \ | ||
| 5732 | || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2) | ||
| 5733 | case 'B': | ||
| 5734 | #endif | ||
| 4829 | case 'o': | 5735 | case 'o': |
| 4830 | case 'x': case 'X': case 'p': | ||
| 4831 | prec_ourselves = has_precision && (precision > 0); | 5736 | prec_ourselves = has_precision && (precision > 0); |
| 4832 | break; | 5737 | break; |
| 5738 | # endif | ||
| 5739 | case 'x': case 'X': case 'p': | ||
| 5740 | prec_ourselves = | ||
| 5741 | has_precision | ||
| 5742 | && (0 | ||
| 5743 | # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO | ||
| 5744 | || (precision == 0) | ||
| 5745 | # endif | ||
| 5746 | # if NEED_PRINTF_UNBOUNDED_PRECISION | ||
| 5747 | || (precision > 0) | ||
| 5748 | # endif | ||
| 5749 | ); | ||
| 5750 | break; | ||
| 4833 | default: | 5751 | default: |
| 4834 | prec_ourselves = 0; | 5752 | prec_ourselves = 0; |
| 4835 | break; | 5753 | break; |
| @@ -4837,7 +5755,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4837 | #endif | 5755 | #endif |
| 4838 | 5756 | ||
| 4839 | /* Decide whether to perform the padding ourselves. */ | 5757 | /* Decide whether to perform the padding ourselves. */ |
| 4840 | #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION) | 5758 | #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) |
| 4841 | switch (dp->conversion) | 5759 | switch (dp->conversion) |
| 4842 | { | 5760 | { |
| 4843 | # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO | 5761 | # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO |
| @@ -4956,6 +5874,54 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4956 | { | 5874 | { |
| 4957 | case TYPE_LONGLONGINT: | 5875 | case TYPE_LONGLONGINT: |
| 4958 | case TYPE_ULONGLONGINT: | 5876 | case TYPE_ULONGLONGINT: |
| 5877 | #if INT8_WIDTH > LONG_WIDTH | ||
| 5878 | case TYPE_INT8_T: | ||
| 5879 | #endif | ||
| 5880 | #if UINT8_WIDTH > LONG_WIDTH | ||
| 5881 | case TYPE_UINT8_T: | ||
| 5882 | #endif | ||
| 5883 | #if INT16_WIDTH > LONG_WIDTH | ||
| 5884 | case TYPE_INT16_T: | ||
| 5885 | #endif | ||
| 5886 | #if UINT16_WIDTH > LONG_WIDTH | ||
| 5887 | case TYPE_UINT16_T: | ||
| 5888 | #endif | ||
| 5889 | #if INT32_WIDTH > LONG_WIDTH | ||
| 5890 | case TYPE_INT32_T: | ||
| 5891 | #endif | ||
| 5892 | #if UINT32_WIDTH > LONG_WIDTH | ||
| 5893 | case TYPE_UINT32_T: | ||
| 5894 | #endif | ||
| 5895 | #if INT64_WIDTH > LONG_WIDTH | ||
| 5896 | case TYPE_INT64_T: | ||
| 5897 | #endif | ||
| 5898 | #if UINT64_WIDTH > LONG_WIDTH | ||
| 5899 | case TYPE_UINT64_T: | ||
| 5900 | #endif | ||
| 5901 | #if INT_FAST8_WIDTH > LONG_WIDTH | ||
| 5902 | case TYPE_INT_FAST8_T: | ||
| 5903 | #endif | ||
| 5904 | #if UINT_FAST8_WIDTH > LONG_WIDTH | ||
| 5905 | case TYPE_UINT_FAST8_T: | ||
| 5906 | #endif | ||
| 5907 | #if INT_FAST16_WIDTH > LONG_WIDTH | ||
| 5908 | case TYPE_INT_FAST16_T: | ||
| 5909 | #endif | ||
| 5910 | #if UINT_FAST16_WIDTH > LONG_WIDTH | ||
| 5911 | case TYPE_UINT_FAST16_T: | ||
| 5912 | #endif | ||
| 5913 | #if INT_FAST32_WIDTH > LONG_WIDTH | ||
| 5914 | case TYPE_INT3_FAST2_T: | ||
| 5915 | #endif | ||
| 5916 | #if UINT_FAST32_WIDTH > LONG_WIDTH | ||
| 5917 | case TYPE_UINT_FAST32_T: | ||
| 5918 | #endif | ||
| 5919 | #if INT_FAST64_WIDTH > LONG_WIDTH | ||
| 5920 | case TYPE_INT_FAST64_T: | ||
| 5921 | #endif | ||
| 5922 | #if UINT_FAST64_WIDTH > LONG_WIDTH | ||
| 5923 | case TYPE_UINT_FAST64_T: | ||
| 5924 | #endif | ||
| 4959 | #if defined _WIN32 && ! defined __CYGWIN__ | 5925 | #if defined _WIN32 && ! defined __CYGWIN__ |
| 4960 | *fbp++ = 'I'; | 5926 | *fbp++ = 'I'; |
| 4961 | *fbp++ = '6'; | 5927 | *fbp++ = '6'; |
| @@ -4967,12 +5933,60 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4967 | FALLTHROUGH; | 5933 | FALLTHROUGH; |
| 4968 | case TYPE_LONGINT: | 5934 | case TYPE_LONGINT: |
| 4969 | case TYPE_ULONGINT: | 5935 | case TYPE_ULONGINT: |
| 4970 | #if HAVE_WINT_T | 5936 | #if INT8_WIDTH > INT_WIDTH && INT8_WIDTH <= LONG_WIDTH |
| 5937 | case TYPE_INT8_T: | ||
| 5938 | #endif | ||
| 5939 | #if UINT8_WIDTH > INT_WIDTH && UINT8_WIDTH <= LONG_WIDTH | ||
| 5940 | case TYPE_UINT8_T: | ||
| 5941 | #endif | ||
| 5942 | #if INT16_WIDTH > INT_WIDTH && INT16_WIDTH <= LONG_WIDTH | ||
| 5943 | case TYPE_INT16_T: | ||
| 5944 | #endif | ||
| 5945 | #if UINT16_WIDTH > INT_WIDTH && UINT16_WIDTH <= LONG_WIDTH | ||
| 5946 | case TYPE_UINT16_T: | ||
| 5947 | #endif | ||
| 5948 | #if INT32_WIDTH > INT_WIDTH && INT32_WIDTH <= LONG_WIDTH | ||
| 5949 | case TYPE_INT32_T: | ||
| 5950 | #endif | ||
| 5951 | #if UINT32_WIDTH > INT_WIDTH && UINT32_WIDTH <= LONG_WIDTH | ||
| 5952 | case TYPE_UINT32_T: | ||
| 5953 | #endif | ||
| 5954 | #if INT64_WIDTH > INT_WIDTH && INT64_WIDTH <= LONG_WIDTH | ||
| 5955 | case TYPE_INT64_T: | ||
| 5956 | #endif | ||
| 5957 | #if UINT64_WIDTH > INT_WIDTH && UINT64_WIDTH <= LONG_WIDTH | ||
| 5958 | case TYPE_UINT64_T: | ||
| 5959 | #endif | ||
| 5960 | #if INT_FAST8_WIDTH > INT_WIDTH && INT_FAST8_WIDTH <= LONG_WIDTH | ||
| 5961 | case TYPE_INT_FAST8_T: | ||
| 5962 | #endif | ||
| 5963 | #if UINT_FAST8_WIDTH > INT_WIDTH && UINT_FAST8_WIDTH <= LONG_WIDTH | ||
| 5964 | case TYPE_UINT_FAST8_T: | ||
| 5965 | #endif | ||
| 5966 | #if INT_FAST16_WIDTH > INT_WIDTH && INT_FAST16_WIDTH <= LONG_WIDTH | ||
| 5967 | case TYPE_INT_FAST16_T: | ||
| 5968 | #endif | ||
| 5969 | #if UINT_FAST16_WIDTH > INT_WIDTH && UINT_FAST16_WIDTH <= LONG_WIDTH | ||
| 5970 | case TYPE_UINT_FAST16_T: | ||
| 5971 | #endif | ||
| 5972 | #if INT_FAST32_WIDTH > INT_WIDTH && INT_FAST32_WIDTH <= LONG_WIDTH | ||
| 5973 | case TYPE_INT_FAST32_T: | ||
| 5974 | #endif | ||
| 5975 | #if UINT_FAST32_WIDTH > INT_WIDTH && UINT_FAST32_WIDTH <= LONG_WIDTH | ||
| 5976 | case TYPE_UINT_FAST32_T: | ||
| 5977 | #endif | ||
| 5978 | #if INT_FAST64_WIDTH > INT_WIDTH && INT_FAST64_WIDTH <= LONG_WIDTH | ||
| 5979 | case TYPE_INT_FAST64_T: | ||
| 5980 | #endif | ||
| 5981 | #if UINT_FAST64_WIDTH > INT_WIDTH && UINT_FAST64_WIDTH <= LONG_WIDTH | ||
| 5982 | case TYPE_UINT_FAST64_T: | ||
| 5983 | #endif | ||
| 5984 | #if HAVE_WINT_T | ||
| 4971 | case TYPE_WIDE_CHAR: | 5985 | case TYPE_WIDE_CHAR: |
| 4972 | #endif | 5986 | #endif |
| 4973 | #if HAVE_WCHAR_T | 5987 | #if HAVE_WCHAR_T |
| 4974 | case TYPE_WIDE_STRING: | 5988 | case TYPE_WIDE_STRING: |
| 4975 | #endif | 5989 | #endif |
| 4976 | *fbp++ = 'l'; | 5990 | *fbp++ = 'l'; |
| 4977 | break; | 5991 | break; |
| 4978 | case TYPE_LONGDOUBLE: | 5992 | case TYPE_LONGDOUBLE: |
| @@ -4988,47 +6002,74 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4988 | #endif | 6002 | #endif |
| 4989 | *fbp = dp->conversion; | 6003 | *fbp = dp->conversion; |
| 4990 | #if USE_SNPRINTF | 6004 | #if USE_SNPRINTF |
| 4991 | # if ((HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99) \ | 6005 | /* Decide whether to pass %n in the format string |
| 6006 | to SNPRINTF. */ | ||
| 6007 | # if (((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR) \ | ||
| 6008 | && (HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99)) \ | ||
| 4992 | || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \ | 6009 | || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \ |
| 4993 | && !defined __UCLIBC__) \ | 6010 | && !defined __UCLIBC__) \ |
| 4994 | || (defined __APPLE__ && defined __MACH__) \ | 6011 | || (defined __APPLE__ && defined __MACH__) \ |
| 6012 | || defined __OpenBSD__ \ | ||
| 4995 | || defined __ANDROID__ \ | 6013 | || defined __ANDROID__ \ |
| 4996 | || (defined _WIN32 && ! defined __CYGWIN__)) | 6014 | || (defined _WIN32 && ! defined __CYGWIN__)) \ |
| 4997 | /* On systems where we know that snprintf's return value | 6015 | || (WIDE_CHAR_VERSION && MUSL_LIBC) |
| 4998 | conforms to ISO C 99 (HAVE_SNPRINTF_RETVAL_C99) and that | 6016 | /* We can avoid passing %n and instead rely on SNPRINTF's |
| 4999 | snprintf always produces NUL-terminated strings | 6017 | return value if |
| 5000 | (HAVE_SNPRINTF_TRUNCATION_C99), it is possible to avoid | 6018 | - !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR, because otherwise, |
| 5001 | using %n. And it is desirable to do so, because more and | 6019 | when WIDE_CHAR_VERSION && DCHAR_IS_TCHAR, |
| 5002 | more platforms no longer support %n, for "security reasons". | 6020 | snwprintf()/_snwprintf() (Windows) and swprintf() (Unix) |
| 5003 | In particular, the following platforms: | 6021 | don't return the needed buffer size, |
| 6022 | and | ||
| 6023 | - we're compiling for a system where we know | ||
| 6024 | - that snprintf's return value conforms to ISO C 99 | ||
| 6025 | (HAVE_SNPRINTF_RETVAL_C99) and | ||
| 6026 | - that snprintf always produces NUL-terminated strings | ||
| 6027 | (HAVE_SNPRINTF_TRUNCATION_C99). | ||
| 6028 | And it is desirable to do so, because more and more platforms | ||
| 6029 | no longer support %n, for "security reasons". */ | ||
| 6030 | /* On specific platforms, listed below, we *must* avoid %n. | ||
| 6031 | In the case | ||
| 6032 | !WIDE_CHAR_VERSION && HAVE_SNPRINTF_RETVAL_C99 && !USE_MSVC__SNPRINTF | ||
| 6033 | we can rely on the return value of snprintf instead. Whereas | ||
| 6034 | in the opposite case | ||
| 6035 | WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF | ||
| 6036 | we need to make room based on an estimation, computed by | ||
| 6037 | MAX_ROOM_NEEDED. */ | ||
| 6038 | /* The following platforms forbid %n: | ||
| 5004 | - On glibc2 systems from 2004-10-18 or newer, the use of | 6039 | - On glibc2 systems from 2004-10-18 or newer, the use of |
| 5005 | %n in format strings in writable memory may crash the | 6040 | %n in format strings in writable memory may crash the |
| 5006 | program (if compiled with _FORTIFY_SOURCE=2). | 6041 | program (if compiled with _FORTIFY_SOURCE=2). |
| 5007 | - On Mac OS X 10.13 or newer, the use of %n in format | 6042 | - On macOS 10.13 or newer, the use of %n in format |
| 5008 | strings in writable memory by default crashes the | 6043 | strings in writable memory by default crashes the |
| 5009 | program. | 6044 | program. |
| 6045 | - On OpenBSD, since 2021-08-30, the use of %n in format | ||
| 6046 | strings produces an abort (see | ||
| 6047 | <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfprintf.c.diff?r1=1.79&r2=1.80&f=h>, | ||
| 6048 | <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfwprintf.c.diff?r1=1.20&r2=1.21&f=h>). | ||
| 5010 | - On Android, starting on 2018-03-07, the use of %n in | 6049 | - On Android, starting on 2018-03-07, the use of %n in |
| 5011 | format strings produces a fatal error (see | 6050 | format strings produces a fatal error (see |
| 5012 | <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>). | 6051 | <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>). |
| 5013 | On these platforms, HAVE_SNPRINTF_RETVAL_C99 and | 6052 | - On native Windows systems (such as mingw) where the OS is |
| 5014 | HAVE_SNPRINTF_TRUNCATION_C99 are 1. We have listed them | 6053 | Windows Vista, the use of %n in format strings by default |
| 5015 | explicitly in the condition above, in case of cross- | 6054 | crashes the program. See |
| 5016 | compilation (just to be sure). */ | 6055 | <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and |
| 5017 | /* On native Windows systems (such as mingw), we can avoid using | 6056 | <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output> |
| 5018 | %n because: | 6057 | On the first four of these platforms, if !WIDE_CHAR_VERSION, |
| 6058 | it is not a big deal to avoid %n, because on these platforms, | ||
| 6059 | HAVE_SNPRINTF_RETVAL_C99 and HAVE_SNPRINTF_TRUNCATION_C99 are | ||
| 6060 | 1. | ||
| 6061 | On native Windows, if !WIDE_CHAR_VERSION, it's not a big deal | ||
| 6062 | either because: | ||
| 5019 | - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, | 6063 | - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, |
| 5020 | snprintf does not write more than the specified number | 6064 | snprintf does not write more than the specified number |
| 5021 | of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes | 6065 | of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes |
| 5022 | '4', '5', '6' into buf, not '4', '5', '\0'.) | 6066 | '4', '5', '6' into buf, not '4', '5', '\0'.) |
| 5023 | - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf | 6067 | - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf |
| 5024 | allows us to recognize the case of an insufficient | 6068 | allows us to recognize the case of an insufficient |
| 5025 | buffer size: it returns -1 in this case. | 6069 | buffer size: it returns -1 in this case. */ |
| 5026 | On native Windows systems (such as mingw) where the OS is | 6070 | /* Additionally, in the WIDE_CHAR_VERSION case, we cannot use %n |
| 5027 | Windows Vista, the use of %n in format strings by default | 6071 | on musl libc because we would run into an swprintf() bug. |
| 5028 | crashes the program. See | 6072 | See <https://www.openwall.com/lists/musl/2023/03/19/1>. */ |
| 5029 | <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and | ||
| 5030 | <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output> | ||
| 5031 | So we should avoid %n in this situation. */ | ||
| 5032 | fbp[1] = '\0'; | 6073 | fbp[1] = '\0'; |
| 5033 | # else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */ | 6074 | # else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */ |
| 5034 | fbp[1] = '%'; | 6075 | fbp[1] = '%'; |
| @@ -5189,6 +6230,102 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5189 | SNPRINTF_BUF (arg); | 6230 | SNPRINTF_BUF (arg); |
| 5190 | } | 6231 | } |
| 5191 | break; | 6232 | break; |
| 6233 | case TYPE_INT8_T: | ||
| 6234 | { | ||
| 6235 | int8_t arg = a.arg[dp->arg_index].a.a_int8_t; | ||
| 6236 | SNPRINTF_BUF (arg); | ||
| 6237 | } | ||
| 6238 | break; | ||
| 6239 | case TYPE_UINT8_T: | ||
| 6240 | { | ||
| 6241 | uint8_t arg = a.arg[dp->arg_index].a.a_uint8_t; | ||
| 6242 | SNPRINTF_BUF (arg); | ||
| 6243 | } | ||
| 6244 | break; | ||
| 6245 | case TYPE_INT16_T: | ||
| 6246 | { | ||
| 6247 | int16_t arg = a.arg[dp->arg_index].a.a_int16_t; | ||
| 6248 | SNPRINTF_BUF (arg); | ||
| 6249 | } | ||
| 6250 | break; | ||
| 6251 | case TYPE_UINT16_T: | ||
| 6252 | { | ||
| 6253 | uint16_t arg = a.arg[dp->arg_index].a.a_uint16_t; | ||
| 6254 | SNPRINTF_BUF (arg); | ||
| 6255 | } | ||
| 6256 | break; | ||
| 6257 | case TYPE_INT32_T: | ||
| 6258 | { | ||
| 6259 | int32_t arg = a.arg[dp->arg_index].a.a_int32_t; | ||
| 6260 | SNPRINTF_BUF (arg); | ||
| 6261 | } | ||
| 6262 | break; | ||
| 6263 | case TYPE_UINT32_T: | ||
| 6264 | { | ||
| 6265 | uint32_t arg = a.arg[dp->arg_index].a.a_uint32_t; | ||
| 6266 | SNPRINTF_BUF (arg); | ||
| 6267 | } | ||
| 6268 | break; | ||
| 6269 | case TYPE_INT64_T: | ||
| 6270 | { | ||
| 6271 | int64_t arg = a.arg[dp->arg_index].a.a_int64_t; | ||
| 6272 | SNPRINTF_BUF (arg); | ||
| 6273 | } | ||
| 6274 | break; | ||
| 6275 | case TYPE_UINT64_T: | ||
| 6276 | { | ||
| 6277 | uint64_t arg = a.arg[dp->arg_index].a.a_uint64_t; | ||
| 6278 | SNPRINTF_BUF (arg); | ||
| 6279 | } | ||
| 6280 | break; | ||
| 6281 | case TYPE_INT_FAST8_T: | ||
| 6282 | { | ||
| 6283 | int_fast8_t arg = a.arg[dp->arg_index].a.a_int_fast8_t; | ||
| 6284 | SNPRINTF_BUF (arg); | ||
| 6285 | } | ||
| 6286 | break; | ||
| 6287 | case TYPE_UINT_FAST8_T: | ||
| 6288 | { | ||
| 6289 | uint_fast8_t arg = a.arg[dp->arg_index].a.a_uint_fast8_t; | ||
| 6290 | SNPRINTF_BUF (arg); | ||
| 6291 | } | ||
| 6292 | break; | ||
| 6293 | case TYPE_INT_FAST16_T: | ||
| 6294 | { | ||
| 6295 | int_fast16_t arg = a.arg[dp->arg_index].a.a_int_fast16_t; | ||
| 6296 | SNPRINTF_BUF (arg); | ||
| 6297 | } | ||
| 6298 | break; | ||
| 6299 | case TYPE_UINT_FAST16_T: | ||
| 6300 | { | ||
| 6301 | uint_fast16_t arg = a.arg[dp->arg_index].a.a_uint_fast16_t; | ||
| 6302 | SNPRINTF_BUF (arg); | ||
| 6303 | } | ||
| 6304 | break; | ||
| 6305 | case TYPE_INT_FAST32_T: | ||
| 6306 | { | ||
| 6307 | int_fast32_t arg = a.arg[dp->arg_index].a.a_int_fast32_t; | ||
| 6308 | SNPRINTF_BUF (arg); | ||
| 6309 | } | ||
| 6310 | break; | ||
| 6311 | case TYPE_UINT_FAST32_T: | ||
| 6312 | { | ||
| 6313 | uint_fast32_t arg = a.arg[dp->arg_index].a.a_uint_fast32_t; | ||
| 6314 | SNPRINTF_BUF (arg); | ||
| 6315 | } | ||
| 6316 | break; | ||
| 6317 | case TYPE_INT_FAST64_T: | ||
| 6318 | { | ||
| 6319 | int_fast64_t arg = a.arg[dp->arg_index].a.a_int_fast64_t; | ||
| 6320 | SNPRINTF_BUF (arg); | ||
| 6321 | } | ||
| 6322 | break; | ||
| 6323 | case TYPE_UINT_FAST64_T: | ||
| 6324 | { | ||
| 6325 | uint_fast64_t arg = a.arg[dp->arg_index].a.a_uint_fast64_t; | ||
| 6326 | SNPRINTF_BUF (arg); | ||
| 6327 | } | ||
| 6328 | break; | ||
| 5192 | case TYPE_DOUBLE: | 6329 | case TYPE_DOUBLE: |
| 5193 | { | 6330 | { |
| 5194 | double arg = a.arg[dp->arg_index].a.a_double; | 6331 | double arg = a.arg[dp->arg_index].a.a_double; |
| @@ -5271,12 +6408,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5271 | /* Look at the snprintf() return value. */ | 6408 | /* Look at the snprintf() return value. */ |
| 5272 | if (retcount < 0) | 6409 | if (retcount < 0) |
| 5273 | { | 6410 | { |
| 5274 | # if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF | 6411 | # if (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF |
| 5275 | /* HP-UX 10.20 snprintf() is doubly deficient: | 6412 | /* HP-UX 10.20 snprintf() is doubly deficient: |
| 5276 | It doesn't understand the '%n' directive, | 6413 | It doesn't understand the '%n' directive, |
| 5277 | *and* it returns -1 (rather than the length | 6414 | *and* it returns -1 (rather than the length |
| 5278 | that would have been required) when the | 6415 | that would have been required) when the |
| 5279 | buffer is too small. | 6416 | buffer is too small. |
| 6417 | Likewise, in case of | ||
| 6418 | WIDE_CHAR_VERSION && DCHAR_IS_TCHAR, the | ||
| 6419 | functions snwprintf()/_snwprintf() (Windows) | ||
| 6420 | or swprintf() (Unix). | ||
| 5280 | But a failure at this point can also come | 6421 | But a failure at this point can also come |
| 5281 | from other reasons than a too small buffer, | 6422 | from other reasons than a too small buffer, |
| 5282 | such as an invalid wide string argument to | 6423 | such as an invalid wide string argument to |
| @@ -5312,7 +6453,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5312 | # endif | 6453 | # endif |
| 5313 | } | 6454 | } |
| 5314 | else | 6455 | else |
| 5315 | count = retcount; | 6456 | { |
| 6457 | count = retcount; | ||
| 6458 | # if WIDE_CHAR_VERSION && defined __MINGW32__ | ||
| 6459 | if (count == 0 && dp->conversion == 'c') | ||
| 6460 | /* snwprintf returned 0 instead of 1. But it | ||
| 6461 | wrote a null wide character. */ | ||
| 6462 | count = 1; | ||
| 6463 | # endif | ||
| 6464 | } | ||
| 5316 | } | 6465 | } |
| 5317 | } | 6466 | } |
| 5318 | #endif | 6467 | #endif |
| @@ -5370,7 +6519,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5370 | } | 6519 | } |
| 5371 | #endif | 6520 | #endif |
| 5372 | 6521 | ||
| 5373 | #if NEED_PRINTF_UNBOUNDED_PRECISION | 6522 | #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 5374 | if (prec_ourselves) | 6523 | if (prec_ourselves) |
| 5375 | { | 6524 | { |
| 5376 | /* Handle the precision. */ | 6525 | /* Handle the precision. */ |
| @@ -5430,6 +6579,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5430 | 6579 | ||
| 5431 | count += insert; | 6580 | count += insert; |
| 5432 | } | 6581 | } |
| 6582 | # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO | ||
| 6583 | else if (precision == 0 | ||
| 6584 | && move == 1 | ||
| 6585 | && prec_ptr[prefix_count] == '0') | ||
| 6586 | { | ||
| 6587 | /* Replace the "0" result with an empty string. */ | ||
| 6588 | count = prefix_count; | ||
| 6589 | } | ||
| 6590 | # endif | ||
| 5433 | } | 6591 | } |
| 5434 | #endif | 6592 | #endif |
| 5435 | 6593 | ||
| @@ -5442,11 +6600,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5442 | 6600 | ||
| 5443 | #if !DCHAR_IS_TCHAR | 6601 | #if !DCHAR_IS_TCHAR |
| 5444 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ | 6602 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ |
| 5445 | if (dp->conversion == 'c' || dp->conversion == 's') | 6603 | if (dp->conversion == 'c' || dp->conversion == 's' |
| 6604 | # if __GLIBC__ >= 2 && !defined __UCLIBC__ | ||
| 6605 | || (flags & FLAG_LOCALIZED) | ||
| 6606 | # endif | ||
| 6607 | ) | ||
| 5446 | { | 6608 | { |
| 5447 | /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING | 6609 | /* The result string is not guaranteed to be ASCII. */ |
| 5448 | TYPE_WIDE_STRING. | ||
| 5449 | The result string is not certainly ASCII. */ | ||
| 5450 | const TCHAR_T *tmpsrc; | 6610 | const TCHAR_T *tmpsrc; |
| 5451 | DCHAR_T *tmpdst; | 6611 | DCHAR_T *tmpdst; |
| 5452 | size_t tmpdst_len; | 6612 | size_t tmpdst_len; |
| @@ -5457,6 +6617,56 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5457 | # else | 6617 | # else |
| 5458 | tmpsrc = tmp; | 6618 | tmpsrc = tmp; |
| 5459 | # endif | 6619 | # endif |
| 6620 | # if WIDE_CHAR_VERSION | ||
| 6621 | /* Convert tmpsrc[0..count-1] to a freshly allocated | ||
| 6622 | wide character array. */ | ||
| 6623 | mbstate_t state; | ||
| 6624 | |||
| 6625 | mbszero (&state); | ||
| 6626 | tmpdst_len = 0; | ||
| 6627 | { | ||
| 6628 | const TCHAR_T *src = tmpsrc; | ||
| 6629 | size_t srclen = count; | ||
| 6630 | |||
| 6631 | for (; srclen > 0; tmpdst_len++) | ||
| 6632 | { | ||
| 6633 | /* Parse the next multibyte character. */ | ||
| 6634 | size_t ret = mbrtowc (NULL, src, srclen, &state); | ||
| 6635 | if (ret == (size_t)(-2) || ret == (size_t)(-1)) | ||
| 6636 | goto fail_with_EILSEQ; | ||
| 6637 | if (ret == 0) | ||
| 6638 | ret = 1; | ||
| 6639 | src += ret; | ||
| 6640 | srclen -= ret; | ||
| 6641 | } | ||
| 6642 | } | ||
| 6643 | |||
| 6644 | tmpdst = | ||
| 6645 | (wchar_t *) malloc ((tmpdst_len + 1) * sizeof (wchar_t)); | ||
| 6646 | if (tmpdst == NULL) | ||
| 6647 | goto out_of_memory; | ||
| 6648 | |||
| 6649 | mbszero (&state); | ||
| 6650 | { | ||
| 6651 | DCHAR_T *destptr = tmpdst; | ||
| 6652 | const TCHAR_T *src = tmpsrc; | ||
| 6653 | size_t srclen = count; | ||
| 6654 | |||
| 6655 | for (; srclen > 0; destptr++) | ||
| 6656 | { | ||
| 6657 | /* Parse the next multibyte character. */ | ||
| 6658 | size_t ret = mbrtowc (destptr, src, srclen, &state); | ||
| 6659 | if (ret == (size_t)(-2) || ret == (size_t)(-1)) | ||
| 6660 | /* Should already have been caught in the first | ||
| 6661 | loop, above. */ | ||
| 6662 | abort (); | ||
| 6663 | if (ret == 0) | ||
| 6664 | ret = 1; | ||
| 6665 | src += ret; | ||
| 6666 | srclen -= ret; | ||
| 6667 | } | ||
| 6668 | } | ||
| 6669 | # else | ||
| 5460 | tmpdst = | 6670 | tmpdst = |
| 5461 | DCHAR_CONV_FROM_ENCODING (locale_charset (), | 6671 | DCHAR_CONV_FROM_ENCODING (locale_charset (), |
| 5462 | iconveh_question_mark, | 6672 | iconveh_question_mark, |
| @@ -5465,6 +6675,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5465 | NULL, &tmpdst_len); | 6675 | NULL, &tmpdst_len); |
| 5466 | if (tmpdst == NULL) | 6676 | if (tmpdst == NULL) |
| 5467 | goto fail_with_errno; | 6677 | goto fail_with_errno; |
| 6678 | # endif | ||
| 5468 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), | 6679 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), |
| 5469 | { free (tmpdst); goto out_of_memory; }); | 6680 | { free (tmpdst); goto out_of_memory; }); |
| 5470 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); | 6681 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); |
| @@ -5531,7 +6742,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5531 | /* Here count <= allocated - length. */ | 6742 | /* Here count <= allocated - length. */ |
| 5532 | 6743 | ||
| 5533 | /* Perform padding. */ | 6744 | /* Perform padding. */ |
| 5534 | #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6745 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION |
| 5535 | if (pad_ourselves && has_width) | 6746 | if (pad_ourselves && has_width) |
| 5536 | { | 6747 | { |
| 5537 | size_t w; | 6748 | size_t w; |
| @@ -5590,6 +6801,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5590 | if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z') | 6801 | if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z') |
| 5591 | || (*pad_ptr >= 'a' && *pad_ptr <= 'z')) | 6802 | || (*pad_ptr >= 'a' && *pad_ptr <= 'z')) |
| 5592 | pad_ptr = NULL; | 6803 | pad_ptr = NULL; |
| 6804 | else | ||
| 6805 | /* Do the zero-padding after the "0x" or | ||
| 6806 | "0b" prefix, not before. */ | ||
| 6807 | if (p - rp >= 2 | ||
| 6808 | && *rp == '0' | ||
| 6809 | && (((dp->conversion == 'a' | ||
| 6810 | || dp->conversion == 'x') | ||
| 6811 | && rp[1] == 'x') | ||
| 6812 | || ((dp->conversion == 'A' | ||
| 6813 | || dp->conversion == 'X') | ||
| 6814 | && rp[1] == 'X') | ||
| 6815 | || (dp->conversion == 'b' | ||
| 6816 | && rp[1] == 'b') | ||
| 6817 | || (dp->conversion == 'B' | ||
| 6818 | && rp[1] == 'B'))) | ||
| 6819 | pad_ptr += 2; | ||
| 5593 | } | 6820 | } |
| 5594 | /* The generated string now extends from rp to p, | 6821 | /* The generated string now extends from rp to p, |
| 5595 | with the zero padding insertion point being at | 6822 | with the zero padding insertion point being at |
| @@ -5603,7 +6830,22 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5603 | for (; pad > 0; pad--) | 6830 | for (; pad > 0; pad--) |
| 5604 | *p++ = ' '; | 6831 | *p++ = ' '; |
| 5605 | } | 6832 | } |
| 5606 | else if ((flags & FLAG_ZERO) && pad_ptr != NULL) | 6833 | else if ((flags & FLAG_ZERO) && pad_ptr != NULL |
| 6834 | /* ISO C says: "For d, i, o, u, x, and X | ||
| 6835 | conversions, if a precision is | ||
| 6836 | specified, the 0 flag is ignored. */ | ||
| 6837 | && !(has_precision | ||
| 6838 | && (dp->conversion == 'd' | ||
| 6839 | || dp->conversion == 'i' | ||
| 6840 | || dp->conversion == 'o' | ||
| 6841 | || dp->conversion == 'u' | ||
| 6842 | || dp->conversion == 'x' | ||
| 6843 | || dp->conversion == 'X' | ||
| 6844 | /* Although ISO C does not | ||
| 6845 | require it, treat 'b' and 'B' | ||
| 6846 | like 'x' and 'X'. */ | ||
| 6847 | || dp->conversion == 'b' | ||
| 6848 | || dp->conversion == 'B'))) | ||
| 5607 | { | 6849 | { |
| 5608 | /* Pad with zeroes. */ | 6850 | /* Pad with zeroes. */ |
| 5609 | DCHAR_T *q = end; | 6851 | DCHAR_T *q = end; |
| @@ -5697,7 +6939,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5697 | errno = ENOMEM; | 6939 | errno = ENOMEM; |
| 5698 | goto fail_with_errno; | 6940 | goto fail_with_errno; |
| 5699 | 6941 | ||
| 5700 | #if ENABLE_UNISTDIO || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) | 6942 | #if ENABLE_UNISTDIO || ((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION) || (NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION) |
| 5701 | fail_with_EILSEQ: | 6943 | fail_with_EILSEQ: |
| 5702 | errno = EILSEQ; | 6944 | errno = EILSEQ; |
| 5703 | goto fail_with_errno; | 6945 | goto fail_with_errno; |
