From 0710282c4378b75df57dc7d7a8f99719b95af6a6 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 12 Apr 2025 11:03:45 +0200 Subject: [PATCH] vasnprintf: Work around two grouping bugs on native Windows. * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_FLAG_GROUPING): On native Windows, define NEED_PRINTF_FLAG_GROUPING. * lib/vasnprintf.c (localeconv): Undefine. (thousands_separator_char, thousands_separator_wchar): On native Windows, use localeconv(). * tests/test-vasnprintf-posix2.c (main): On native Windows, expect 3 digits for the exponent. * tests/test-vasnwprintf-posix2.c (main): Likewise. * doc/posix-functions/fprintf.texi: Mention the mingw and MSVC bugs. * doc/posix-functions/vfprintf.texi: Likewise. * doc/posix-functions/printf.texi: Likewise. * doc/posix-functions/vprintf.texi: Likewise. * doc/posix-functions/sprintf.texi: Likewise. * doc/posix-functions/vsprintf.texi: Likewise. * doc/posix-functions/snprintf.texi: Likewise. * doc/posix-functions/vsnprintf.texi: Likewise. * doc/posix-functions/dprintf.texi: Likewise. * doc/posix-functions/vdprintf.texi: Likewise. * doc/posix-functions/fwprintf.texi: Likewise. * doc/posix-functions/vfwprintf.texi: Likewise. * doc/posix-functions/wprintf.texi: Likewise. * doc/posix-functions/vwprintf.texi: Likewise. * doc/posix-functions/swprintf.texi: Likewise. * doc/posix-functions/vswprintf.texi: Likewise. * doc/posix-functions/asprintf.texi: Likewise. * doc/posix-functions/vasprintf.texi: Likewise. * doc/glibc-functions/obstack_printf.texi: Likewise. * doc/glibc-functions/obstack_vprintf.texi: Likewise. --- ChangeLog | 32 ++++++++++++++++++++ doc/glibc-functions/obstack_printf.texi | 8 +++++ doc/glibc-functions/obstack_vprintf.texi | 8 +++++ doc/posix-functions/asprintf.texi | 8 +++++ doc/posix-functions/dprintf.texi | 8 +++++ doc/posix-functions/fprintf.texi | 8 +++++ doc/posix-functions/fwprintf.texi | 8 +++++ doc/posix-functions/printf.texi | 8 +++++ doc/posix-functions/snprintf.texi | 8 +++++ doc/posix-functions/sprintf.texi | 8 +++++ doc/posix-functions/swprintf.texi | 8 +++++ doc/posix-functions/vasprintf.texi | 8 +++++ doc/posix-functions/vdprintf.texi | 8 +++++ doc/posix-functions/vfprintf.texi | 8 +++++ doc/posix-functions/vfwprintf.texi | 8 +++++ doc/posix-functions/vprintf.texi | 8 +++++ doc/posix-functions/vsnprintf.texi | 8 +++++ doc/posix-functions/vsprintf.texi | 8 +++++ doc/posix-functions/vswprintf.texi | 8 +++++ doc/posix-functions/vwprintf.texi | 8 +++++ doc/posix-functions/wprintf.texi | 8 +++++ lib/vasnprintf.c | 36 ++++++++++++++++++----- m4/printf.m4 | 4 +-- m4/vasnprintf.m4 | 37 ++++++++++++++++-------- tests/test-vasnprintf-posix2.c | 20 ++++++++++--- tests/test-vasnwprintf-posix2.c | 20 ++++++++++--- 26 files changed, 280 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8f3874c09..5deaa6a969 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2025-04-12 Bruno Haible + + vasnprintf: Work around two grouping bugs on native Windows. + * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_FLAG_GROUPING): On native + Windows, define NEED_PRINTF_FLAG_GROUPING. + * lib/vasnprintf.c (localeconv): Undefine. + (thousands_separator_char, thousands_separator_wchar): On native + Windows, use localeconv(). + * tests/test-vasnprintf-posix2.c (main): On native Windows, expect + 3 digits for the exponent. + * tests/test-vasnwprintf-posix2.c (main): Likewise. + * doc/posix-functions/fprintf.texi: Mention the mingw and MSVC bugs. + * doc/posix-functions/vfprintf.texi: Likewise. + * doc/posix-functions/printf.texi: Likewise. + * doc/posix-functions/vprintf.texi: Likewise. + * doc/posix-functions/sprintf.texi: Likewise. + * doc/posix-functions/vsprintf.texi: Likewise. + * doc/posix-functions/snprintf.texi: Likewise. + * doc/posix-functions/vsnprintf.texi: Likewise. + * doc/posix-functions/dprintf.texi: Likewise. + * doc/posix-functions/vdprintf.texi: Likewise. + * doc/posix-functions/fwprintf.texi: Likewise. + * doc/posix-functions/vfwprintf.texi: Likewise. + * doc/posix-functions/wprintf.texi: Likewise. + * doc/posix-functions/vwprintf.texi: Likewise. + * doc/posix-functions/swprintf.texi: Likewise. + * doc/posix-functions/vswprintf.texi: Likewise. + * doc/posix-functions/asprintf.texi: Likewise. + * doc/posix-functions/vasprintf.texi: Likewise. + * doc/glibc-functions/obstack_printf.texi: Likewise. + * doc/glibc-functions/obstack_vprintf.texi: Likewise. + 2025-04-12 Bruno Haible localeconv tests: Add multithread-safety test. diff --git a/doc/glibc-functions/obstack_printf.texi b/doc/glibc-functions/obstack_printf.texi index c96a674ac2..34f2b9fd37 100644 --- a/doc/glibc-functions/obstack_printf.texi +++ b/doc/glibc-functions/obstack_printf.texi @@ -42,6 +42,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/glibc-functions/obstack_vprintf.texi b/doc/glibc-functions/obstack_vprintf.texi index 5fe389c486..92b0efab9b 100644 --- a/doc/glibc-functions/obstack_vprintf.texi +++ b/doc/glibc-functions/obstack_vprintf.texi @@ -42,6 +42,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/asprintf.texi b/doc/posix-functions/asprintf.texi index dbbed305b5..ae6a252915 100644 --- a/doc/posix-functions/asprintf.texi +++ b/doc/posix-functions/asprintf.texi @@ -68,6 +68,14 @@ This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag on some platforms: NetBSD 3.0, Cygwin 1.5.24. @item diff --git a/doc/posix-functions/dprintf.texi b/doc/posix-functions/dprintf.texi index da9446ae99..6f6dc4cfbd 100644 --- a/doc/posix-functions/dprintf.texi +++ b/doc/posix-functions/dprintf.texi @@ -28,6 +28,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/fprintf.texi b/doc/posix-functions/fprintf.texi index 407ad6bc30..4eebaafd8f 100644 --- a/doc/posix-functions/fprintf.texi +++ b/doc/posix-functions/fprintf.texi @@ -55,6 +55,14 @@ This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag on some platforms: NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 14. @item diff --git a/doc/posix-functions/fwprintf.texi b/doc/posix-functions/fwprintf.texi index 0dd8ec828a..3ca62ddd2f 100644 --- a/doc/posix-functions/fwprintf.texi +++ b/doc/posix-functions/fwprintf.texi @@ -24,6 +24,14 @@ This function does not support size specifiers as in C23 (@code{w8}, @code{wf64}) on some platforms: glibc 2.37, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4, Cygwin 3.5.3, mingw, MSVC, Android 9.0. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/printf.texi b/doc/posix-functions/printf.texi index 2b2c240531..4cf38b5ba6 100644 --- a/doc/posix-functions/printf.texi +++ b/doc/posix-functions/printf.texi @@ -30,6 +30,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/snprintf.texi b/doc/posix-functions/snprintf.texi index a1aea4ea4b..410e816445 100644 --- a/doc/posix-functions/snprintf.texi +++ b/doc/posix-functions/snprintf.texi @@ -43,6 +43,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/sprintf.texi b/doc/posix-functions/sprintf.texi index 3b0bc0f725..b0bf752fe7 100644 --- a/doc/posix-functions/sprintf.texi +++ b/doc/posix-functions/sprintf.texi @@ -27,6 +27,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/swprintf.texi b/doc/posix-functions/swprintf.texi index 944dd4798c..72cabd3ba2 100644 --- a/doc/posix-functions/swprintf.texi +++ b/doc/posix-functions/swprintf.texi @@ -60,6 +60,14 @@ characters on some platforms: musl libc 1.2.3, macOS 14, FreeBSD 13.1, NetBSD 10.0, OpenBSD 7.2, AIX 7.2, mingw. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vasprintf.texi b/doc/posix-functions/vasprintf.texi index 8805d6fb9a..7c687f2c3a 100644 --- a/doc/posix-functions/vasprintf.texi +++ b/doc/posix-functions/vasprintf.texi @@ -45,6 +45,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vdprintf.texi b/doc/posix-functions/vdprintf.texi index 3277f6edb6..69c09166e9 100644 --- a/doc/posix-functions/vdprintf.texi +++ b/doc/posix-functions/vdprintf.texi @@ -28,6 +28,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vfprintf.texi b/doc/posix-functions/vfprintf.texi index cdf1f75cc8..53516d374c 100644 --- a/doc/posix-functions/vfprintf.texi +++ b/doc/posix-functions/vfprintf.texi @@ -30,6 +30,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vfwprintf.texi b/doc/posix-functions/vfwprintf.texi index 0e7bb752fa..f0b38bae49 100644 --- a/doc/posix-functions/vfwprintf.texi +++ b/doc/posix-functions/vfwprintf.texi @@ -24,6 +24,14 @@ This function does not support size specifiers as in C23 (@code{w8}, @code{wf64}) on some platforms: glibc 2.37, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4, Cygwin 3.5.3, mingw, MSVC, Android 9.0. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vprintf.texi b/doc/posix-functions/vprintf.texi index ad82631b32..8b84f2f91e 100644 --- a/doc/posix-functions/vprintf.texi +++ b/doc/posix-functions/vprintf.texi @@ -30,6 +30,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vsnprintf.texi b/doc/posix-functions/vsnprintf.texi index 0dc8280a7c..baceea4cdd 100644 --- a/doc/posix-functions/vsnprintf.texi +++ b/doc/posix-functions/vsnprintf.texi @@ -40,6 +40,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vsprintf.texi b/doc/posix-functions/vsprintf.texi index fb23110621..15b6e9204e 100644 --- a/doc/posix-functions/vsprintf.texi +++ b/doc/posix-functions/vsprintf.texi @@ -27,6 +27,14 @@ printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an incorrect result on some platforms: AIX 7.3, Solaris 11.4, mingw, MSVC 14. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vswprintf.texi b/doc/posix-functions/vswprintf.texi index b237e8b086..2bd0b03996 100644 --- a/doc/posix-functions/vswprintf.texi +++ b/doc/posix-functions/vswprintf.texi @@ -26,6 +26,14 @@ This function does not support size specifiers as in C23 (@code{w8}, @code{wf64}) on some platforms: glibc 2.37, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4, Cygwin 3.5.3, mingw, MSVC, Android 9.0. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/vwprintf.texi b/doc/posix-functions/vwprintf.texi index faa3428143..fea34ed3fc 100644 --- a/doc/posix-functions/vwprintf.texi +++ b/doc/posix-functions/vwprintf.texi @@ -27,6 +27,14 @@ This function does not support size specifiers as in C23 (@code{w8}, @code{wf64}) on some platforms: glibc 2.37, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4, Cygwin 3.5.3, mingw, MSVC, Android 9.0. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/doc/posix-functions/wprintf.texi b/doc/posix-functions/wprintf.texi index 47353bcce8..4923552b77 100644 --- a/doc/posix-functions/wprintf.texi +++ b/doc/posix-functions/wprintf.texi @@ -27,6 +27,14 @@ This function does not support size specifiers as in C23 (@code{w8}, @code{wf64}) on some platforms: glibc 2.37, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4, Cygwin 3.5.3, mingw, MSVC, Android 9.0. @item +This function doesn't support the @code{'} flag at all on some platforms: +mingw without @code{__USE_MINGW_ANSI_STDIO}, MSVC 14. +@item +This function doesn't support the @code{'} flag correctly for integers +(it uses the decimal point instead of the thousands separator!) +on some platforms: +mingw with @code{__USE_MINGW_ANSI_STDIO}. +@item This function doesn't support the @code{'} flag together with a precision on an integer argument correctly on some platforms: glibc 2.36, FreeBSD 14.0, NetBSD 10.0, Solaris 11, Cygwin 3.6.0, Haiku. diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index 45e7c724a5..4152237929 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -238,6 +238,11 @@ # define IF_LINT(Code) /* empty */ #endif +/* Here we need only the most basic fields of 'struct lconv', and can + therefore use the system's localeconv() function, without needing a + dependency on module 'localeconv'. */ +#undef localeconv + /* Avoid some warnings from "gcc -Wshadow". This file doesn't use the exp() and remainder() functions. */ #undef exp @@ -409,13 +414,18 @@ decimal_point_char (void) static const char * thousands_separator_char (char stackbuf[10]) { - /* Determine it in a multithread-safe way. We know nl_langinfo is - multithread-safe on glibc systems, on Mac OS X systems, and on NetBSD, - but is not required to be multithread-safe by POSIX. sprintf(), however, - is multithread-safe. localeconv() is rarely multithread-safe. */ + /* Determine it in a multithread-safe way. + We know nl_langinfo is multithread-safe on glibc systems, on Mac OS X + systems, and on NetBSD, but is not required to be multithread-safe by + POSIX. + localeconv() is not guaranteed to be multithread-safe by POSIX either; + however, on native Windows it is (cf. test-localeconv-mt). + sprintf(), however, is multithread-safe. */ # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __NetBSD__) return nl_langinfo (THOUSEP); -# elif 1 +# elif defined _WIN32 && !defined __CYGWIN__ + return localeconv () -> thousands_sep; +# else sprintf (stackbuf, "%'.0f", 1000.0); /* Now stackbuf = "1000". */ stackbuf[strlen (stackbuf) - 3] = '\0'; @@ -425,8 +435,6 @@ thousands_separator_char (char stackbuf[10]) strcpy (&stackbuf[1], MB_CUR_MAX > 1 ? "\302\240" : "\240"); # endif return &stackbuf[1]; -# else - return localeconv () -> thousands_sep; # endif } # endif @@ -451,6 +459,20 @@ thousands_separator_wchar (wchar_t stackbuf[10]) (wchar_t) (unsigned long) nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC); stackbuf[1] = L'\0'; return stackbuf; +# elif defined _WIN32 && !defined __CYGWIN__ + const char *tmp = localeconv () -> thousands_sep; + if (*tmp != '\0') + { + mbstate_t state; + mbszero (&state); + if ((int) mbrtowc (&stackbuf[0], tmp, strlen (tmp), &state) > 0) + stackbuf[1] = L'\0'; + else + stackbuf[0] = L'\0'; + } + else + stackbuf[0] = L'\0'; + return stackbuf; # elif defined __sun /* Use sprintf, because swprintf retrieves a wrong value for the thousands-separator wide character (e.g. (wchar_t) 0xffffffa0). */ diff --git a/m4/printf.m4 b/m4/printf.m4 index 62319e4af3..4619a40252 100644 --- a/m4/printf.m4 +++ b/m4/printf.m4 @@ -2336,10 +2336,10 @@ dnl Cygwin 1.5.19 (2006) # # . . # # # # # . # ? . # ? dnl Solaris 11.4 . # . # # # # # . . # . . . # # . # . . . . . . . . . . # . dnl Solaris 11.3 . # . . . # # # . . # . . . ? ? . . . . . . . . . . . . # . dnl Solaris 11.0 . # . # # # # # . . # . . . ? ? . # . . . . . . . . . ? ? ? -dnl Solaris 10 . # . # # # # # . . # . . . ? ? . # . # . . . . . . . . # . +dnl Solaris 10 . # . # # # # # . . # . . . # # . # . # . . . . . . . . # . dnl Solaris 2.6 ... 9 # # . # # # # # # . # . . . ? ? . # ? # . . . # . . . ? ? ? dnl Solaris 2.5.1 # # . # # # # # # . # . . . ? ? . # ? . . # # # # # # ? ? ? -dnl AIX 7.1 . # . # # # # # . . . . . . ? ? . # . # . . . . . . . # . . +dnl AIX 7.1 . # . # # # # # . . . . . . . . . # . # . . . . . . . # . . dnl AIX 5.2 . # . # # # # # . . . . . . ? ? . # ? . . . . . . . . # ? ? dnl AIX 4.3.2, 5.1 # # . # # # # # # . . . . . ? ? . # ? . . . . # . . . # ? ? dnl HP-UX 11.31 . # . . . # # # . . . ? . . ? ? . # ? . . . . # # . . ? ? ? diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 index 35fdbc5e94..1d040d6e0c 100644 --- a/m4/vasnprintf.m4 +++ b/m4/vasnprintf.m4 @@ -1,5 +1,5 @@ # vasnprintf.m4 -# serial 55 +# serial 56 dnl Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -357,26 +357,39 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_LC], # Extra prerequisites of lib/vasnprintf.c for supporting the ' flag. AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING], [ + AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION]) AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE]) - case "$gl_cv_func_printf_flag_grouping,$gl_cv_func_printf_flag_grouping_multibyte" in - *yes,*yes) - case "$gl_cv_func_printf_flag_grouping_int_precision" in - *yes) + case "$host_os" in + mingw* | windows*) + dnl MSVC does not support the ' flag at all. + dnl mingw does not support it, unless __USE_MINGW_ANSI_STDIO is defined. + dnl mingw also has other bugs regarding the ' flag. + AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], + [Define if the vasnprintf implementation needs special code for the + ' flag.]) + ;; + *) + case "$gl_cv_func_printf_flag_grouping,$gl_cv_func_printf_flag_grouping_multibyte" in + *yes,*yes) + case "$gl_cv_func_printf_flag_grouping_int_precision" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_FLAG_GROUPING_INT], [1], + [Define if the vasnprintf implementation needs special code for the + ' flag, for integer directives only.]) + ;; + esac ;; *) - AC_DEFINE([NEED_PRINTF_FLAG_GROUPING_INT], [1], + AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], [Define if the vasnprintf implementation needs special code for the - ' flag, for integer directives only.]) + ' flag.]) ;; esac ;; - *) - AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], - [Define if the vasnprintf implementation needs special code for the - ' flag.]) - ;; esac ]) diff --git a/tests/test-vasnprintf-posix2.c b/tests/test-vasnprintf-posix2.c index 1f43aa5e6e..b0ba95b667 100644 --- a/tests/test-vasnprintf-posix2.c +++ b/tests/test-vasnprintf-posix2.c @@ -359,16 +359,28 @@ main (int argc, char *argv[]) size_t length; char *result = asnprintf (NULL, &length, "%'.5g", 3141592653.5897932386); ASSERT (result != NULL); - ASSERT (length == 10); - ASSERT (strcmp (result, "3,1416e+09") == 0); + #if defined _WIN32 && !defined __CYGWIN__ + /* Native Windows uses 3 digits for the exponent. */ + ASSERT (length == 11); + ASSERT (strcmp (result, "3,1416e+009") == 0); + #else + ASSERT (length == 10); + ASSERT (strcmp (result, "3,1416e+09") == 0); + #endif free (result); } { size_t length; char *result = asnprintf (NULL, &length, "%'.5g", -3141592653.5897932386); ASSERT (result != NULL); - ASSERT (length == 11); - ASSERT (strcmp (result, "-3,1416e+09") == 0); + #if defined _WIN32 && !defined __CYGWIN__ + /* Native Windows uses 3 digits for the exponent. */ + ASSERT (length == 12); + ASSERT (strcmp (result, "-3,1416e+009") == 0); + #else + ASSERT (length == 11); + ASSERT (strcmp (result, "-3,1416e+09") == 0); + #endif free (result); } { diff --git a/tests/test-vasnwprintf-posix2.c b/tests/test-vasnwprintf-posix2.c index 3794d5f7c4..4ccbe079ae 100644 --- a/tests/test-vasnwprintf-posix2.c +++ b/tests/test-vasnwprintf-posix2.c @@ -292,16 +292,28 @@ main (int argc, char *argv[]) size_t length; wchar_t *result = asnwprintf (NULL, &length, L"%'.5g", 3141592653.5897932386); ASSERT (result != NULL); - ASSERT (length == 10); - ASSERT (wcscmp (result, L"3,1416e+09") == 0); + #if defined _WIN32 && !defined __CYGWIN__ + /* Native Windows uses 3 digits for the exponent. */ + ASSERT (length == 11); + ASSERT (wcscmp (result, L"3,1416e+009") == 0); + #else + ASSERT (length == 10); + ASSERT (wcscmp (result, L"3,1416e+09") == 0); + #endif free (result); } { size_t length; wchar_t *result = asnwprintf (NULL, &length, L"%'.5g", -3141592653.5897932386); ASSERT (result != NULL); - ASSERT (length == 11); - ASSERT (wcscmp (result, L"-3,1416e+09") == 0); + #if defined _WIN32 && !defined __CYGWIN__ + /* Native Windows uses 3 digits for the exponent. */ + ASSERT (length == 12); + ASSERT (wcscmp (result, L"-3,1416e+009") == 0); + #else + ASSERT (length == 11); + ASSERT (wcscmp (result, L"-3,1416e+09") == 0); + #endif free (result); } { -- 2.39.5