mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2026-10-24 00:48:56 +03:00
vasnprintf: Work around two grouping bugs on many platforms.
* m4/printf.m4 (gl_PRINTF_FLAG_GROUPING_INT_PRECISION): New macro. (gl_PRINTF_FLAG_GROUPING_MULTIBYTE): New macro. * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_IS_POSIX): Require gl_PRINTF_FLAG_GROUPING_INT_PRECISION, gl_PRINTF_FLAG_GROUPING_MULTIBYTE. Test gl_cv_func_printf_flag_grouping_int_precision, gl_cv_func_printf_flag_grouping_multibyte. * m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_IS_POSIX): Likewise. * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_IS_POSIX): Likewise. * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_IS_POSIX): Likewise. * m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_IS_POSIX): Likewise. * m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_IS_POSIX): Likewise. * m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_IS_POSIX): Likewise. * m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_IS_POSIX): Likewise. * m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_IS_POSIX): Likewise. * m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_IS_POSIX): Likewise. * m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_IS_POSIX): Likewise. * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_FLAG_GROUPING): Require gl_PRINTF_FLAG_GROUPING_INT_PRECISION, gl_PRINTF_FLAG_GROUPING_MULTIBYTE. Test gl_cv_func_printf_flag_grouping_int_precision, gl_cv_func_printf_flag_grouping_multibyte. Define the C macro NEED_PRINTF_FLAG_GROUPING_INT. * lib/vasnprintf.c (thousands_separator_char): New function. (THOUSEP_CHAR_MAXLEN): New macro. (thousands_separator_wchar): New function. (THOUSEP_WCHAR_MAXLEN): New macro. (MAX_ROOM_NEEDED): Improve the room estimate for FLAG_GROUP. (VASNPRINTF): Add code for emitting thousands separators in the %f, %F, %g, %G implementations and in the code relies the system's sprintf/snprintf/swprintf function. Test NEED_PRINTF_FLAG_GROUPING and NEED_PRINTF_FLAG_GROUPING_INT where needed. * tests/test-vasnprintf-posix2.c (main): Add tests of the grouping flag. * tests/test-vasnwprintf-posix2.c (main): Likewise. * tests/test-vasnprintf-posix2.sh: Test in both French locales, not only in one of them. * tests/test-vasnwprintf-posix2.sh: Likewise. * modules/vasnprintf-posix-tests (Depends-on): Add localeconv. * modules/vasnwprintf-posix-tests (Depends-on): Likewise. * doc/posix-functions/fprintf.texi: Mention the grouping bug with precision on integers and the grouping bug with a multibyte thousands separator. * 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.
This commit is contained in:
66
ChangeLog
66
ChangeLog
@@ -1,3 +1,69 @@
|
||||
2025-04-11 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
vasnprintf: Work around two grouping bugs on many platforms.
|
||||
* m4/printf.m4 (gl_PRINTF_FLAG_GROUPING_INT_PRECISION): New macro.
|
||||
(gl_PRINTF_FLAG_GROUPING_MULTIBYTE): New macro.
|
||||
* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_IS_POSIX): Require
|
||||
gl_PRINTF_FLAG_GROUPING_INT_PRECISION,
|
||||
gl_PRINTF_FLAG_GROUPING_MULTIBYTE. Test
|
||||
gl_cv_func_printf_flag_grouping_int_precision,
|
||||
gl_cv_func_printf_flag_grouping_multibyte.
|
||||
* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_IS_POSIX): Likewise.
|
||||
* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_IS_POSIX): Likewise.
|
||||
* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_IS_POSIX): Likewise.
|
||||
* m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_IS_POSIX): Likewise.
|
||||
* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_IS_POSIX): Likewise.
|
||||
* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_IS_POSIX): Likewise.
|
||||
* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_IS_POSIX): Likewise.
|
||||
* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_IS_POSIX): Likewise.
|
||||
* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_IS_POSIX): Likewise.
|
||||
* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_IS_POSIX):
|
||||
Likewise.
|
||||
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_FLAG_GROUPING): Require
|
||||
gl_PRINTF_FLAG_GROUPING_INT_PRECISION,
|
||||
gl_PRINTF_FLAG_GROUPING_MULTIBYTE. Test
|
||||
gl_cv_func_printf_flag_grouping_int_precision,
|
||||
gl_cv_func_printf_flag_grouping_multibyte. Define the C macro
|
||||
NEED_PRINTF_FLAG_GROUPING_INT.
|
||||
* lib/vasnprintf.c (thousands_separator_char): New function.
|
||||
(THOUSEP_CHAR_MAXLEN): New macro.
|
||||
(thousands_separator_wchar): New function.
|
||||
(THOUSEP_WCHAR_MAXLEN): New macro.
|
||||
(MAX_ROOM_NEEDED): Improve the room estimate for FLAG_GROUP.
|
||||
(VASNPRINTF): Add code for emitting thousands separators in the %f, %F,
|
||||
%g, %G implementations and in the code relies the system's
|
||||
sprintf/snprintf/swprintf function. Test NEED_PRINTF_FLAG_GROUPING and
|
||||
NEED_PRINTF_FLAG_GROUPING_INT where needed.
|
||||
* tests/test-vasnprintf-posix2.c (main): Add tests of the grouping flag.
|
||||
* tests/test-vasnwprintf-posix2.c (main): Likewise.
|
||||
* tests/test-vasnprintf-posix2.sh: Test in both French locales, not only
|
||||
in one of them.
|
||||
* tests/test-vasnwprintf-posix2.sh: Likewise.
|
||||
* modules/vasnprintf-posix-tests (Depends-on): Add localeconv.
|
||||
* modules/vasnwprintf-posix-tests (Depends-on): Likewise.
|
||||
* doc/posix-functions/fprintf.texi: Mention the grouping bug with
|
||||
precision on integers and the grouping bug with a multibyte thousands
|
||||
separator.
|
||||
* 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-11 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
vasnprintf: Follow glibc's behaviour on glibc systems.
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -71,6 +71,14 @@ NetBSD 3.0.
|
||||
This function doesn't support the @code{'} flag on some platforms:
|
||||
NetBSD 3.0, Cygwin 1.5.24.
|
||||
@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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not round the argument of the @samp{a} directive correctly
|
||||
on some platforms:
|
||||
macOS 14, FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4.
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
Solaris 11.4.
|
||||
|
||||
@@ -58,6 +58,14 @@ NetBSD 3.0, mingw, MSVC 14.
|
||||
This function doesn't support the @code{'} flag on some platforms:
|
||||
NetBSD 3.0, Cygwin 1.5.24, mingw, MSVC 14.
|
||||
@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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not round the argument of the @samp{a} directive correctly
|
||||
on some platforms:
|
||||
macOS 14, FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4.
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{b} directive, required by ISO C23,
|
||||
on some platforms:
|
||||
glibc 2.34, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{b} directive, required by ISO C23,
|
||||
on some platforms:
|
||||
glibc 2.34, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, Solaris 11.4, Cygwin 1.5.x.
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
Solaris 11.4.
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{b} directive, required by ISO C23,
|
||||
on some platforms:
|
||||
glibc 2.34, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{a} and @samp{A} directives on some
|
||||
platforms:
|
||||
FreeBSD 5.2.1, OpenBSD 4.0, AIX 5.2, HP-UX 11,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{b} directive, required by ISO C23,
|
||||
on some platforms:
|
||||
glibc 2.34, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{b} directive, required by ISO C23,
|
||||
on some platforms:
|
||||
glibc 2.34, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5,
|
||||
|
||||
@@ -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 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.
|
||||
@item
|
||||
This function doesn't support the @code{'} flag correctly in locales where
|
||||
the thousands separator is a multibyte character on some platforms:
|
||||
NetBSD 10.0, Solaris 11 OpenIndiana.
|
||||
@item
|
||||
This function does not support the @samp{b} directive, required by ISO C23,
|
||||
on some platforms:
|
||||
glibc 2.34, musl libc, macOS 14, FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5,
|
||||
|
||||
484
lib/vasnprintf.c
484
lib/vasnprintf.c
@@ -88,7 +88,7 @@
|
||||
#include <errno.h> /* errno */
|
||||
#include <limits.h> /* CHAR_BIT, INT_MAX, INT_WIDTH, LONG_WIDTH */
|
||||
#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP, LDBL_MANT_DIG */
|
||||
#if HAVE_NL_LANGINFO
|
||||
#if HAVE_NL_LANGINFO || __GLIBC__ >= 2 || defined __CYGWIN__
|
||||
# include <langinfo.h>
|
||||
#endif
|
||||
#ifndef VASNPRINTF
|
||||
@@ -371,7 +371,7 @@ local_wctomb (char *s, wchar_t wc)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#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)
|
||||
#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) || (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
|
||||
/* Determine the decimal-point character according to the current locale. */
|
||||
# ifndef decimal_point_char_defined
|
||||
# define decimal_point_char_defined 1
|
||||
@@ -398,6 +398,94 @@ decimal_point_char (void)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (!WIDE_CHAR_VERSION && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE)) || ((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR) && (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT))
|
||||
/* Determine the thousands-separator character according to the current
|
||||
locale.
|
||||
It is a single multibyte character.
|
||||
In glibc: 35x ".", 90x ",", 23x U+202F, 1x U+2019, 1x U+066C, on other
|
||||
systems also U+00A0. */
|
||||
# ifndef thousands_separator_char_defined
|
||||
# define thousands_separator_char_defined 1
|
||||
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. */
|
||||
# if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __NetBSD__)
|
||||
return nl_langinfo (THOUSEP);
|
||||
# elif 1
|
||||
sprintf (stackbuf, "%'.0f", 1000.0);
|
||||
/* Now stackbuf = "1<thousep>000". */
|
||||
stackbuf[strlen (stackbuf) - 3] = '\0';
|
||||
# if defined __sun
|
||||
/* Solaris specific hack: Replace wrong result (0xC2 means U+00A0). */
|
||||
if (strcmp (&stackbuf[1], "\302") == 0)
|
||||
strcpy (&stackbuf[1], MB_CUR_MAX > 1 ? "\302\240" : "\240");
|
||||
# endif
|
||||
return &stackbuf[1];
|
||||
# else
|
||||
return localeconv () -> thousands_sep;
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
/* Maximum number of 'char' in the char[] representation of the thousands
|
||||
separator. */
|
||||
#define THOUSEP_CHAR_MAXLEN 3
|
||||
|
||||
#if WIDE_CHAR_VERSION && ((NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || ((NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) && DCHAR_IS_TCHAR))
|
||||
/* Determine the thousands-separator character, as a wide character, according
|
||||
to the current locale.
|
||||
It is a single wide character. */
|
||||
# ifndef thousands_separator_wchar_defined
|
||||
# define thousands_separator_wchar_defined 1
|
||||
static const wchar_t *
|
||||
thousands_separator_wchar (wchar_t stackbuf[10])
|
||||
{
|
||||
# if __GLIBC__ >= 2 || defined __CYGWIN__
|
||||
/* On glibc, in the unibyte locale fr_FR, the *wprintf routines use U+202F
|
||||
as separator, which cannot be represented in the locale encoding. */
|
||||
stackbuf[0] =
|
||||
(wchar_t) (unsigned long) nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC);
|
||||
stackbuf[1] = 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). */
|
||||
char tmp[10];
|
||||
sprintf (tmp, "%'.0f", 1000.0);
|
||||
/* Now tmp = L"1<thousep>000". */
|
||||
tmp[strlen (tmp) - 3] = '\0';
|
||||
/* Solaris specific hack: Replace wrong result (0xC2 means U+00A0). */
|
||||
if (strcmp (&tmp[1], "\302") == 0)
|
||||
strcpy (&tmp[1], MB_CUR_MAX > 1 ? "\302\240" : "\240");
|
||||
if (tmp[1] != '\0')
|
||||
{
|
||||
mbstate_t state;
|
||||
mbszero (&state);
|
||||
if ((int) mbrtowc (&stackbuf[0], &tmp[1], strlen (&tmp[1]), &state) > 0)
|
||||
stackbuf[1] = L'\0';
|
||||
else
|
||||
stackbuf[0] = L'\0';
|
||||
}
|
||||
else
|
||||
stackbuf[0] = L'\0';
|
||||
return stackbuf;
|
||||
# else
|
||||
swprintf (stackbuf, 10, L"%'.0f", 1000.0);
|
||||
/* Now stackbuf = L"1<thousep>000". */
|
||||
stackbuf[local_wcslen (stackbuf) - 3] = '\0';
|
||||
return &stackbuf[1];
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
/* Maximum number of 'wchar_t' in the wchar_t[] representation of the thousands
|
||||
separator. */
|
||||
#define THOUSEP_WCHAR_MAXLEN 1
|
||||
|
||||
#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE
|
||||
|
||||
/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
|
||||
@@ -1852,8 +1940,15 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
|
||||
}
|
||||
if (tmp_length < precision)
|
||||
tmp_length = precision;
|
||||
/* Multiply by 2, as an estimate for FLAG_GROUP. */
|
||||
tmp_length = xsum (tmp_length, tmp_length);
|
||||
/* Account for thousands separators. */
|
||||
if (flags & FLAG_GROUP)
|
||||
{
|
||||
# if WIDE_CHAR_VERSION
|
||||
tmp_length = xsum (tmp_length, tmp_length / 3 * THOUSEP_WCHAR_MAXLEN);
|
||||
# else
|
||||
tmp_length = xsum (tmp_length, tmp_length / 3 * THOUSEP_CHAR_MAXLEN);
|
||||
# endif
|
||||
}
|
||||
/* Add 1, to account for a leading sign. */
|
||||
tmp_length = xsum (tmp_length, 1);
|
||||
break;
|
||||
@@ -4903,6 +4998,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
}
|
||||
}
|
||||
# endif
|
||||
/* Account for thousands separators. */
|
||||
if (flags & FLAG_GROUP)
|
||||
{
|
||||
# if WIDE_CHAR_VERSION
|
||||
tmp_length = xsum (tmp_length, tmp_length / 3 * THOUSEP_WCHAR_MAXLEN);
|
||||
# else
|
||||
|
||||
tmp_length = xsum (tmp_length, tmp_length / 3 * THOUSEP_CHAR_MAXLEN);
|
||||
# endif
|
||||
}
|
||||
/* Account for sign, decimal point etc. */
|
||||
tmp_length = xsum (tmp_length, 12);
|
||||
|
||||
@@ -4998,12 +5103,49 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
ndigits = strlen (digits);
|
||||
|
||||
if (ndigits > precision)
|
||||
do
|
||||
{
|
||||
--ndigits;
|
||||
*p++ = digits[ndigits];
|
||||
}
|
||||
while (ndigits > precision);
|
||||
{
|
||||
const DCHAR_T *thousep = NULL;
|
||||
DCHAR_T thousep_buf[10];
|
||||
# if !WIDE_CHAR_VERSION
|
||||
size_t thousep_len;
|
||||
# endif
|
||||
|
||||
if ((flags & FLAG_GROUP)
|
||||
&& (ndigits - precision > 3))
|
||||
{
|
||||
/* Determine the thousands separator of the
|
||||
current locale. */
|
||||
# if WIDE_CHAR_VERSION
|
||||
/* DCHAR_T is wchar_t. */
|
||||
thousep = thousands_separator_wchar (thousep_buf);
|
||||
# else
|
||||
/* DCHAR_T is char. */
|
||||
thousep = thousands_separator_char (thousep_buf);
|
||||
thousep_len = strlen (thousep);
|
||||
# endif
|
||||
if (*thousep == 0)
|
||||
thousep = NULL;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
--ndigits;
|
||||
*p++ = digits[ndigits];
|
||||
if (ndigits == precision)
|
||||
break;
|
||||
if (thousep != NULL
|
||||
/* implies (flags & FLAG_GROUP) */
|
||||
&& ((ndigits - precision) % 3) == 0)
|
||||
{
|
||||
# if WIDE_CHAR_VERSION
|
||||
*p++ = thousep[0];
|
||||
# else
|
||||
memcpy (p, thousep, thousep_len);
|
||||
p += thousep_len;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*p++ = '0';
|
||||
/* Here ndigits <= precision. */
|
||||
@@ -5258,8 +5400,49 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
{
|
||||
size_t ecount = exponent + 1;
|
||||
/* Note: count <= precision = ndigits. */
|
||||
for (; ecount > 0; ecount--)
|
||||
*p++ = digits[--ndigits];
|
||||
|
||||
const DCHAR_T *thousep = NULL;
|
||||
DCHAR_T thousep_buf[10];
|
||||
# if !WIDE_CHAR_VERSION
|
||||
size_t thousep_len;
|
||||
# endif
|
||||
|
||||
if ((flags & FLAG_GROUP) && (ecount > 3))
|
||||
{
|
||||
/* Determine the thousands separator of the
|
||||
current locale. */
|
||||
# if WIDE_CHAR_VERSION
|
||||
/* DCHAR_T is wchar_t. */
|
||||
thousep = thousands_separator_wchar (thousep_buf);
|
||||
# else
|
||||
/* DCHAR_T is char. */
|
||||
thousep = thousands_separator_char (thousep_buf);
|
||||
thousep_len = strlen (thousep);
|
||||
# endif
|
||||
if (*thousep == 0)
|
||||
thousep = NULL;
|
||||
}
|
||||
|
||||
if (ecount > 0)
|
||||
for (;;)
|
||||
{
|
||||
--ndigits;
|
||||
*p++ = digits[ndigits];
|
||||
if (--ecount == 0)
|
||||
break;
|
||||
if (thousep != NULL
|
||||
/* implies (flags & FLAG_GROUP) */
|
||||
&& (ecount % 3) == 0)
|
||||
{
|
||||
# if WIDE_CHAR_VERSION
|
||||
*p++ = thousep[0];
|
||||
# else
|
||||
memcpy (p, thousep, thousep_len);
|
||||
p += thousep_len;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & FLAG_ALT) || ndigits > nzeroes)
|
||||
{
|
||||
*p++ = decimal_point_char ();
|
||||
@@ -5460,12 +5643,49 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
ndigits = strlen (digits);
|
||||
|
||||
if (ndigits > precision)
|
||||
do
|
||||
{
|
||||
--ndigits;
|
||||
*p++ = digits[ndigits];
|
||||
}
|
||||
while (ndigits > precision);
|
||||
{
|
||||
const DCHAR_T *thousep = NULL;
|
||||
DCHAR_T thousep_buf[10];
|
||||
# if !WIDE_CHAR_VERSION
|
||||
size_t thousep_len;
|
||||
# endif
|
||||
|
||||
if ((flags & FLAG_GROUP)
|
||||
&& (ndigits - precision > 3))
|
||||
{
|
||||
/* Determine the thousands separator of the
|
||||
current locale. */
|
||||
# if WIDE_CHAR_VERSION
|
||||
/* DCHAR_T is wchar_t. */
|
||||
thousep = thousands_separator_wchar (thousep_buf);
|
||||
# else
|
||||
/* DCHAR_T is char. */
|
||||
thousep = thousands_separator_char (thousep_buf);
|
||||
thousep_len = strlen (thousep);
|
||||
# endif
|
||||
if (*thousep == 0)
|
||||
thousep = NULL;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
--ndigits;
|
||||
*p++ = digits[ndigits];
|
||||
if (ndigits == precision)
|
||||
break;
|
||||
if (thousep != NULL
|
||||
/* implies (flags & FLAG_GROUP) */
|
||||
&& ((ndigits - precision) % 3) == 0)
|
||||
{
|
||||
# if WIDE_CHAR_VERSION
|
||||
*p++ = thousep[0];
|
||||
# else
|
||||
memcpy (p, thousep, thousep_len);
|
||||
p += thousep_len;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*p++ = '0';
|
||||
/* Here ndigits <= precision. */
|
||||
@@ -5728,8 +5948,49 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
{
|
||||
size_t ecount = exponent + 1;
|
||||
/* Note: ecount <= precision = ndigits. */
|
||||
for (; ecount > 0; ecount--)
|
||||
*p++ = digits[--ndigits];
|
||||
|
||||
const DCHAR_T *thousep = NULL;
|
||||
DCHAR_T thousep_buf[10];
|
||||
# if !WIDE_CHAR_VERSION
|
||||
size_t thousep_len;
|
||||
# endif
|
||||
|
||||
if ((flags & FLAG_GROUP) && (ecount > 3))
|
||||
{
|
||||
/* Determine the thousands separator of the
|
||||
current locale. */
|
||||
# if WIDE_CHAR_VERSION
|
||||
/* DCHAR_T is wchar_t. */
|
||||
thousep = thousands_separator_wchar (thousep_buf);
|
||||
# else
|
||||
/* DCHAR_T is char. */
|
||||
thousep = thousands_separator_char (thousep_buf);
|
||||
thousep_len = strlen (thousep);
|
||||
# endif
|
||||
if (*thousep == 0)
|
||||
thousep = NULL;
|
||||
}
|
||||
|
||||
if (ecount > 0)
|
||||
for (;;)
|
||||
{
|
||||
--ndigits;
|
||||
*p++ = digits[ndigits];
|
||||
if (--ecount == 0)
|
||||
break;
|
||||
if (thousep != NULL
|
||||
/* implies (flags & FLAG_GROUP) */
|
||||
&& (ecount % 3) == 0)
|
||||
{
|
||||
# if WIDE_CHAR_VERSION
|
||||
*p++ = thousep[0];
|
||||
# else
|
||||
memcpy (p, thousep, thousep_len);
|
||||
p += thousep_len;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & FLAG_ALT) || ndigits > nzeroes)
|
||||
{
|
||||
*p++ = decimal_point_char ();
|
||||
@@ -5937,13 +6198,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
{
|
||||
arg_type type = a.arg[dp->arg_index].type;
|
||||
int flags = dp->flags;
|
||||
#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
|
||||
#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
int has_width;
|
||||
#endif
|
||||
#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
|
||||
#if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
size_t width;
|
||||
#endif
|
||||
#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
|
||||
#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
int has_precision;
|
||||
size_t precision;
|
||||
#endif
|
||||
@@ -5952,9 +6213,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
#else
|
||||
# define prec_ourselves 0
|
||||
#endif
|
||||
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
int group_ourselves;
|
||||
#else
|
||||
# define group_ourselves 0
|
||||
#endif
|
||||
#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST
|
||||
# define pad_ourselves 1
|
||||
#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
|
||||
#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
int pad_ourselves;
|
||||
#else
|
||||
# define pad_ourselves 0
|
||||
@@ -5969,10 +6235,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
TCHAR_T *tmp;
|
||||
#endif
|
||||
|
||||
#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
|
||||
#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
has_width = 0;
|
||||
#endif
|
||||
#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
|
||||
#if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
width = 0;
|
||||
if (dp->width_start != dp->width_end)
|
||||
{
|
||||
@@ -6003,13 +6269,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
if (width > (size_t) INT_MAX)
|
||||
goto overflow;
|
||||
# define WIDTH_IS_CHECKED 1
|
||||
# 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
|
||||
# if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
has_width = 1;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#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
|
||||
#if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
has_precision = 0;
|
||||
precision = 6;
|
||||
if (dp->precision_start != dp->precision_end)
|
||||
@@ -6074,8 +6340,37 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Decide whether to add the thousands separators ourselves. */
|
||||
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
if (flags & FLAG_GROUP)
|
||||
{
|
||||
switch (dp->conversion)
|
||||
{
|
||||
case 'd': case 'i': case 'u':
|
||||
# if NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
group_ourselves = 1;
|
||||
# else
|
||||
group_ourselves = prec_ourselves;
|
||||
# endif
|
||||
break;
|
||||
case 'f': case 'F': case 'g': case 'G':
|
||||
# if NEED_PRINTF_FLAG_GROUPING
|
||||
group_ourselves = 1;
|
||||
# else
|
||||
group_ourselves = prec_ourselves;
|
||||
# endif
|
||||
break;
|
||||
default:
|
||||
group_ourselves = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
group_ourselves = 0;
|
||||
#endif
|
||||
|
||||
/* Decide whether to perform the padding ourselves. */
|
||||
#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)
|
||||
#if !((WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST) && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
|
||||
switch (dp->conversion)
|
||||
{
|
||||
# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
|
||||
@@ -6092,7 +6387,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
pad_ourselves = 1;
|
||||
break;
|
||||
default:
|
||||
pad_ourselves = prec_ourselves;
|
||||
pad_ourselves = prec_ourselves | group_ourselves;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -6125,14 +6420,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
sprintf. */
|
||||
fbp = buf;
|
||||
*fbp++ = '%';
|
||||
#if NEED_PRINTF_FLAG_GROUPING
|
||||
/* The underlying implementation doesn't support the ' flag.
|
||||
Produce no grouping characters in this case; this is
|
||||
acceptable because the grouping is locale dependent. */
|
||||
#else
|
||||
if (flags & FLAG_GROUP)
|
||||
if ((flags & FLAG_GROUP) && !group_ourselves)
|
||||
*fbp++ = '\'';
|
||||
#endif
|
||||
if (flags & FLAG_LEFT)
|
||||
*fbp++ = '-';
|
||||
if (flags & FLAG_SHOWSIGN)
|
||||
@@ -6947,6 +7236,124 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
if (group_ourselves) /* implies (flags & FLAG_GROUP) */
|
||||
/* Handle the grouping. */
|
||||
switch (dp->conversion)
|
||||
{
|
||||
/* These are the only conversion to which grouping
|
||||
applies. */
|
||||
case 'd': case 'i': case 'u':
|
||||
case 'f': case 'F': case 'g': case 'G':
|
||||
{
|
||||
/* Determine the thousands separator of the current
|
||||
locale. */
|
||||
const TCHAR_T *thousep;
|
||||
TCHAR_T thousep_buf[10];
|
||||
|
||||
# if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
|
||||
/* TCHAR_T is wchar_t. */
|
||||
thousep = thousands_separator_wchar (thousep_buf);
|
||||
# else
|
||||
/* TCHAR_T is char. */
|
||||
thousep = thousands_separator_char (thousep_buf);
|
||||
# endif
|
||||
|
||||
/* Nothing to do in locales where thousep is the empty
|
||||
string. */
|
||||
if (*thousep != 0)
|
||||
{
|
||||
/* Since FLAG_LOCALIZED is only supported on glibc
|
||||
systems, here we can assume that all digits are
|
||||
the ASCII digits '0'..'9'. */
|
||||
TCHAR_T *number_ptr =
|
||||
# if USE_SNPRINTF
|
||||
(TCHAR_T *) (result + length);
|
||||
# else
|
||||
tmp;
|
||||
# endif
|
||||
TCHAR_T *end_ptr = number_ptr + count;
|
||||
|
||||
/* Find where the leading digits start. */
|
||||
TCHAR_T *digits_ptr = number_ptr;
|
||||
if (count >= 1
|
||||
&& (*digits_ptr == '-' || *digits_ptr == '+'
|
||||
|| *digits_ptr == ' '))
|
||||
digits_ptr++;
|
||||
|
||||
/* Find where the leading digits end. */
|
||||
TCHAR_T *digits_end_ptr;
|
||||
switch (dp->conversion)
|
||||
{
|
||||
case 'd': case 'i': case 'u':
|
||||
digits_end_ptr = end_ptr;
|
||||
break;
|
||||
case 'f': case 'F': case 'g': case 'G':
|
||||
{
|
||||
TCHAR_T decimal_point = decimal_point_char ();
|
||||
for (digits_end_ptr = digits_ptr;
|
||||
digits_end_ptr < end_ptr;
|
||||
digits_end_ptr++)
|
||||
if (*digits_end_ptr == decimal_point
|
||||
|| *digits_end_ptr == 'e')
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Determine the number of thousands separators
|
||||
to insert. */
|
||||
size_t insert = digits_end_ptr - digits_ptr;
|
||||
insert = (insert > 0 ? (insert - 1) / 3 : 0);
|
||||
if (insert > 0)
|
||||
{
|
||||
# if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
|
||||
# define thousep_len 1
|
||||
# else
|
||||
size_t thousep_len = strlen (thousep);
|
||||
# endif
|
||||
# if USE_SNPRINTF
|
||||
size_t digits_offset = digits_ptr - number_ptr;
|
||||
size_t digits_end_offset = digits_end_ptr - number_ptr;
|
||||
size_t n =
|
||||
xsum (length,
|
||||
(count + insert * thousep_len + TCHARS_PER_DCHAR - 1)
|
||||
/ TCHARS_PER_DCHAR);
|
||||
length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
|
||||
ENSURE_ALLOCATION (n);
|
||||
length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
|
||||
number_ptr = (TCHAR_T *) (result + length);
|
||||
end_ptr = number_ptr + count;
|
||||
digits_ptr = number_ptr + digits_offset;
|
||||
digits_end_ptr = number_ptr + digits_end_offset;
|
||||
# endif
|
||||
|
||||
count += insert * thousep_len;
|
||||
|
||||
const TCHAR_T *p = end_ptr;
|
||||
TCHAR_T *q = end_ptr + insert * thousep_len;
|
||||
while (p > digits_end_ptr)
|
||||
*--q = *--p;
|
||||
for (; insert > 0; insert--)
|
||||
{
|
||||
*--q = *--p;
|
||||
*--q = *--p;
|
||||
*--q = *--p;
|
||||
# if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
|
||||
*--q = *thousep;
|
||||
# else
|
||||
q -= thousep_len;
|
||||
memcpy (q, thousep, thousep_len);
|
||||
# endif
|
||||
}
|
||||
/* Here q == p. Done with the insertions. */
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !USE_SNPRINTF
|
||||
if (count >= tmp_length)
|
||||
/* tmp_length was incorrectly calculated - fix the
|
||||
@@ -6957,6 +7364,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
#if !DCHAR_IS_TCHAR
|
||||
/* Convert from TCHAR_T[] to DCHAR_T[]. */
|
||||
if (dp->conversion == 'c' || dp->conversion == 's'
|
||||
|| (flags & FLAG_GROUP)
|
||||
# if __GLIBC__ >= 2 && !defined __UCLIBC__
|
||||
|| (flags & FLAG_LOCALIZED)
|
||||
# endif
|
||||
@@ -7098,7 +7506,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
|
||||
/* Here count <= allocated - length. */
|
||||
|
||||
/* Perform padding. */
|
||||
#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
|
||||
#if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
|
||||
if (pad_ourselves && has_width)
|
||||
{
|
||||
size_t w;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# dprintf-posix.m4
|
||||
# serial 10
|
||||
# serial 11
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_DPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -67,19 +69,27 @@ AC_DEFUN([gl_FUNC_DPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
# dprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_dprintf_posix=yes
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
# dprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_dprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# fprintf-posix.m4
|
||||
# serial 21
|
||||
# serial 22
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_FPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -65,19 +67,27 @@ AC_DEFUN([gl_FUNC_FPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
# fprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_fprintf_posix=yes
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
# fprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_fprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# obstack-printf-posix.m4
|
||||
# serial 11
|
||||
# serial 12
|
||||
dnl Copyright (C) 2008-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,
|
||||
@@ -37,6 +37,8 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -71,19 +73,27 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
# obstack_printf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_obstack_printf_posix=yes
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
# obstack_printf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_obstack_printf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
252
m4/printf.m4
252
m4/printf.m4
@@ -1,5 +1,5 @@
|
||||
# printf.m4
|
||||
# serial 95
|
||||
# serial 96
|
||||
dnl Copyright (C) 2003, 2007-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,
|
||||
@@ -1186,6 +1186,112 @@ changequote([,])dnl
|
||||
])
|
||||
])
|
||||
|
||||
dnl Test whether the *printf family of functions supports POSIX/XSI format
|
||||
dnl strings with the ' flag for grouping of decimal digits on integers,
|
||||
dnl together with a precision.
|
||||
dnl Result is gl_cv_func_printf_flag_grouping_int_precision.
|
||||
|
||||
AC_DEFUN([gl_PRINTF_FLAG_GROUPING_INT_PRECISION],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_CACHE_CHECK([whether printf supports grouping on integers with a precision],
|
||||
[gl_cv_func_printf_flag_grouping_int_precision],
|
||||
[
|
||||
dnl Prepare a guess, used when cross-compiling or when specific locales
|
||||
dnl are not available.
|
||||
case "$host_os" in
|
||||
# Guess no on FreeBSD, NetBSD, Solaris, Cygwin, Haiku.
|
||||
freebsd* | dragonfly* | netbsd* | solaris* | cygwin* | haiku*)
|
||||
gl_cv_func_printf_flag_grouping_int_precision="guessing no";;
|
||||
*)
|
||||
gl_cv_func_printf_flag_grouping_int_precision="guessing yes";;
|
||||
esac
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_SOURCE([[
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
static char buf[100];
|
||||
int main ()
|
||||
{
|
||||
if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL
|
||||
|| setlocale (LC_ALL, "fr_FR") != NULL
|
||||
|| setlocale (LC_ALL, "fr_FR.ISO-8859-1") != NULL
|
||||
|| setlocale (LC_ALL, "fr_FR.ISO8859-1") != NULL)
|
||||
{
|
||||
if (sprintf (buf, "%'.10d", 1000) < 0)
|
||||
return 1;
|
||||
if (strlen (buf) == 10 && strcmp (buf, "0000001000") != 0)
|
||||
/* The sprintf implementation has produced fewer than 10 digits. */
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 3;
|
||||
}]])],
|
||||
[gl_cv_func_printf_flag_grouping_int_precision=yes],
|
||||
[if test $? = 2; then
|
||||
gl_cv_func_printf_flag_grouping_int_precision=no
|
||||
fi
|
||||
],
|
||||
[:])
|
||||
])
|
||||
])
|
||||
|
||||
dnl Test whether the *printf family of functions supports POSIX/XSI format
|
||||
dnl strings with the ' flag for grouping of decimal digits, when the thousands
|
||||
dnl separator is a multibyte character (such as U+00A0 or U+202F in a UTF-8
|
||||
dnl locale).
|
||||
dnl Result is gl_cv_func_printf_flag_grouping_multibyte.
|
||||
|
||||
AC_DEFUN([gl_PRINTF_FLAG_GROUPING_MULTIBYTE],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_CACHE_CHECK([whether printf supports grouping with a multibyte separator],
|
||||
[gl_cv_func_printf_flag_grouping_multibyte],
|
||||
[
|
||||
dnl Prepare a guess, used when cross-compiling or when specific locales
|
||||
dnl are not available.
|
||||
case "$host_os" in
|
||||
# Guess no on NetBSD and Solaris 11 OpenIndiana.
|
||||
netbsd* | solaris*)
|
||||
gl_cv_func_printf_flag_grouping_multibyte="guessing no";;
|
||||
*)
|
||||
gl_cv_func_printf_flag_grouping_multibyte="guessing yes";;
|
||||
esac
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_SOURCE([[
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
static char buf[100];
|
||||
int main ()
|
||||
{
|
||||
if (setlocale (LC_ALL, "fr_FR.UTF-8") == NULL)
|
||||
return 0;
|
||||
if (sprintf (buf, "%'.0f", 1000.0) < 0)
|
||||
return 1;
|
||||
if (strlen (localeconv ()->thousands_sep) > 1)
|
||||
{
|
||||
if (strlen (buf) <= 4 + 1)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}]])],
|
||||
[:],
|
||||
[case $? in
|
||||
2) gl_cv_func_printf_flag_grouping_multibyte=no ;;
|
||||
3) gl_cv_func_printf_flag_grouping_multibyte=yes ;;
|
||||
esac
|
||||
],
|
||||
[:])
|
||||
])
|
||||
])
|
||||
|
||||
dnl Test whether the *printf family of functions supports the - flag correctly.
|
||||
dnl (ISO C99.) See
|
||||
dnl <https://lists.gnu.org/r/bug-coreutils/2008-02/msg00035.html>
|
||||
@@ -2161,20 +2267,22 @@ dnl 11 = gl_PRINTF_DIRECTIVE_LS
|
||||
dnl 12 = gl_PRINTF_DIRECTIVE_LC
|
||||
dnl 13 = gl_PRINTF_POSITIONS
|
||||
dnl 14 = gl_PRINTF_FLAG_GROUPING
|
||||
dnl 15 = gl_PRINTF_FLAG_LEFTADJUST
|
||||
dnl 16 = gl_PRINTF_FLAG_ZERO
|
||||
dnl 17 = gl_PRINTF_FLAG_ALT_PRECISION_ZERO
|
||||
dnl 18 = gl_PRINTF_PRECISION
|
||||
dnl 19 = gl_PRINTF_ENOMEM
|
||||
dnl 20 = gl_SNPRINTF_PRESENCE
|
||||
dnl 21 = gl_SNPRINTF_TRUNCATION_C99
|
||||
dnl 22 = gl_SNPRINTF_RETVAL_C99
|
||||
dnl 23 = gl_SNPRINTF_DIRECTIVE_N
|
||||
dnl 24 = gl_SNPRINTF_SIZE1
|
||||
dnl 25 = gl_VSNPRINTF_ZEROSIZE_C99
|
||||
dnl 26 = gl_SWPRINTF_WORKS
|
||||
dnl 27 = gl_SWPRINTF_DIRECTIVE_LA
|
||||
dnl 28 = gl_SWPRINTF_DIRECTIVE_LC
|
||||
dnl 15 = gl_PRINTF_FLAG_GROUPING_INT_PRECISION
|
||||
dnl 16 = gl_PRINTF_FLAG_GROUPING_MULTIBYTE
|
||||
dnl 17 = gl_PRINTF_FLAG_LEFTADJUST
|
||||
dnl 18 = gl_PRINTF_FLAG_ZERO
|
||||
dnl 19 = gl_PRINTF_FLAG_ALT_PRECISION_ZERO
|
||||
dnl 20 = gl_PRINTF_PRECISION
|
||||
dnl 21 = gl_PRINTF_ENOMEM
|
||||
dnl 22 = gl_SNPRINTF_PRESENCE
|
||||
dnl 23 = gl_SNPRINTF_TRUNCATION_C99
|
||||
dnl 24 = gl_SNPRINTF_RETVAL_C99
|
||||
dnl 25 = gl_SNPRINTF_DIRECTIVE_N
|
||||
dnl 26 = gl_SNPRINTF_SIZE1
|
||||
dnl 27 = gl_VSNPRINTF_ZEROSIZE_C99
|
||||
dnl 28 = gl_SWPRINTF_WORKS
|
||||
dnl 29 = gl_SWPRINTF_DIRECTIVE_LA
|
||||
dnl 30 = gl_SWPRINTF_DIRECTIVE_LC
|
||||
dnl
|
||||
dnl 1 = checking whether printf supports size specifiers as in C99...
|
||||
dnl 2 = checking whether printf supports size specifiers as in C23...
|
||||
@@ -2190,62 +2298,64 @@ dnl 11 = checking whether printf supports the 'ls' directive...
|
||||
dnl 12 = checking whether printf supports the 'lc' directive correctly...
|
||||
dnl 13 = checking whether printf supports POSIX/XSI format strings with positions...
|
||||
dnl 14 = checking whether printf supports the grouping flag...
|
||||
dnl 15 = checking whether printf supports the left-adjust flag correctly...
|
||||
dnl 16 = checking whether printf supports the zero flag correctly...
|
||||
dnl 17 = checking whether printf supports the alternative flag with a zero precision...
|
||||
dnl 18 = checking whether printf supports large precisions...
|
||||
dnl 19 = checking whether printf survives out-of-memory conditions...
|
||||
dnl 20 = checking for snprintf...
|
||||
dnl 21 = checking whether snprintf truncates the result as in C99...
|
||||
dnl 22 = checking whether snprintf returns a byte count as in C99...
|
||||
dnl 23 = checking whether snprintf fully supports the 'n' directive...
|
||||
dnl 24 = checking whether snprintf respects a size of 1...
|
||||
dnl 25 = checking whether vsnprintf respects a zero size as in C99...
|
||||
dnl 26 = checking whether swprintf works...
|
||||
dnl 27 = checking whether swprintf supports the 'La' and 'LA' directives...
|
||||
dnl 28 = checking whether swprintf supports the 'lc' directive...
|
||||
dnl 15 = checking whether printf supports grouping on integers with a precision...
|
||||
dnl 16 = checking whether printf supports grouping with a multibyte separator...
|
||||
dnl 17 = checking whether printf supports the left-adjust flag correctly...
|
||||
dnl 18 = checking whether printf supports the zero flag correctly...
|
||||
dnl 19 = checking whether printf supports the alternative flag with a zero precision...
|
||||
dnl 20 = checking whether printf supports large precisions...
|
||||
dnl 21 = checking whether printf survives out-of-memory conditions...
|
||||
dnl 22 = checking for snprintf...
|
||||
dnl 23 = checking whether snprintf truncates the result as in C99...
|
||||
dnl 24 = checking whether snprintf returns a byte count as in C99...
|
||||
dnl 25 = checking whether snprintf fully supports the 'n' directive...
|
||||
dnl 26 = checking whether snprintf respects a size of 1...
|
||||
dnl 27 = checking whether vsnprintf respects a zero size as in C99...
|
||||
dnl 28 = checking whether swprintf works...
|
||||
dnl 29 = checking whether swprintf supports the 'La' and 'LA' directives...
|
||||
dnl 30 = checking whether swprintf supports the 'lc' directive...
|
||||
dnl
|
||||
dnl . = yes, # = no.
|
||||
dnl
|
||||
dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
||||
dnl musl libc 1.2.3 . # . . . . # # . . . # . . . . ? . . . . . . . . # . #
|
||||
dnl glibc 2.35 . # . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
dnl glibc 2.5 . # . . . . # # . . . . . . . . . . . . . . . . . . # .
|
||||
dnl glibc 2.3.6 . # . . . # # # . . . . . . . . . . . . . . . . . . # .
|
||||
dnl FreeBSD 14.0 . . . . . # . . . . . . . . . . . . # . . . . . . # . #
|
||||
dnl FreeBSD 13.0 . # . . . # # # . . . . . . . . . . # . . . . . . # . #
|
||||
dnl FreeBSD 5.4, 6.1 . # . . . # # # . . . . . . . # ? . # . . . . . . # ? ?
|
||||
dnl Mac OS X 10.13.5 . # . . # # # # . # . . . . . . . . . . . . # . . # ? ?
|
||||
dnl Mac OS X 10.5.8 . # . . # # # # . . . . . . . # # . . . . . . . . # ? ?
|
||||
dnl Mac OS X 10.3.9 . # . . . # # # . . . . . . . # # . # . . . . . . # ? ?
|
||||
dnl OpenBSD 6.0, 6.7 . # . . . # # # . . . . . . . . . . # . . . . . . # . #
|
||||
dnl OpenBSD 3.9, 4.0 . # . # # # # # # . # . . # . # ? . # . . . . . . # ? ?
|
||||
dnl Cygwin 1.7.0 (2009) . # . . # . # # . . ? ? . . . . ? . ? . . . . . . ? ? ?
|
||||
dnl Cygwin 1.5.25 (2008) . # . . # # # # . . # ? . . . . ? . # . . . . . . ? ? ?
|
||||
dnl Cygwin 1.5.19 (2006) # # . . # # # # # . # ? . # . # ? # # . . . . . . ? ? ?
|
||||
dnl Solaris 11.4 . # . # # # # # . . # . . . . # . . . . . . . . . . # .
|
||||
dnl Solaris 11.3 . # . . . # # # . . # . . . . . . . . . . . . . . . # .
|
||||
dnl Solaris 11.0 . # . # # # # # . . # . . . . # . . . . . . . . . ? ? ?
|
||||
dnl Solaris 10 . # . # # # # # . . # . . . . # . # . . . . . . . . # .
|
||||
dnl Solaris 2.6 ... 9 # # . # # # # # # . # . . . . # ? # . . . # . . . ? ? ?
|
||||
dnl Solaris 2.5.1 # # . # # # # # # . # . . . . # ? . . # # # # # # ? ? ?
|
||||
dnl AIX 7.1 . # . # # # # # . . . . . . . # . # . . . . . . . # . .
|
||||
dnl AIX 5.2 . # . # # # # # . . . . . . . # ? . . . . . . . . # ? ?
|
||||
dnl AIX 4.3.2, 5.1 # # . # # # # # # . . . . . . # ? . . . . # . . . # ? ?
|
||||
dnl HP-UX 11.31 . # . . . # # # . . . ? . . . # ? . . . . # # . . ? ? ?
|
||||
dnl HP-UX 11.{00,11,23} # # . . . # # # # . . ? . . . # ? . . . . # # . # ? ? ?
|
||||
dnl HP-UX 10.20 # # . # . # # # # . ? ? . . # # ? . . . . # # ? # ? ? ?
|
||||
dnl IRIX 6.5 # # . # # # # # # . # . . . . # ? . . . . # . . . # ? ?
|
||||
dnl OSF/1 5.1 # # . # # # # # # . . ? . . . # ? . . . . # . . # ? ? ?
|
||||
dnl OSF/1 4.0d # # . # # # # # # . . ? . . . # ? . . # # # # # # ? ? ?
|
||||
dnl NetBSD 9.0 . # . . . # # # . . . . . . . . . . . . . . . . . # . #
|
||||
dnl NetBSD 5.0 . # . . # # # # . . . . . . . # ? . # . . . . . . # ? ?
|
||||
dnl NetBSD 4.0 . # ? ? ? ? # # ? . ? . . ? ? ? ? ? ? . . . ? ? ? # ? ?
|
||||
dnl NetBSD 3.0 . # . . . # # # # . ? . # # ? # ? . # . . . . . . # ? ?
|
||||
dnl Haiku . # . . # # # # # . # ? . . . . ? . ? . . ? . . . . # .
|
||||
dnl BeOS # # # . # # # # # . ? ? # . ? . ? # ? . . ? . . . ? ? ?
|
||||
dnl Android 4.3 . # . # # # # # # # # ? . # . # ? . # . . . # . . ? ? ?
|
||||
dnl old mingw / msvcrt # # # # # # # # # . . ? # # . # ? # ? . # # # . . # ? ?
|
||||
dnl MSVC 9 # # # # # # # # # # . ? # # . # ? # ? # # # # . . # ? ?
|
||||
dnl mingw 2009-2011 . # # . # . # # . . . ? # # . . ? . ? . . . . . . # ? ?
|
||||
dnl mingw-w64 2011 # # # # # # # # # . . ? # # . # ? # ? . # # # . . # ? ?
|
||||
dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
||||
dnl musl libc 1.2.3 . # . . . . # # . . . # . . . . . . . . . . . . . . . # . #
|
||||
dnl glibc 2.35 . # . . . . . . . . . . . . # . . . . . . . . . . . . . . .
|
||||
dnl glibc 2.5 . # . . . . # # . . . . . . # . . . . . . . . . . . . . # .
|
||||
dnl glibc 2.3.6 . # . . . # # # . . . . . . . . . . . . . . . . . . . . # .
|
||||
dnl FreeBSD 14.0 . . . . . # . . . . . . . . # . . . . . # . . . . . . # . #
|
||||
dnl FreeBSD 13.0 . # . . . # # # . . . . . . # . . . . . # . . . . . . # . #
|
||||
dnl FreeBSD 5.4, 6.1 . # . . . # # # . . . . . . . . . # ? . # . . . . . . # ? ?
|
||||
dnl Mac OS X 10.13.5 . # . . # # # # . # . . . . ? ? . . . . . . . . # . . # ? ?
|
||||
dnl Mac OS X 10.5.8 . # . . # # # # . . . . . . ? ? . # # . . . . . . . . # ? ?
|
||||
dnl Mac OS X 10.3.9 . # . . . # # # . . . . . . ? ? . # # . # . . . . . . # ? ?
|
||||
dnl OpenBSD 6.0, 6.7 . # . . . # # # . . . . . . . . . . . . # . . . . . . # . #
|
||||
dnl OpenBSD 3.9, 4.0 . # . # # # # # # . # . . # ? ? . # ? . # . . . . . . # ? ?
|
||||
dnl Cygwin 1.7.0 (2009) . # . . # . # # . . ? ? . . ? ? . . ? . ? . . . . . . ? ? ?
|
||||
dnl Cygwin 1.5.25 (2008) . # . . # # # # . . # ? . . ? ? . . ? . # . . . . . . ? ? ?
|
||||
dnl Cygwin 1.5.19 (2006) # # . . # # # # # . # ? . # ? ? . # ? # # . . . . . . ? ? ?
|
||||
dnl Solaris 11.4 . # . # # # # # . . # . . . # # . # . . . . . . . . . . # .
|
||||
dnl Solaris 11.3 . # . . . # # # . . # . . . ? ? . . . . . . . . . . . . # .
|
||||
dnl Solaris 11.0 . # . # # # # # . . # . . . ? ? . # . . . . . . . . . ? ? ?
|
||||
dnl Solaris 10 . # . # # # # # . . # . . . ? ? . # . # . . . . . . . . # .
|
||||
dnl Solaris 2.6 ... 9 # # . # # # # # # . # . . . ? ? . # ? # . . . # . . . ? ? ?
|
||||
dnl Solaris 2.5.1 # # . # # # # # # . # . . . ? ? . # ? . . # # # # # # ? ? ?
|
||||
dnl AIX 7.1 . # . # # # # # . . . . . . ? ? . # . # . . . . . . . # . .
|
||||
dnl AIX 5.2 . # . # # # # # . . . . . . ? ? . # ? . . . . . . . . # ? ?
|
||||
dnl AIX 4.3.2, 5.1 # # . # # # # # # . . . . . ? ? . # ? . . . . # . . . # ? ?
|
||||
dnl HP-UX 11.31 . # . . . # # # . . . ? . . ? ? . # ? . . . . # # . . ? ? ?
|
||||
dnl HP-UX 11.{00,11,23} # # . . . # # # # . . ? . . ? ? . # ? . . . . # # . # ? ? ?
|
||||
dnl HP-UX 10.20 # # . # . # # # # . ? ? . . ? ? # # ? . . . . # # ? # ? ? ?
|
||||
dnl IRIX 6.5 # # . # # # # # # . # . . . ? ? . # ? . . . . # . . . # ? ?
|
||||
dnl OSF/1 5.1 # # . # # # # # # . . ? . . ? ? . # ? . . . . # . . # ? ? ?
|
||||
dnl OSF/1 4.0d # # . # # # # # # . . ? . . ? ? . # ? . . # # # # # # ? ? ?
|
||||
dnl NetBSD 9.0 . # . . . # # # . . . . . . # # . . . . . . . . . . . # . #
|
||||
dnl NetBSD 5.0 . # . . # # # # . . . . . . ? ? . # ? . # . . . . . . # ? ?
|
||||
dnl NetBSD 4.0 . # ? ? ? ? # # ? . ? . . ? ? ? ? ? ? ? ? . . . ? ? ? # ? ?
|
||||
dnl NetBSD 3.0 . # . . . # # # # . ? . # # ? ? ? # ? . # . . . . . . # ? ?
|
||||
dnl Haiku . # . . # # # # # . # ? . . # . . . ? . ? . . ? . . . . # .
|
||||
dnl BeOS # # # . # # # # # . ? ? # . ? ? ? . ? # ? . . ? . . . ? ? ?
|
||||
dnl Android 4.3 . # . # # # # # # # # ? . # ? ? . # ? . # . . . # . . ? ? ?
|
||||
dnl old mingw / msvcrt # # # # # # # # # . . ? # # ? ? . # ? # ? . # # # . . # ? ?
|
||||
dnl MSVC 9 # # # # # # # # # # . ? # # ? ? . # ? # ? # # # # . . # ? ?
|
||||
dnl mingw 2009-2011 . # # . # . # # . . . ? # # ? ? . . ? . ? . . . . . . # ? ?
|
||||
dnl mingw-w64 2011 # # # # # # # # # . . ? # # ? ? . # ? # ? . # # # . . # ? ?
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# snprintf-posix.m4
|
||||
# serial 22
|
||||
# serial 23
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_SNPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -72,29 +74,37 @@ AC_DEFUN([gl_FUNC_SNPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_snprintf_truncation_c99" in
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_snprintf_retval_c99" in
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
case m4_ifdef([gl_PRINTF_SUPPORT_N_DIRECTIVE],["$gl_cv_func_snprintf_directive_n"],["yes"]) in
|
||||
case "$gl_cv_func_snprintf_truncation_c99" in
|
||||
*yes)
|
||||
case "$gl_cv_func_snprintf_size1" in
|
||||
case "$gl_cv_func_snprintf_retval_c99" in
|
||||
*yes)
|
||||
case "$gl_cv_func_vsnprintf_zerosize_c99" in
|
||||
case m4_ifdef([gl_PRINTF_SUPPORT_N_DIRECTIVE],["$gl_cv_func_snprintf_directive_n"],["yes"]) in
|
||||
*yes)
|
||||
# snprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_snprintf_posix=yes
|
||||
case "$gl_cv_func_snprintf_size1" in
|
||||
*yes)
|
||||
case "$gl_cv_func_vsnprintf_zerosize_c99" in
|
||||
*yes)
|
||||
# snprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_snprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# sprintf-posix.m4
|
||||
# serial 19
|
||||
# serial 20
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_SPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -65,19 +67,27 @@ AC_DEFUN([gl_FUNC_SPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
# sprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_sprintf_posix=yes
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
# sprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_sprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vasnprintf-posix.m4
|
||||
# serial 20
|
||||
# serial 21
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -32,6 +32,8 @@ AC_DEFUN_ONCE([gl_FUNC_VASNPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -65,21 +67,29 @@ AC_DEFUN_ONCE([gl_FUNC_VASNPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
if test $ac_cv_func_vasnprintf = yes; then
|
||||
# vasnprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vasnprintf_posix=yes
|
||||
fi
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
if test $ac_cv_func_vasnprintf = yes; then
|
||||
# vasnprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vasnprintf_posix=yes
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vasnprintf.m4
|
||||
# serial 54
|
||||
# serial 55
|
||||
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,
|
||||
@@ -358,8 +358,19 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_LC],
|
||||
AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING],
|
||||
[
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
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)
|
||||
;;
|
||||
*)
|
||||
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], [1],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vasprintf-posix.m4
|
||||
# serial 20
|
||||
# serial 21
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_VASPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -66,21 +68,29 @@ AC_DEFUN([gl_FUNC_VASPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
if test $ac_cv_func_vasprintf = yes; then
|
||||
# vasprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vasprintf_posix=yes
|
||||
fi
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
if test $ac_cv_func_vasprintf = yes; then
|
||||
# vasprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vasprintf_posix=yes
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vdprintf-posix.m4
|
||||
# serial 10
|
||||
# serial 11
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_VDPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -67,19 +69,27 @@ AC_DEFUN([gl_FUNC_VDPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
# vdprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vdprintf_posix=yes
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
# vdprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vdprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vfprintf-posix.m4
|
||||
# serial 21
|
||||
# serial 22
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_VFPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -65,19 +67,27 @@ AC_DEFUN([gl_FUNC_VFPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
# vfprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vfprintf_posix=yes
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
# vfprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vfprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vsnprintf-posix.m4
|
||||
# serial 23
|
||||
# serial 24
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -73,29 +75,37 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_snprintf_truncation_c99" in
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_snprintf_retval_c99" in
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
case m4_ifdef([gl_PRINTF_SUPPORT_N_DIRECTIVE],["$gl_cv_func_snprintf_directive_n"],["yes"]) in
|
||||
case "$gl_cv_func_snprintf_truncation_c99" in
|
||||
*yes)
|
||||
case "$gl_cv_func_snprintf_size1" in
|
||||
case "$gl_cv_func_snprintf_retval_c99" in
|
||||
*yes)
|
||||
case "$gl_cv_func_vsnprintf_zerosize_c99" in
|
||||
case m4_ifdef([gl_PRINTF_SUPPORT_N_DIRECTIVE],["$gl_cv_func_snprintf_directive_n"],["yes"]) in
|
||||
*yes)
|
||||
# vsnprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vsnprintf_posix=yes
|
||||
case "$gl_cv_func_snprintf_size1" in
|
||||
*yes)
|
||||
case "$gl_cv_func_vsnprintf_zerosize_c99" in
|
||||
*yes)
|
||||
# vsnprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vsnprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# vsprintf-posix.m4
|
||||
# serial 19
|
||||
# serial 20
|
||||
dnl Copyright (C) 2007-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,
|
||||
@@ -33,6 +33,8 @@ AC_DEFUN([gl_FUNC_VSPRINTF_IS_POSIX],
|
||||
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LC])
|
||||
AC_REQUIRE([gl_PRINTF_POSITIONS])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ZERO])
|
||||
AC_REQUIRE([gl_PRINTF_FLAG_ALT_PRECISION_ZERO])
|
||||
@@ -65,19 +67,27 @@ AC_DEFUN([gl_FUNC_VSPRINTF_IS_POSIX],
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_grouping" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
case "$gl_cv_func_printf_flag_grouping_int_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
case "$gl_cv_func_printf_flag_grouping_multibyte" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
case "$gl_cv_func_printf_flag_leftadjust" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
case "$gl_cv_func_printf_flag_zero" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
case "$gl_cv_func_printf_flag_alt_precision_zero" in
|
||||
*yes)
|
||||
# vsprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vsprintf_posix=yes
|
||||
case "$gl_cv_func_printf_precision" in
|
||||
*yes)
|
||||
case "$gl_cv_func_printf_enomem" in
|
||||
*yes)
|
||||
# vsprintf exists and is
|
||||
# already POSIX compliant.
|
||||
gl_cv_func_vsprintf_posix=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@@ -16,6 +16,7 @@ float-h
|
||||
nan
|
||||
snan
|
||||
setlocale
|
||||
localeconv
|
||||
|
||||
configure.ac:
|
||||
AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
|
||||
|
||||
@@ -17,6 +17,7 @@ float-h
|
||||
nan
|
||||
snan
|
||||
setlocale
|
||||
localeconv
|
||||
wcscmp
|
||||
wcsspn
|
||||
wmemcmp
|
||||
|
||||
@@ -59,5 +59,375 @@ main (int argc, char *argv[])
|
||||
free (result);
|
||||
}
|
||||
|
||||
/* Test that a locale dependent grouping separator is used correctly. */
|
||||
{
|
||||
const char *separator =
|
||||
localeconv ()->thousands_sep; /* = nl_langinfo (THOUSEP) */
|
||||
size_t separator_len = strlen (separator);
|
||||
|
||||
/* Tests of %d directive with grouping separator. */
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'d", 1000);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 4 + separator_len);
|
||||
ASSERT (memcmp (result, "1", 1) == 0
|
||||
&& memcmp (result + 1, separator, separator_len) == 0
|
||||
&& strcmp (result + 1 + separator_len, "000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'d", -1000);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 5 + separator_len);
|
||||
ASSERT (memcmp (result, "-1", 2) == 0
|
||||
&& memcmp (result + 2, separator, separator_len) == 0
|
||||
&& strcmp (result + 2 + separator_len, "000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'d", -142857);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 7 + separator_len);
|
||||
ASSERT (memcmp (result, "-142", 4) == 0
|
||||
&& memcmp (result + 4, separator, separator_len) == 0
|
||||
&& strcmp (result + 4 + separator_len, "857") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'d", 2147483647);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 10 + 3 * separator_len);
|
||||
ASSERT (memcmp (result, "2", 1) == 0
|
||||
&& memcmp (result + 1, separator, separator_len) == 0
|
||||
&& memcmp (result + 1 + separator_len, "147", 3) == 0
|
||||
&& memcmp (result + 4 + separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 4 + 2 * separator_len, "483", 3) == 0
|
||||
&& memcmp (result + 7 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 7 + 3 * separator_len, "647") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'d", -2147483647);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 11 + 3 * separator_len);
|
||||
ASSERT (memcmp (result, "-2", 2) == 0
|
||||
&& memcmp (result + 2, separator, separator_len) == 0
|
||||
&& memcmp (result + 2 + separator_len, "147", 3) == 0
|
||||
&& memcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 5 + 2 * separator_len, "483", 3) == 0
|
||||
&& memcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 8 + 3 * separator_len, "647") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'.10d", 1000);
|
||||
ASSERT (result != NULL);
|
||||
if (length == 10 + separator_len)
|
||||
{
|
||||
/* Most implementations don't add the grouping character within the
|
||||
leading zeroes. */
|
||||
ASSERT (length == 10 + separator_len);
|
||||
ASSERT (memcmp (result, "0000001", 7) == 0
|
||||
&& memcmp (result + 7, separator, separator_len) == 0
|
||||
&& strcmp (result + 7 + separator_len, "000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* But there are good arguments for adding the grouping character
|
||||
within the leading zeroes.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=23432> */
|
||||
ASSERT (length == 10 + 3 * separator_len);
|
||||
ASSERT (memcmp (result, "0", 1) == 0
|
||||
&& memcmp (result + 1, separator, separator_len) == 0
|
||||
&& memcmp (result + 1 + separator_len, "000", 3) == 0
|
||||
&& memcmp (result + 4 + separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 4 + 2 * separator_len, "001", 3) == 0
|
||||
&& memcmp (result + 7 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 7 + 3 * separator_len, "000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'.10d", -1000);
|
||||
ASSERT (result != NULL);
|
||||
if (length == 11 + separator_len)
|
||||
{
|
||||
/* Most implementations don't add the grouping character within the
|
||||
leading zeroes. */
|
||||
ASSERT (length == 11 + separator_len);
|
||||
ASSERT (memcmp (result, "-0000001", 8) == 0
|
||||
&& memcmp (result + 8, separator, separator_len) == 0
|
||||
&& strcmp (result + 8 + separator_len, "000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* But there are good arguments for adding the grouping character
|
||||
within the leading zeroes.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=23432> */
|
||||
ASSERT (length == 11 + 3 * separator_len);
|
||||
ASSERT (memcmp (result, "-0", 2) == 0
|
||||
&& memcmp (result + 2, separator, separator_len) == 0
|
||||
&& memcmp (result + 2 + separator_len, "000", 3) == 0
|
||||
&& memcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 5 + 2 * separator_len, "001", 3) == 0
|
||||
&& memcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 8 + 3 * separator_len, "000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'10d", 1000);
|
||||
ASSERT (result != NULL);
|
||||
if (separator_len > 0)
|
||||
{
|
||||
if (length == 10)
|
||||
{
|
||||
/* Result according to POSIX, which says that the width is
|
||||
measured in "bytes".
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/functions/fprintf.html>
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap05.html#tag_05> */
|
||||
ASSERT (length == 10);
|
||||
ASSERT (memcmp (result, " 1" + separator_len, 7 - separator_len) == 0
|
||||
&& memcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 7, "000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Result according to glibc, which measures the width in
|
||||
multibyte characters or column positions.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=28943>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=30883>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=31542> */
|
||||
ASSERT (length == 9 + separator_len);
|
||||
ASSERT (memcmp (result, " 1", 6) == 0
|
||||
&& memcmp (result + 6, separator, separator_len) == 0
|
||||
&& strcmp (result + 6 + separator_len, "000") == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (length == 10);
|
||||
ASSERT (strcmp (result, " 1000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'10d", -1000);
|
||||
ASSERT (result != NULL);
|
||||
if (separator_len > 0)
|
||||
{
|
||||
if (length == 10)
|
||||
{
|
||||
/* Result according to POSIX, which says that the width is
|
||||
measured in "bytes".
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/functions/fprintf.html>
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap05.html#tag_05> */
|
||||
ASSERT (length == 10);
|
||||
ASSERT (memcmp (result, " -1" + separator_len, 7 - separator_len) == 0
|
||||
&& memcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 7, "000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Result according to glibc, which measures the width in
|
||||
multibyte characters or column positions.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=28943>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=30883>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=31542> */
|
||||
ASSERT (length == 9 + separator_len);
|
||||
ASSERT (memcmp (result, " -1", 6) == 0
|
||||
&& memcmp (result + 6, separator, separator_len) == 0
|
||||
&& strcmp (result + 6 + separator_len, "000") == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (length == 10);
|
||||
ASSERT (strcmp (result, " -1000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
|
||||
/* Tests of %f directive with grouping separator. */
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'.0f", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 4 + separator_len);
|
||||
ASSERT (memcmp (result, "1", 1) == 0
|
||||
&& memcmp (result + 1, separator, separator_len) == 0
|
||||
&& strcmp (result + 1 + separator_len, "000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'.5f", 3141592653.5897932386);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 16 + 3 * separator_len);
|
||||
ASSERT (memcmp (result, "3", 1) == 0
|
||||
&& memcmp (result + 1, separator, separator_len) == 0
|
||||
&& memcmp (result + 1 + separator_len, "141", 3) == 0
|
||||
&& memcmp (result + 4 + separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 4 + 2 * separator_len, "592", 3) == 0
|
||||
&& memcmp (result + 7 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 7 + 3 * separator_len, "653,58979") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'.5f", -3141592653.5897932386);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 17 + 3 * separator_len);
|
||||
ASSERT (memcmp (result, "-3", 2) == 0
|
||||
&& memcmp (result + 2, separator, separator_len) == 0
|
||||
&& memcmp (result + 2 + separator_len, "141", 3) == 0
|
||||
&& memcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 5 + 2 * separator_len, "592", 3) == 0
|
||||
&& memcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 8 + 3 * separator_len, "653,58979") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'010.0f", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
if (separator_len > 0)
|
||||
{
|
||||
if (length == 10)
|
||||
{
|
||||
/* Result according to POSIX, which says that the width is
|
||||
measured in "bytes".
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/functions/fprintf.html>
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap05.html#tag_05> */
|
||||
ASSERT (length == 10);
|
||||
ASSERT (memcmp (result, "0000001" + separator_len, 7 - separator_len) == 0
|
||||
&& memcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 7, "000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Result according to glibc, which measures the width in
|
||||
multibyte characters or column positions.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=28943>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=30883>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=31542> */
|
||||
ASSERT (length == 9 + separator_len);
|
||||
ASSERT (memcmp (result, "000001", 6) == 0
|
||||
&& memcmp (result + 6, separator, separator_len) == 0
|
||||
&& strcmp (result + 6 + separator_len, "000") == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (length == 10);
|
||||
ASSERT (strcmp (result, "0000001000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
|
||||
/* Tests of %g directive with grouping separator. */
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'g", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 4 + separator_len);
|
||||
ASSERT (memcmp (result, "1", 1) == 0
|
||||
&& memcmp (result + 1, separator, separator_len) == 0
|
||||
&& strcmp (result + 1 + separator_len, "000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'g", -142857.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 7 + separator_len);
|
||||
ASSERT (memcmp (result, "-142", 4) == 0
|
||||
&& memcmp (result + 4, separator, separator_len) == 0
|
||||
&& strcmp (result + 4 + separator_len, "857") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'.5g", 3141592653.5897932386);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 10);
|
||||
ASSERT (strcmp (result, "3,1416e+09") == 0);
|
||||
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);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result =
|
||||
asnprintf (NULL, &length, "%'.50g",
|
||||
42351647362715016953416125033982098102569580078125.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 50 + 16 * separator_len);
|
||||
ASSERT (memcmp (result, "42", 2) == 0
|
||||
&& memcmp (result + 2, separator, separator_len) == 0
|
||||
&& memcmp (result + 2 + separator_len, "351", 3) == 0
|
||||
&& memcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 5 + 2 * separator_len, "647", 3) == 0
|
||||
&& memcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 8 + 3 * separator_len, "362", 3) == 0
|
||||
&& memcmp (result + 11 + 3 * separator_len, separator, separator_len) == 0
|
||||
&& memcmp (result + 11 + 4 * separator_len, "715", 3) == 0
|
||||
&& memcmp (result + 14 + 4 * separator_len, separator, separator_len) == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
char *result = asnprintf (NULL, &length, "%'010g", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
if (separator_len > 0)
|
||||
{
|
||||
if (length == 10)
|
||||
{
|
||||
/* Result according to POSIX, which says that the width is
|
||||
measured in "bytes".
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/functions/fprintf.html>
|
||||
<https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap05.html#tag_05> */
|
||||
ASSERT (length == 10);
|
||||
ASSERT (memcmp (result, "0000001" + separator_len, 7 - separator_len) == 0
|
||||
&& memcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& strcmp (result + 7, "000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Result according to glibc, which measures the width in
|
||||
multibyte characters or column positions.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=28943>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=30883>
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=31542> */
|
||||
ASSERT (length == 9 + separator_len);
|
||||
ASSERT (memcmp (result, "000001", 6) == 0
|
||||
&& memcmp (result + 6, separator, separator_len) == 0
|
||||
&& strcmp (result + 6 + separator_len, "000") == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (length == 10);
|
||||
ASSERT (strcmp (result, "0000001000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
}
|
||||
|
||||
return test_exit_status;
|
||||
}
|
||||
|
||||
@@ -3,19 +3,13 @@
|
||||
# Test whether a french locale is installed.
|
||||
: "${LOCALE_FR=fr_FR}"
|
||||
: "${LOCALE_FR_UTF8=fr_FR.UTF-8}"
|
||||
if test $LOCALE_FR != none; then
|
||||
testlocale=$LOCALE_FR
|
||||
else
|
||||
if test $LOCALE_FR_UTF8 != none; then
|
||||
testlocale=$LOCALE_FR_UTF8
|
||||
if test $LOCALE_FR = none && test $LOCALE_FR_UTF8 = none; then
|
||||
if test -f /usr/bin/localedef; then
|
||||
echo "Skipping test: no french locale is installed"
|
||||
else
|
||||
if test -f /usr/bin/localedef; then
|
||||
echo "Skipping test: no french locale is installed"
|
||||
else
|
||||
echo "Skipping test: no french locale is supported"
|
||||
fi
|
||||
exit 77
|
||||
echo "Skipping test: no french locale is supported"
|
||||
fi
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if $LC_NUMERIC_IMPLEMENTED; then
|
||||
@@ -25,5 +19,11 @@ else
|
||||
exit 77
|
||||
fi
|
||||
|
||||
LC_ALL=$testlocale \
|
||||
${CHECKER} ./test-vasnprintf-posix2${EXEEXT}
|
||||
if test $LOCALE_FR != none; then
|
||||
LC_ALL=$LOCALE_FR ${CHECKER} ./test-vasnprintf-posix2${EXEEXT} || exit 1
|
||||
fi
|
||||
if test $LOCALE_FR_UTF8 != none; then
|
||||
LC_ALL=$LOCALE_FR_UTF8 ${CHECKER} ./test-vasnprintf-posix2${EXEEXT} || exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#if __GLIBC__ >= 2 || defined __CYGWIN__
|
||||
# include <langinfo.h>
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
@@ -60,5 +64,276 @@ main (int argc, char *argv[])
|
||||
free (result);
|
||||
}
|
||||
|
||||
/* Test that a locale dependent grouping separator is used correctly. */
|
||||
{
|
||||
wchar_t separator[10];
|
||||
#if __GLIBC__ >= 2 || defined __CYGWIN__
|
||||
/* On glibc, in the unibyte locale fr_FR, the *wprintf routines use U+202F
|
||||
as separator, which cannot be represented in the locale encoding. */
|
||||
separator[0] = (wchar_t) (uintptr_t) nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC);
|
||||
separator[1] = L'\0';
|
||||
#else
|
||||
const char *separator_mb =
|
||||
localeconv ()->thousands_sep; /* = nl_langinfo (THOUSEP) */
|
||||
mbstowcs (separator, separator_mb, SIZEOF (separator));
|
||||
#endif
|
||||
size_t separator_len = wcslen (separator);
|
||||
|
||||
/* Tests of %d directive with grouping separator. */
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'d", 1000);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 4 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"1", 1) == 0
|
||||
&& wmemcmp (result + 1, separator, separator_len) == 0
|
||||
&& wcscmp (result + 1 + separator_len, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'d", -1000);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 5 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"-1", 2) == 0
|
||||
&& wmemcmp (result + 2, separator, separator_len) == 0
|
||||
&& wcscmp (result + 2 + separator_len, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'d", -142857);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 7 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"-142", 4) == 0
|
||||
&& wmemcmp (result + 4, separator, separator_len) == 0
|
||||
&& wcscmp (result + 4 + separator_len, L"857") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'d", 2147483647);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 10 + 3 * separator_len);
|
||||
ASSERT (wmemcmp (result, L"2", 1) == 0
|
||||
&& wmemcmp (result + 1, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 1 + separator_len, L"147", 3) == 0
|
||||
&& wmemcmp (result + 4 + separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 4 + 2 * separator_len, L"483", 3) == 0
|
||||
&& wmemcmp (result + 7 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7 + 3 * separator_len, L"647") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'d", -2147483647);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 11 + 3 * separator_len);
|
||||
ASSERT (wmemcmp (result, L"-2", 2) == 0
|
||||
&& wmemcmp (result + 2, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 2 + separator_len, L"147", 3) == 0
|
||||
&& wmemcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 5 + 2 * separator_len, L"483", 3) == 0
|
||||
&& wmemcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 8 + 3 * separator_len, L"647") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'.10d", 1000);
|
||||
ASSERT (result != NULL);
|
||||
if (length == 10 + separator_len)
|
||||
{
|
||||
/* Most implementations don't add the grouping character within the
|
||||
leading zeroes. */
|
||||
ASSERT (length == 10 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"0000001", 7) == 0
|
||||
&& wmemcmp (result + 7, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7 + separator_len, L"000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* But there are good arguments for adding the grouping character
|
||||
within the leading zeroes too.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=23432> */
|
||||
ASSERT (length == 10 + 3 * separator_len);
|
||||
ASSERT (wmemcmp (result, L"0", 1) == 0
|
||||
&& wmemcmp (result + 1, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 1 + separator_len, L"000", 3) == 0
|
||||
&& wmemcmp (result + 4 + separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 4 + 2 * separator_len, L"001", 3) == 0
|
||||
&& wmemcmp (result + 7 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7 + 3 * separator_len, L"000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'.10d", -1000);
|
||||
ASSERT (result != NULL);
|
||||
if (length == 11 + separator_len)
|
||||
{
|
||||
/* Most implementations don't add the grouping character within the
|
||||
leading zeroes. */
|
||||
ASSERT (length == 11 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"-0000001", 8) == 0
|
||||
&& wmemcmp (result + 8, separator, separator_len) == 0
|
||||
&& wcscmp (result + 8 + separator_len, L"000") == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* But there are good arguments for adding the grouping character
|
||||
within the leading zeroes too.
|
||||
<https://sourceware.org/bugzilla/show_bug.cgi?id=23432> */
|
||||
ASSERT (length == 11 + 3 * separator_len);
|
||||
ASSERT (wmemcmp (result, L"-0", 2) == 0
|
||||
&& wmemcmp (result + 2, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 2 + separator_len, L"000", 3) == 0
|
||||
&& wmemcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 5 + 2 * separator_len, L"001", 3) == 0
|
||||
&& wmemcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 8 + 3 * separator_len, L"000") == 0);
|
||||
}
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'10d", 1000);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 10);
|
||||
ASSERT (wmemcmp (result, L" 1" + separator_len, 7 - separator_len) == 0
|
||||
&& wmemcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'10d", -1000);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 10);
|
||||
ASSERT (wmemcmp (result, L" -1" + separator_len, 7 - separator_len) == 0
|
||||
&& wmemcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
|
||||
/* Tests of %f directive with grouping separator. */
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'.0f", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 4 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"1", 1) == 0
|
||||
&& wmemcmp (result + 1, separator, separator_len) == 0
|
||||
&& wcscmp (result + 1 + separator_len, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'.5f", 3141592653.5897932386);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 16 + 3 * separator_len);
|
||||
ASSERT (wmemcmp (result, L"3", 1) == 0
|
||||
&& wmemcmp (result + 1, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 1 + separator_len, L"141", 3) == 0
|
||||
&& wmemcmp (result + 4 + separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 4 + 2 * separator_len, L"592", 3) == 0
|
||||
&& wmemcmp (result + 7 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7 + 3 * separator_len, L"653,58979") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'.5f", -3141592653.5897932386);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 17 + 3 * separator_len);
|
||||
ASSERT (wmemcmp (result, L"-3", 2) == 0
|
||||
&& wmemcmp (result + 2, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 2 + separator_len, L"141", 3) == 0
|
||||
&& wmemcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 5 + 2 * separator_len, L"592", 3) == 0
|
||||
&& wmemcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 8 + 3 * separator_len, L"653,58979") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'010.0f", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 10);
|
||||
ASSERT (wmemcmp (result, L"0000001" + separator_len, 7 - separator_len) == 0
|
||||
&& wmemcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
|
||||
/* Tests of %g directive with grouping separator. */
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'g", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 4 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"1", 1) == 0
|
||||
&& wmemcmp (result + 1, separator, separator_len) == 0
|
||||
&& wcscmp (result + 1 + separator_len, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'g", -142857.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 7 + separator_len);
|
||||
ASSERT (wmemcmp (result, L"-142", 4) == 0
|
||||
&& wmemcmp (result + 4, separator, separator_len) == 0
|
||||
&& wcscmp (result + 4 + separator_len, L"857") == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
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);
|
||||
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);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result =
|
||||
asnwprintf (NULL, &length, L"%'.50g",
|
||||
42351647362715016953416125033982098102569580078125.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 50 + 16 * separator_len);
|
||||
ASSERT (wmemcmp (result, L"42", 2) == 0
|
||||
&& wmemcmp (result + 2, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 2 + separator_len, L"351", 3) == 0
|
||||
&& wmemcmp (result + 5 + separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 5 + 2 * separator_len, L"647", 3) == 0
|
||||
&& wmemcmp (result + 8 + 2 * separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 8 + 3 * separator_len, L"362", 3) == 0
|
||||
&& wmemcmp (result + 11 + 3 * separator_len, separator, separator_len) == 0
|
||||
&& wmemcmp (result + 11 + 4 * separator_len, L"715", 3) == 0
|
||||
&& wmemcmp (result + 14 + 4 * separator_len, separator, separator_len) == 0);
|
||||
free (result);
|
||||
}
|
||||
{
|
||||
size_t length;
|
||||
wchar_t *result = asnwprintf (NULL, &length, L"%'010g", 1000.0);
|
||||
ASSERT (result != NULL);
|
||||
ASSERT (length == 10);
|
||||
ASSERT (wmemcmp (result, L"0000001" + separator_len, 7 - separator_len) == 0
|
||||
&& wmemcmp (result + 7 - separator_len, separator, separator_len) == 0
|
||||
&& wcscmp (result + 7, L"000") == 0);
|
||||
free (result);
|
||||
}
|
||||
}
|
||||
|
||||
return test_exit_status;
|
||||
}
|
||||
|
||||
@@ -3,19 +3,13 @@
|
||||
# Test whether a french locale is installed.
|
||||
: "${LOCALE_FR=fr_FR}"
|
||||
: "${LOCALE_FR_UTF8=fr_FR.UTF-8}"
|
||||
if test $LOCALE_FR != none; then
|
||||
testlocale=$LOCALE_FR
|
||||
else
|
||||
if test $LOCALE_FR_UTF8 != none; then
|
||||
testlocale=$LOCALE_FR_UTF8
|
||||
if test $LOCALE_FR = none && test $LOCALE_FR_UTF8 = none; then
|
||||
if test -f /usr/bin/localedef; then
|
||||
echo "Skipping test: no french locale is installed"
|
||||
else
|
||||
if test -f /usr/bin/localedef; then
|
||||
echo "Skipping test: no french locale is installed"
|
||||
else
|
||||
echo "Skipping test: no french locale is supported"
|
||||
fi
|
||||
exit 77
|
||||
echo "Skipping test: no french locale is supported"
|
||||
fi
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if $LC_NUMERIC_IMPLEMENTED; then
|
||||
@@ -25,5 +19,11 @@ else
|
||||
exit 77
|
||||
fi
|
||||
|
||||
LC_ALL=$testlocale \
|
||||
${CHECKER} ./test-vasnwprintf-posix2${EXEEXT}
|
||||
if test $LOCALE_FR != none; then
|
||||
LC_ALL=$LOCALE_FR ${CHECKER} ./test-vasnwprintf-posix2${EXEEXT} || exit 1
|
||||
fi
|
||||
if test $LOCALE_FR_UTF8 != none; then
|
||||
LC_ALL=$LOCALE_FR_UTF8 ${CHECKER} ./test-vasnwprintf-posix2${EXEEXT} || exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user