* *printf-posix: ISO C 23: Add %b directive for binary output of integers
@ 2023-03-17 21:51 Bruno Haible
2023-03-18 11:50 ` Pádraig Brady
2023-03-22 21:13 ` *printf-posix: ISO C 23: Add %b directive for binary output of integers Bruno Haible
0 siblings, 2 replies; 9+ messages in thread
From: Bruno Haible @ 2023-03-17 21:51 UTC (permalink / raw)
To: bug-gnulib
[-- Attachment #1: Type: text/plain, Size: 3151 bytes --]
This set of patches adds support for the %b format string directive, required
by ISO C 23, to the *printf family of functions.
So far, only glibc implements it (since version 2.35). For portability to the
other platforms, use the *printf-posix modules.
2023-03-17 Bruno Haible <bruno@clisp.org>
*printf-posix: ISO C 23: Add %b directive for binary output of integers.
* lib/printf-parse.c (PRINTF_PARSE): Recognize the 'b' directive.
* lib/printf-parse.h: Update comment.
* lib/wprintf-parse.h: Likewise.
* lib/vasnprintf.c (MAX_ROOM_NEEDED, VASNPRINTF): Add support for the
'b' directive.
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_B): New macro.
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_B): New macro.
(gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it.
* m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_POSIX): Invoke
gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_POSIX): Require
gl_PRINTF_DIRECTIVE_B and test its result. Invoke
gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Likewise.
* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX): Likewise.
* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise.
* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise.
* m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise.
* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise.
* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_POSIX): Likewise.
* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise.
* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise.
* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise.
* tests/test-snprintf-posix.h (test_function): Add some tests of the %b
directive.
* tests/test-sprintf-posix.h (test_function): Likewise.
* tests/test-vasnprintf-posix.c (test_function): Likewise.
* tests/test-vasnwprintf-posix.c (test_function): Likewise.
* tests/test-vasprintf-posix.c (test_function): Likewise.
* doc/glibc-functions/asprintf.texi: Mention the 'b' directive.
* doc/glibc-functions/obstack_printf.texi: Likewise.
* doc/glibc-functions/obstack_vprintf.texi: Likewise.
* doc/glibc-functions/vasprintf.texi: Likewise.
* doc/posix-functions/dprintf.texi: Likewise.
* doc/posix-functions/fprintf.texi: Likewise.
* doc/posix-functions/fwprintf.texi: Likewise.
* doc/posix-functions/printf.texi: Likewise.
* doc/posix-functions/snprintf.texi: Likewise.
* doc/posix-functions/sprintf.texi: Likewise.
* doc/posix-functions/swprintf.texi: Likewise.
* doc/posix-functions/vdprintf.texi: Likewise.
* doc/posix-functions/vfprintf.texi: Likewise.
* doc/posix-functions/vfwprintf.texi: Likewise.
* doc/posix-functions/vprintf.texi: Likewise.
* doc/posix-functions/vsnprintf.texi: Likewise.
* doc/posix-functions/vsprintf.texi: Likewise.
* doc/posix-functions/vswprintf.texi: Likewise.
* doc/posix-functions/vwprintf.texi: Likewise.
* doc/posix-functions/wprintf.texi: Likewise.
2023-03-17 Bruno Haible <bruno@clisp.org>
vasnprintf, vasnwprintf: Simplify code.
* lib/vasnprintf.c (MAX_ROOM_NEEDED): Remove dead code: The directives
'o', 'x', 'X' always take an unsigned integer argument.
[-- Attachment #2: 0001-vasnprintf-vasnwprintf-Simplify-code.patch --]
[-- Type: text/x-patch, Size: 2849 bytes --]
From 21ed6e8365e371b9088df727d0449133df58e9bc Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 17 Mar 2023 22:33:24 +0100
Subject: [PATCH 1/2] vasnprintf, vasnwprintf: Simplify code.
* lib/vasnprintf.c (MAX_ROOM_NEEDED): Remove dead code: The directives
'o', 'x', 'X' always take an unsigned integer argument.
---
ChangeLog | 6 ++++++
lib/vasnprintf.c | 10 +++++-----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8318d7f6fc..62dd39e17f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2023-03-17 Bruno Haible <bruno@clisp.org>
+
+ vasnprintf, vasnwprintf: Simplify code.
+ * lib/vasnprintf.c (MAX_ROOM_NEEDED): Remove dead code: The directives
+ 'o', 'x', 'X' always take an unsigned integer argument.
+
2023-03-17 Bruno Haible <bruno@clisp.org>
vasnwprintf: Fix test failure on OpenBSD.
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 74a6712926..a49eb1dcd7 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -1654,13 +1654,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
break;
case 'o':
- if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+ if (type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
- else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+ else if (type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.333334 /* binary -> octal */
@@ -1679,13 +1679,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
break;
case 'x': case 'X':
- if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+ if (type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
- else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+ else if (type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
@@ -1699,7 +1699,7 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
+ 1; /* turn floor into ceil */
if (tmp_length < precision)
tmp_length = precision;
- /* Add 2, to account for a leading sign or alternate form. */
+ /* Add 2, to account for a prefix from the alternate form. */
tmp_length = xsum (tmp_length, 2);
break;
--
2.34.1
[-- Attachment #3: 0002-printf-posix-ISO-C-23-Add-b-directive-for-binary-out.patch --]
[-- Type: text/x-patch, Size: 118401 bytes --]
From bb7cf2b64d2caf381249dda65ee0fe6766d9b3c6 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 17 Mar 2023 22:45:56 +0100
Subject: [PATCH 2/2] *printf-posix: ISO C 23: Add %b directive for binary
output of integers.
* lib/printf-parse.c (PRINTF_PARSE): Recognize the 'b' directive.
* lib/printf-parse.h: Update comment.
* lib/wprintf-parse.h: Likewise.
* lib/vasnprintf.c (MAX_ROOM_NEEDED, VASNPRINTF): Add support for the
'b' directive.
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_B): New macro.
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_B): New macro.
(gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it.
* m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_POSIX): Invoke
gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_POSIX): Require
gl_PRINTF_DIRECTIVE_B and test its result. Invoke
gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Likewise.
* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX): Likewise.
* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise.
* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise.
* m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise.
* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise.
* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_POSIX): Likewise.
* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise.
* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise.
* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise.
* tests/test-snprintf-posix.h (test_function): Add some tests of the %b
directive.
* tests/test-sprintf-posix.h (test_function): Likewise.
* tests/test-vasnprintf-posix.c (test_function): Likewise.
* tests/test-vasnwprintf-posix.c (test_function): Likewise.
* tests/test-vasprintf-posix.c (test_function): Likewise.
* doc/glibc-functions/asprintf.texi: Mention the 'b' directive.
* doc/glibc-functions/obstack_printf.texi: Likewise.
* doc/glibc-functions/obstack_vprintf.texi: Likewise.
* doc/glibc-functions/vasprintf.texi: Likewise.
* doc/posix-functions/dprintf.texi: Likewise.
* doc/posix-functions/fprintf.texi: Likewise.
* doc/posix-functions/fwprintf.texi: Likewise.
* doc/posix-functions/printf.texi: Likewise.
* doc/posix-functions/snprintf.texi: Likewise.
* doc/posix-functions/sprintf.texi: Likewise.
* doc/posix-functions/swprintf.texi: Likewise.
* doc/posix-functions/vdprintf.texi: Likewise.
* doc/posix-functions/vfprintf.texi: Likewise.
* doc/posix-functions/vfwprintf.texi: Likewise.
* doc/posix-functions/vprintf.texi: Likewise.
* doc/posix-functions/vsnprintf.texi: Likewise.
* doc/posix-functions/vsprintf.texi: Likewise.
* doc/posix-functions/vswprintf.texi: Likewise.
* doc/posix-functions/vwprintf.texi: Likewise.
* doc/posix-functions/wprintf.texi: Likewise.
---
ChangeLog | 53 ++++++
doc/glibc-functions/asprintf.texi | 5 +
doc/glibc-functions/obstack_printf.texi | 5 +
doc/glibc-functions/obstack_vprintf.texi | 5 +
doc/glibc-functions/vasprintf.texi | 5 +
doc/posix-functions/dprintf.texi | 5 +
doc/posix-functions/fprintf.texi | 5 +
doc/posix-functions/fwprintf.texi | 13 +-
doc/posix-functions/printf.texi | 5 +
doc/posix-functions/snprintf.texi | 5 +
doc/posix-functions/sprintf.texi | 5 +
doc/posix-functions/swprintf.texi | 13 +-
doc/posix-functions/vdprintf.texi | 5 +
doc/posix-functions/vfprintf.texi | 5 +
doc/posix-functions/vfwprintf.texi | 13 +-
doc/posix-functions/vprintf.texi | 5 +
doc/posix-functions/vsnprintf.texi | 5 +
doc/posix-functions/vsprintf.texi | 5 +
doc/posix-functions/vswprintf.texi | 13 +-
doc/posix-functions/vwprintf.texi | 13 +-
doc/posix-functions/wprintf.texi | 13 +-
lib/printf-parse.c | 2 +-
lib/printf-parse.h | 2 +-
lib/vasnprintf.c | 213 +++++++++++++++++++++++
lib/wprintf-parse.h | 2 +-
m4/dprintf-posix.m4 | 32 ++--
m4/fprintf-posix.m4 | 32 ++--
m4/obstack-printf-posix.m4 | 32 ++--
m4/printf.m4 | 186 ++++++++++++--------
m4/snprintf-posix.m4 | 42 +++--
m4/sprintf-posix.m4 | 32 ++--
m4/vasnprintf-posix.m4 | 36 ++--
m4/vasnprintf.m4 | 18 +-
m4/vasnwprintf-posix.m4 | 3 +-
m4/vasprintf-posix.m4 | 36 ++--
m4/vdprintf-posix.m4 | 32 ++--
m4/vfprintf-posix.m4 | 32 ++--
m4/vsnprintf-posix.m4 | 42 +++--
m4/vsprintf-posix.m4 | 32 ++--
tests/test-snprintf-posix.h | 68 ++++++++
tests/test-sprintf-posix.h | 68 ++++++++
tests/test-vasnprintf-posix.c | 93 ++++++++++
tests/test-vasnwprintf-posix.c | 93 ++++++++++
tests/test-vasprintf-posix.c | 93 ++++++++++
44 files changed, 1166 insertions(+), 256 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 62dd39e17f..173cd45bff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2023-03-17 Bruno Haible <bruno@clisp.org>
+
+ *printf-posix: ISO C 23: Add %b directive for binary output of integers.
+ * lib/printf-parse.c (PRINTF_PARSE): Recognize the 'b' directive.
+ * lib/printf-parse.h: Update comment.
+ * lib/wprintf-parse.h: Likewise.
+ * lib/vasnprintf.c (MAX_ROOM_NEEDED, VASNPRINTF): Add support for the
+ 'b' directive.
+ * m4/printf.m4 (gl_PRINTF_DIRECTIVE_B): New macro.
+ * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_B): New macro.
+ (gl_PREREQ_VASNPRINTF_WITH_EXTRAS): Invoke it.
+ * m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_POSIX): Invoke
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
+ * m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_POSIX): Require
+ gl_PRINTF_DIRECTIVE_B and test its result. Invoke
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B.
+ * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_POSIX): Likewise.
+ * m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX): Likewise.
+ * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Likewise.
+ * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_POSIX): Likewise.
+ * m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_POSIX): Likewise.
+ * m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_POSIX): Likewise.
+ * m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_POSIX): Likewise.
+ * m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_POSIX): Likewise.
+ * m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise.
+ * m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_POSIX): Likewise.
+ * tests/test-snprintf-posix.h (test_function): Add some tests of the %b
+ directive.
+ * tests/test-sprintf-posix.h (test_function): Likewise.
+ * tests/test-vasnprintf-posix.c (test_function): Likewise.
+ * tests/test-vasnwprintf-posix.c (test_function): Likewise.
+ * tests/test-vasprintf-posix.c (test_function): Likewise.
+ * doc/glibc-functions/asprintf.texi: Mention the 'b' directive.
+ * doc/glibc-functions/obstack_printf.texi: Likewise.
+ * doc/glibc-functions/obstack_vprintf.texi: Likewise.
+ * doc/glibc-functions/vasprintf.texi: Likewise.
+ * doc/posix-functions/dprintf.texi: Likewise.
+ * doc/posix-functions/fprintf.texi: Likewise.
+ * doc/posix-functions/fwprintf.texi: Likewise.
+ * doc/posix-functions/printf.texi: Likewise.
+ * doc/posix-functions/snprintf.texi: Likewise.
+ * doc/posix-functions/sprintf.texi: Likewise.
+ * doc/posix-functions/swprintf.texi: Likewise.
+ * doc/posix-functions/vdprintf.texi: Likewise.
+ * doc/posix-functions/vfprintf.texi: Likewise.
+ * doc/posix-functions/vfwprintf.texi: Likewise.
+ * doc/posix-functions/vprintf.texi: Likewise.
+ * doc/posix-functions/vsnprintf.texi: Likewise.
+ * doc/posix-functions/vsprintf.texi: Likewise.
+ * doc/posix-functions/vswprintf.texi: Likewise.
+ * doc/posix-functions/vwprintf.texi: Likewise.
+ * doc/posix-functions/wprintf.texi: Likewise.
+
2023-03-17 Bruno Haible <bruno@clisp.org>
vasnprintf, vasnwprintf: Simplify code.
diff --git a/doc/glibc-functions/asprintf.texi b/doc/glibc-functions/asprintf.texi
index 93d092d795..47708c40fb 100644
--- a/doc/glibc-functions/asprintf.texi
+++ b/doc/glibc-functions/asprintf.texi
@@ -41,6 +41,11 @@
platforms:
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, Solaris 11.4, Cygwin 1.5.x.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, Solaris 11.4, Cygwin 2.9.0.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, Cygwin 1.5.x.
@item
diff --git a/doc/glibc-functions/obstack_printf.texi b/doc/glibc-functions/obstack_printf.texi
index b417486e7f..7feae78b36 100644
--- a/doc/glibc-functions/obstack_printf.texi
+++ b/doc/glibc-functions/obstack_printf.texi
@@ -39,6 +39,11 @@
glibc-2.3.6, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/glibc-functions/obstack_vprintf.texi b/doc/glibc-functions/obstack_vprintf.texi
index a4d6242704..cdded10221 100644
--- a/doc/glibc-functions/obstack_vprintf.texi
+++ b/doc/glibc-functions/obstack_vprintf.texi
@@ -39,6 +39,11 @@
glibc-2.3.6, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/glibc-functions/vasprintf.texi b/doc/glibc-functions/vasprintf.texi
index 2ba5405558..2f69df8e78 100644
--- a/doc/glibc-functions/vasprintf.texi
+++ b/doc/glibc-functions/vasprintf.texi
@@ -41,6 +41,11 @@
platforms:
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, Solaris 11.4, Cygwin 1.5.x.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, Solaris 11.4, Cygwin 2.9.0.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, Cygwin 1.5.x.
@item
diff --git a/doc/posix-functions/dprintf.texi b/doc/posix-functions/dprintf.texi
index 51428d036f..7d5aeb9051 100644
--- a/doc/posix-functions/dprintf.texi
+++ b/doc/posix-functions/dprintf.texi
@@ -24,6 +24,11 @@
platforms:
glibc-2.3.6, Solaris 11.4.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, Solaris 11.4, Cygwin 2.9.0.
+@item
This function does not support the @samp{n} directive on some platforms:
glibc when used with @code{_FORTIFY_SOURCE >= 2} (set by default on Ubuntu),
macOS 11.1.
diff --git a/doc/posix-functions/fprintf.texi b/doc/posix-functions/fprintf.texi
index 18c4e0549d..eedd9babbf 100644
--- a/doc/posix-functions/fprintf.texi
+++ b/doc/posix-functions/fprintf.texi
@@ -25,6 +25,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/fwprintf.texi b/doc/posix-functions/fwprintf.texi
index 1bd4f3d4b8..b9ce2eb024 100644
--- a/doc/posix-functions/fwprintf.texi
+++ b/doc/posix-functions/fwprintf.texi
@@ -13,16 +13,21 @@
Portability problems not fixed by Gnulib:
@itemize
@item
-The @code{%m} directive is not portable, use @code{%s} mapped to an
-argument of @code{strerror(errno)} (or a version of @code{strerror_r})
-instead.
-@item
This function is missing on some platforms:
NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11.00, IRIX 6.5, Cygwin 1.5.x.
@item
On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and therefore cannot
accommodate all Unicode characters.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
+The @code{%m} directive is not portable, use @code{%s} mapped to an
+argument of @code{strerror(errno)} (or a version of @code{strerror_r})
+instead.
+@item
When formatting an integer with grouping flag, this function inserts thousands
separators even in the "C" locale on some platforms:
NetBSD 5.1.
diff --git a/doc/posix-functions/printf.texi b/doc/posix-functions/printf.texi
index 6fab46033e..c32881c2cc 100644
--- a/doc/posix-functions/printf.texi
+++ b/doc/posix-functions/printf.texi
@@ -25,6 +25,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/snprintf.texi b/doc/posix-functions/snprintf.texi
index 13d63acac7..6d8453b9fe 100644
--- a/doc/posix-functions/snprintf.texi
+++ b/doc/posix-functions/snprintf.texi
@@ -40,6 +40,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/sprintf.texi b/doc/posix-functions/sprintf.texi
index 0ced69dc57..8974498ebf 100644
--- a/doc/posix-functions/sprintf.texi
+++ b/doc/posix-functions/sprintf.texi
@@ -25,6 +25,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/swprintf.texi b/doc/posix-functions/swprintf.texi
index a076eb32cf..906ee521aa 100644
--- a/doc/posix-functions/swprintf.texi
+++ b/doc/posix-functions/swprintf.texi
@@ -13,10 +13,6 @@
Portability problems not fixed by Gnulib:
@itemize
@item
-The @code{%m} directive is not portable, use @code{%s} mapped to an
-argument of @code{strerror(errno)} (or a version of @code{strerror_r})
-instead.
-@item
This function is missing on some platforms:
NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11.00, IRIX 6.5, Cygwin 1.5.x.
@item
@@ -35,6 +31,15 @@
@item
On Windows, this function does not take a buffer size as second argument.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
+The @code{%m} directive is not portable, use @code{%s} mapped to an
+argument of @code{strerror(errno)} (or a version of @code{strerror_r})
+instead.
+@item
When formatting an integer with grouping flag, this function inserts thousands
separators even in the "C" locale on some platforms:
NetBSD 5.1.
diff --git a/doc/posix-functions/vdprintf.texi b/doc/posix-functions/vdprintf.texi
index ca84b011bb..d4de64ee25 100644
--- a/doc/posix-functions/vdprintf.texi
+++ b/doc/posix-functions/vdprintf.texi
@@ -24,6 +24,11 @@
platforms:
glibc-2.3.6, Solaris 11.4.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, Solaris 11.4, Cygwin 2.9.0.
+@item
This function does not support the @samp{n} directive on some platforms:
glibc when used with @code{_FORTIFY_SOURCE >= 2} (set by default on Ubuntu),
macOS 11.1.
diff --git a/doc/posix-functions/vfprintf.texi b/doc/posix-functions/vfprintf.texi
index 8441649d03..f3ec56b5a6 100644
--- a/doc/posix-functions/vfprintf.texi
+++ b/doc/posix-functions/vfprintf.texi
@@ -25,6 +25,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/vfwprintf.texi b/doc/posix-functions/vfwprintf.texi
index 56cd3851f8..f6e136b0b1 100644
--- a/doc/posix-functions/vfwprintf.texi
+++ b/doc/posix-functions/vfwprintf.texi
@@ -13,16 +13,21 @@
Portability problems not fixed by Gnulib:
@itemize
@item
-The @code{%m} directive is not portable, use @code{%s} mapped to an
-argument of @code{strerror(errno)} (or a version of @code{strerror_r})
-instead.
-@item
This function is missing on some platforms:
NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11.00, IRIX 6.5, Cygwin 1.5.x.
@item
On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and therefore cannot
accommodate all Unicode characters.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
+The @code{%m} directive is not portable, use @code{%s} mapped to an
+argument of @code{strerror(errno)} (or a version of @code{strerror_r})
+instead.
+@item
When formatting an integer with grouping flag, this function inserts thousands
separators even in the "C" locale on some platforms:
NetBSD 5.1.
diff --git a/doc/posix-functions/vprintf.texi b/doc/posix-functions/vprintf.texi
index a43942fbd2..6e05d41002 100644
--- a/doc/posix-functions/vprintf.texi
+++ b/doc/posix-functions/vprintf.texi
@@ -25,6 +25,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/vsnprintf.texi b/doc/posix-functions/vsnprintf.texi
index 2f3406ec4c..660ccfb1c3 100644
--- a/doc/posix-functions/vsnprintf.texi
+++ b/doc/posix-functions/vsnprintf.texi
@@ -37,6 +37,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/vsprintf.texi b/doc/posix-functions/vsprintf.texi
index 0ddcdfca12..8af4bdf279 100644
--- a/doc/posix-functions/vsprintf.texi
+++ b/doc/posix-functions/vsprintf.texi
@@ -25,6 +25,11 @@
glibc-2.3.6, Mac OS X 10.5, NetBSD 9.0, OpenBSD 4.0, AIX 5.2, HP-UX 11,
IRIX 6.5, Solaris 11.4, Cygwin 1.5.x, mingw, MSVC 14.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
This function does not support the @samp{F} directive on some platforms:
NetBSD 3.0, AIX 5.1, HP-UX 11.23, IRIX 6.5, Solaris 9,
Cygwin 1.5.x, mingw, MSVC 14.
diff --git a/doc/posix-functions/vswprintf.texi b/doc/posix-functions/vswprintf.texi
index 2f771216ab..62a644fb6d 100644
--- a/doc/posix-functions/vswprintf.texi
+++ b/doc/posix-functions/vswprintf.texi
@@ -13,10 +13,6 @@
Portability problems not fixed by Gnulib:
@itemize
@item
-The @code{%m} directive is not portable, use @code{%s} mapped to an
-argument of @code{strerror(errno)} (or a version of @code{strerror_r})
-instead.
-@item
This function is missing on some platforms:
NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11.00, IRIX 6.5, Cygwin 1.5.x.
@item
@@ -25,6 +21,15 @@
@item
On Windows, this function does not take a buffer size as second argument.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
+The @code{%m} directive is not portable, use @code{%s} mapped to an
+argument of @code{strerror(errno)} (or a version of @code{strerror_r})
+instead.
+@item
When formatting an integer with grouping flag, this function inserts thousands
separators even in the "C" locale on some platforms:
NetBSD 5.1.
diff --git a/doc/posix-functions/vwprintf.texi b/doc/posix-functions/vwprintf.texi
index f2d839bdbc..80c8646663 100644
--- a/doc/posix-functions/vwprintf.texi
+++ b/doc/posix-functions/vwprintf.texi
@@ -13,10 +13,6 @@
Portability problems not fixed by Gnulib:
@itemize
@item
-The @code{%m} directive is not portable, use @code{%s} mapped to an
-argument of @code{strerror(errno)} (or a version of @code{strerror_r})
-instead.
-@item
This function is missing on some platforms:
NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11.00, IRIX 6.5, Cygwin 1.7.
@item
@@ -26,6 +22,15 @@
On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and therefore cannot
accommodate all Unicode characters.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
+The @code{%m} directive is not portable, use @code{%s} mapped to an
+argument of @code{strerror(errno)} (or a version of @code{strerror_r})
+instead.
+@item
When formatting an integer with grouping flag, this function inserts thousands
separators even in the "C" locale on some platforms:
NetBSD 5.1.
diff --git a/doc/posix-functions/wprintf.texi b/doc/posix-functions/wprintf.texi
index 48ac729e01..1c3b99b281 100644
--- a/doc/posix-functions/wprintf.texi
+++ b/doc/posix-functions/wprintf.texi
@@ -13,10 +13,6 @@
Portability problems not fixed by Gnulib:
@itemize
@item
-The @code{%m} directive is not portable, use @code{%s} mapped to an
-argument of @code{strerror(errno)} (or a version of @code{strerror_r})
-instead.
-@item
This function is missing on some platforms:
NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11.00, IRIX 6.5.
@item
@@ -26,6 +22,15 @@
On Windows and 32-bit AIX platforms, @code{wchar_t} is a 16-bit type and therefore cannot
accommodate all Unicode characters.
@item
+This function does not support the @samp{b} directive, required by ISO C23,
+on some platforms:
+glibc 2.34, musl libc, macOS 12.5, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2,
+AIX 7.2, HP-UX 11, Solaris 11.4, Cygwin 2.9.0, mingw, MSVC 14.
+@item
+The @code{%m} directive is not portable, use @code{%s} mapped to an
+argument of @code{strerror(errno)} (or a version of @code{strerror_r})
+instead.
+@item
When formatting an integer with grouping flag, this function inserts thousands
separators even in the "C" locale on some platforms:
NetBSD 5.1.
diff --git a/lib/printf-parse.c b/lib/printf-parse.c
index 3040749abd..6273dd773f 100644
--- a/lib/printf-parse.c
+++ b/lib/printf-parse.c
@@ -453,7 +453,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
else
type = TYPE_INT;
break;
- case 'o': case 'u': case 'x': case 'X':
+ case 'b': case 'o': case 'u': case 'x': case 'X':
/* If 'unsigned long long' is larger than 'unsigned long': */
if (flags >= 16 || (flags & 4))
type = TYPE_ULONGLONGINT;
diff --git a/lib/printf-parse.h b/lib/printf-parse.h
index 1f86e32c99..fcb3cc462e 100644
--- a/lib/printf-parse.h
+++ b/lib/printf-parse.h
@@ -61,7 +61,7 @@ typedef struct
const char* precision_start;
const char* precision_end;
size_t precision_arg_index;
- char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
+ char conversion; /* d i b o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
char_directive;
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index a49eb1dcd7..c2f10cb0c4 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -1653,6 +1653,25 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
tmp_length = xsum (tmp_length, 1);
break;
+ case 'b':
+ if (type == TYPE_ULONGLONGINT)
+ tmp_length =
+ (unsigned int) (sizeof (unsigned long long) * CHAR_BIT)
+ + 1; /* turn floor into ceil */
+ else if (type == TYPE_ULONGINT)
+ tmp_length =
+ (unsigned int) (sizeof (unsigned long) * CHAR_BIT)
+ + 1; /* turn floor into ceil */
+ else
+ tmp_length =
+ (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
+ + 1; /* turn floor into ceil */
+ if (tmp_length < precision)
+ tmp_length = precision;
+ /* Add 2, to account for a prefix from the alternate form. */
+ tmp_length = xsum (tmp_length, 2);
+ break;
+
case 'o':
if (type == TYPE_ULONGLONGINT)
tmp_length =
@@ -3043,6 +3062,199 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#endif
+#if NEED_PRINTF_DIRECTIVE_B
+ else if (dp->conversion == 'b')
+ {
+ arg_type type = a.arg[dp->arg_index].type;
+ int flags = dp->flags;
+ size_t width;
+ int has_precision;
+ size_t precision;
+ size_t tmp_length;
+ size_t count;
+ DCHAR_T tmpbuf[700];
+ DCHAR_T *tmp;
+ DCHAR_T *tmp_end;
+ DCHAR_T *tmp_start;
+ DCHAR_T *pad_ptr;
+ DCHAR_T *p;
+
+ width = 0;
+ if (dp->width_start != dp->width_end)
+ {
+ if (dp->width_arg_index != ARG_NONE)
+ {
+ int arg;
+
+ if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+ abort ();
+ arg = a.arg[dp->width_arg_index].a.a_int;
+ width = arg;
+ if (arg < 0)
+ {
+ /* "A negative field width is taken as a '-' flag
+ followed by a positive field width." */
+ flags |= FLAG_LEFT;
+ width = -width;
+ }
+ }
+ else
+ {
+ const FCHAR_T *digitp = dp->width_start;
+
+ do
+ width = xsum (xtimes (width, 10), *digitp++ - '0');
+ while (digitp != dp->width_end);
+ }
+ }
+
+ has_precision = 0;
+ precision = 0;
+ if (dp->precision_start != dp->precision_end)
+ {
+ if (dp->precision_arg_index != ARG_NONE)
+ {
+ int arg;
+
+ if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+ abort ();
+ arg = a.arg[dp->precision_arg_index].a.a_int;
+ /* "A negative precision is taken as if the precision
+ were omitted." */
+ if (arg >= 0)
+ {
+ precision = arg;
+ has_precision = 1;
+ }
+ }
+ else
+ {
+ const FCHAR_T *digitp = dp->precision_start + 1;
+
+ precision = 0;
+ while (digitp != dp->precision_end)
+ precision = xsum (xtimes (precision, 10), *digitp++ - '0');
+ has_precision = 1;
+ }
+ }
+
+ /* Allocate a temporary buffer of sufficient size. */
+ if (type == TYPE_ULONGLONGINT)
+ tmp_length =
+ (unsigned int) (sizeof (unsigned long long) * CHAR_BIT)
+ + 1; /* turn floor into ceil */
+ else if (type == TYPE_ULONGINT)
+ tmp_length =
+ (unsigned int) (sizeof (unsigned long) * CHAR_BIT)
+ + 1; /* turn floor into ceil */
+ else
+ tmp_length =
+ (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
+ + 1; /* turn floor into ceil */
+ if (tmp_length < precision)
+ tmp_length = precision;
+ /* Add 2, to account for a prefix from the alternate form. */
+ tmp_length = xsum (tmp_length, 2);
+
+ if (tmp_length < width)
+ tmp_length = width;
+
+ if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
+ tmp = tmpbuf;
+ else
+ {
+ size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
+
+ if (size_overflow_p (tmp_memsize))
+ /* Overflow, would lead to out of memory. */
+ goto out_of_memory;
+ tmp = (DCHAR_T *) malloc (tmp_memsize);
+ if (tmp == NULL)
+ /* Out of memory. */
+ goto out_of_memory;
+ }
+
+ tmp_end = tmp + tmp_length;
+
+ unsigned long long arg =
+ (type == TYPE_ULONGLONGINT ? a.arg[dp->arg_index].a.a_ulonglongint :
+ type == TYPE_ULONGINT ? a.arg[dp->arg_index].a.a_ulongint :
+ a.arg[dp->arg_index].a.a_uint);
+ int need_prefix = ((flags & FLAG_ALT) && arg != 0);
+
+ p = tmp_end;
+ do
+ {
+ *--p = '0' + (arg & 1);
+ arg = arg >> 1;
+ }
+ while (arg != 0);
+
+ pad_ptr = p;
+
+ if (need_prefix)
+ {
+ *--p = 'b'; *--p = '0';
+ }
+ tmp_start = p;
+
+ /* The generated string now extends from tmp_start to tmp_end,
+ with the zero padding insertion point being at pad_ptr,
+ tmp_start <= pad_ptr <= tmp_end. */
+ count = tmp_end - tmp_start;
+
+ if (count < width)
+ {
+ size_t pad = width - count;
+
+ if (flags & FLAG_LEFT)
+ {
+ /* Pad with spaces on the right. */
+ for (p = tmp_start; p < tmp_end; p++)
+ *(p - pad) = *p;
+ for (p = tmp_end - pad; p < tmp_end; p++)
+ *p = ' ';
+ }
+ else if (flags & FLAG_ZERO)
+ {
+ /* Pad with zeroes. */
+ for (p = tmp_start; p < pad_ptr; p++)
+ *(p - pad) = *p;
+ for (p = pad_ptr - pad; p < pad_ptr; p++)
+ *p = '0';
+ }
+ else
+ {
+ /* Pad with spaces on the left. */
+ for (p = tmp_start - pad; p < tmp_start; p++)
+ *p = ' ';
+ }
+
+ tmp_start = tmp_start - pad;
+ }
+
+ count = tmp_end - tmp_start;
+
+ if (count > tmp_length)
+ /* tmp_length was incorrectly calculated - fix the
+ code above! */
+ abort ();
+
+ /* Make room for the result. */
+ if (count >= allocated - length)
+ {
+ size_t n = xsum (length, count);
+
+ ENSURE_ALLOCATION (n);
+ }
+
+ /* Append the result. */
+ memcpy (result + length, tmp_start, count * sizeof (DCHAR_T));
+ if (tmp != tmpbuf)
+ free (tmp);
+ length += count;
+ }
+#endif
#if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE
else if ((dp->conversion == 'a' || dp->conversion == 'A')
# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
@@ -4826,6 +5038,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
switch (dp->conversion)
{
case 'd': case 'i': case 'u':
+ case 'b':
case 'o':
case 'x': case 'X': case 'p':
prec_ourselves = has_precision && (precision > 0);
diff --git a/lib/wprintf-parse.h b/lib/wprintf-parse.h
index 05799b8f15..86bdec9a21 100644
--- a/lib/wprintf-parse.h
+++ b/lib/wprintf-parse.h
@@ -55,7 +55,7 @@ typedef struct
const wchar_t* precision_start;
const wchar_t* precision_end;
size_t precision_arg_index;
- wchar_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
+ wchar_t conversion; /* d i b o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
wchar_t_directive;
diff --git a/m4/dprintf-posix.m4 b/m4/dprintf-posix.m4
index a25ef4164e..4186ab70fe 100644
--- a/m4/dprintf-posix.m4
+++ b/m4/dprintf-posix.m4
@@ -1,4 +1,4 @@
-# dprintf-posix.m4 serial 3
+# dprintf-posix.m4 serial 4
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_DPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -33,27 +34,31 @@ AC_DEFUN([gl_FUNC_DPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- # dprintf exists and is
- # already POSIX compliant.
- gl_cv_func_dprintf_posix=yes
+ case "$gl_cv_func_printf_enomem" in
+ *yes)
+ # dprintf exists and is
+ # already POSIX compliant.
+ gl_cv_func_dprintf_posix=yes
+ ;;
+ esac
;;
esac
;;
@@ -88,6 +93,7 @@ AC_DEFUN([gl_FUNC_DPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/fprintf-posix.m4 b/m4/fprintf-posix.m4
index 3a51bcf4e1..5602000e4a 100644
--- a/m4/fprintf-posix.m4
+++ b/m4/fprintf-posix.m4
@@ -1,4 +1,4 @@
-# fprintf-posix.m4 serial 14
+# fprintf-posix.m4 serial 15
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -31,27 +32,31 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- # fprintf exists and is
- # already POSIX compliant.
- gl_cv_func_fprintf_posix=yes
+ case "$gl_cv_func_printf_enomem" in
+ *yes)
+ # fprintf exists and is
+ # already POSIX compliant.
+ gl_cv_func_fprintf_posix=yes
+ ;;
+ esac
;;
esac
;;
@@ -85,6 +90,7 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/obstack-printf-posix.m4 b/m4/obstack-printf-posix.m4
index 10f744c575..633b017442 100644
--- a/m4/obstack-printf-posix.m4
+++ b/m4/obstack-printf-posix.m4
@@ -1,4 +1,4 @@
-# obstack-printf-posix.m4 serial 4
+# obstack-printf-posix.m4 serial 5
dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -14,6 +14,7 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -36,27 +37,31 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- # obstack_printf exists and is
- # already POSIX compliant.
- gl_cv_func_obstack_printf_posix=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
;;
@@ -91,6 +96,7 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/printf.m4 b/m4/printf.m4
index de98a870e9..719679c362 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 74
+# printf.m4 serial 75
dnl Copyright (C) 2003, 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -603,6 +603,50 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_A]
])
])
+dnl Test whether the *printf family of functions supports the 'b' conversion
+dnl specifier for binary output of integers.
+dnl (ISO C23)
+dnl Result is gl_cv_func_printf_directive_b.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_B],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether printf supports the 'b' directive],
+ [gl_cv_func_printf_directive_b],
+ [
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+ int result = 0;
+ if (sprintf (buf, "%b %d", 12345, 33, 44, 55) < 0
+ || strcmp (buf, "11000000111001 33") != 0)
+ result |= 1;
+ return result;
+}]])],
+ [gl_cv_func_printf_directive_b=yes],
+ [gl_cv_func_printf_directive_b=no],
+ [
+ case "$host_os" in
+ # Guess no on glibc systems.
+ *-gnu* | gnu*) gl_cv_func_printf_directive_b="guessing no";;
+ # Guess no on musl systems.
+ *-musl* | midipix*) gl_cv_func_printf_directive_b="guessing no";;
+ # Guess no on Android.
+ linux*-android*) gl_cv_func_printf_directive_b="guessing no";;
+ # Guess no on native Windows.
+ mingw*) gl_cv_func_printf_directive_b="guessing no";;
+ # If we don't know, obey --enable-cross-guesses.
+ *) gl_cv_func_printf_directive_b="$gl_cross_guess_normal";;
+ esac
+ ])
+ ])
+])
+
dnl Test whether the *printf family of functions supports the %F format
dnl directive. (ISO C99, POSIX:2001)
dnl Result is gl_cv_func_printf_directive_f.
@@ -1648,81 +1692,83 @@ AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99]
dnl 3 = gl_PRINTF_INFINITE
dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
dnl 5 = gl_PRINTF_DIRECTIVE_A
-dnl 6 = gl_PRINTF_DIRECTIVE_F
-dnl 7 = gl_PRINTF_DIRECTIVE_N
-dnl 8 = gl_PRINTF_DIRECTIVE_LS
-dnl 9 = gl_PRINTF_POSITIONS
-dnl 10 = gl_PRINTF_FLAG_GROUPING
-dnl 11 = gl_PRINTF_FLAG_LEFTADJUST
-dnl 12 = gl_PRINTF_FLAG_ZERO
-dnl 13 = gl_PRINTF_PRECISION
-dnl 14 = gl_PRINTF_ENOMEM
-dnl 15 = gl_SNPRINTF_PRESENCE
-dnl 16 = gl_SNPRINTF_TRUNCATION_C99
-dnl 17 = gl_SNPRINTF_RETVAL_C99
-dnl 18 = gl_SNPRINTF_DIRECTIVE_N
-dnl 19 = gl_SNPRINTF_SIZE1
-dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99
+dnl 6 = gl_PRINTF_DIRECTIVE_B
+dnl 7 = gl_PRINTF_DIRECTIVE_F
+dnl 8 = gl_PRINTF_DIRECTIVE_N
+dnl 9 = gl_PRINTF_DIRECTIVE_LS
+dnl 10 = gl_PRINTF_POSITIONS
+dnl 11 = gl_PRINTF_FLAG_GROUPING
+dnl 12 = gl_PRINTF_FLAG_LEFTADJUST
+dnl 13 = gl_PRINTF_FLAG_ZERO
+dnl 14 = gl_PRINTF_PRECISION
+dnl 15 = gl_PRINTF_ENOMEM
+dnl 16 = gl_SNPRINTF_PRESENCE
+dnl 17 = gl_SNPRINTF_TRUNCATION_C99
+dnl 18 = gl_SNPRINTF_RETVAL_C99
+dnl 19 = gl_SNPRINTF_DIRECTIVE_N
+dnl 20 = gl_SNPRINTF_SIZE1
+dnl 21 = gl_VSNPRINTF_ZEROSIZE_C99
dnl
dnl 1 = checking whether printf supports size specifiers as in C99...
dnl 2 = checking whether printf supports 'long double' arguments...
dnl 3 = checking whether printf supports infinite 'double' arguments...
dnl 4 = checking whether printf supports infinite 'long double' arguments...
dnl 5 = checking whether printf supports the 'a' and 'A' directives...
-dnl 6 = checking whether printf supports the 'F' directive...
-dnl 7 = checking whether printf supports the 'n' directive...
-dnl 8 = checking whether printf supports the 'ls' directive...
-dnl 9 = checking whether printf supports POSIX/XSI format strings with positions...
-dnl 10 = checking whether printf supports the grouping flag...
-dnl 11 = checking whether printf supports the left-adjust flag correctly...
-dnl 12 = checking whether printf supports the zero flag correctly...
-dnl 13 = checking whether printf supports large precisions...
-dnl 14 = checking whether printf survives out-of-memory conditions...
-dnl 15 = checking for snprintf...
-dnl 16 = checking whether snprintf truncates the result as in C99...
-dnl 17 = checking whether snprintf returns a byte count as in C99...
-dnl 18 = checking whether snprintf fully supports the 'n' directive...
-dnl 19 = checking whether snprintf respects a size of 1...
-dnl 20 = checking whether vsnprintf respects a zero size as in C99...
+dnl 6 = checking whether printf supports the 'b' directive...
+dnl 7 = checking whether printf supports the 'F' directive...
+dnl 8 = checking whether printf supports the 'n' directive...
+dnl 9 = checking whether printf supports the 'ls' directive...
+dnl 10 = checking whether printf supports POSIX/XSI format strings with positions...
+dnl 11 = checking whether printf supports the grouping flag...
+dnl 12 = checking whether printf supports the left-adjust flag correctly...
+dnl 13 = checking whether printf supports the zero flag correctly...
+dnl 14 = checking whether printf supports large precisions...
+dnl 15 = checking whether printf survives out-of-memory conditions...
+dnl 16 = checking for snprintf...
+dnl 17 = checking whether snprintf truncates the result as in C99...
+dnl 18 = checking whether snprintf returns a byte count as in C99...
+dnl 19 = checking whether snprintf fully supports the 'n' directive...
+dnl 20 = checking whether snprintf respects a size of 1...
+dnl 21 = checking whether vsnprintf respects a zero size as in C99...
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
-dnl glibc 2.5 . . . . . . . . . . . . . . . . . . . .
-dnl glibc 2.3.6 . . . . # . . . . . . . . . . . . . . .
-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
+dnl glibc 2.5 . . . . . # . . . . . . . . . . . . . . .
+dnl glibc 2.3.6 . . . . # # . . . . . . . . . . . . . . .
+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 # # # # # # # . . # # . # # ? . # # # . .
diff --git a/m4/snprintf-posix.m4 b/m4/snprintf-posix.m4
index 61a80a8aa8..033e1916e5 100644
--- a/m4/snprintf-posix.m4
+++ b/m4/snprintf-posix.m4
@@ -1,4 +1,4 @@
-# snprintf-posix.m4 serial 14
+# snprintf-posix.m4 serial 15
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -38,37 +39,41 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- case "$gl_cv_func_snprintf_truncation_c99" in
+ case "$gl_cv_func_printf_enomem" in
*yes)
- case "$gl_cv_func_snprintf_retval_c99" in
+ case "$gl_cv_func_snprintf_truncation_c99" in
*yes)
- case "$gl_cv_func_snprintf_directive_n" in
+ case "$gl_cv_func_snprintf_retval_c99" in
*yes)
- case "$gl_cv_func_snprintf_size1" in
+ case "$gl_cv_func_snprintf_directive_n" in
*yes)
- case "$gl_cv_func_vsnprintf_zerosize_c99" in
+ case "$gl_cv_func_snprintf_size1" in
*yes)
- # snprintf exists and is
- # already POSIX compliant.
- gl_cv_func_snprintf_posix=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
;;
@@ -113,6 +118,7 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/sprintf-posix.m4 b/m4/sprintf-posix.m4
index 9d9258e17a..cfcbe37cce 100644
--- a/m4/sprintf-posix.m4
+++ b/m4/sprintf-posix.m4
@@ -1,4 +1,4 @@
-# sprintf-posix.m4 serial 12
+# sprintf-posix.m4 serial 13
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -31,27 +32,31 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- # sprintf exists and is
- # already POSIX compliant.
- gl_cv_func_sprintf_posix=yes
+ case "$gl_cv_func_printf_enomem" in
+ *yes)
+ # sprintf exists and is
+ # already POSIX compliant.
+ gl_cv_func_sprintf_posix=yes
+ ;;
+ esac
;;
esac
;;
@@ -85,6 +90,7 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vasnprintf-posix.m4 b/m4/vasnprintf-posix.m4
index baf7cb437d..4983dfc50a 100644
--- a/m4/vasnprintf-posix.m4
+++ b/m4/vasnprintf-posix.m4
@@ -1,4 +1,4 @@
-# vasnprintf-posix.m4 serial 13
+# vasnprintf-posix.m4 serial 14
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -32,29 +33,33 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" 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_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
;;
@@ -88,6 +93,7 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4
index cf451f9b03..b868aed08b 100644
--- a/m4/vasnprintf.m4
+++ b/m4/vasnprintf.m4
@@ -1,4 +1,4 @@
-# vasnprintf.m4 serial 40
+# vasnprintf.m4 serial 41
dnl Copyright (C) 2002-2004, 2006-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -182,6 +182,21 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_A]
esac
])
+# Extra prerequisites of lib/vasnprintf.c for supporting the 'b' directive.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_B],
+[
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
+ case "$gl_cv_func_printf_directive_b" in
+ *yes)
+ ;;
+ *)
+ AC_DEFINE([NEED_PRINTF_DIRECTIVE_B], [1],
+ [Define if the vasnprintf implementation needs special code for
+ the 'b' directive.])
+ ;;
+ esac
+])
+
# Extra prerequisites of lib/vasnprintf.c for supporting the 'F' directive.
AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_F],
[
@@ -308,6 +323,7 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vasnwprintf-posix.m4 b/m4/vasnwprintf-posix.m4
index 9561bcf2b6..d9dc41fa97 100644
--- a/m4/vasnwprintf-posix.m4
+++ b/m4/vasnwprintf-posix.m4
@@ -1,4 +1,4 @@
-# vasnwprintf-posix.m4 serial 1
+# vasnwprintf-posix.m4 serial 2
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_VASNWPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vasprintf-posix.m4 b/m4/vasprintf-posix.m4
index 7c198a6410..1537ad52d9 100644
--- a/m4/vasprintf-posix.m4
+++ b/m4/vasprintf-posix.m4
@@ -1,4 +1,4 @@
-# vasprintf-posix.m4 serial 13
+# vasprintf-posix.m4 serial 14
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -32,29 +33,33 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" 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_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
;;
@@ -88,6 +93,7 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vdprintf-posix.m4 b/m4/vdprintf-posix.m4
index 47914cd177..eb9ab8c679 100644
--- a/m4/vdprintf-posix.m4
+++ b/m4/vdprintf-posix.m4
@@ -1,4 +1,4 @@
-# vdprintf-posix.m4 serial 3
+# vdprintf-posix.m4 serial 4
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_VDPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -33,27 +34,31 @@ AC_DEFUN([gl_FUNC_VDPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- # vdprintf exists and is
- # already POSIX compliant.
- gl_cv_func_vdprintf_posix=yes
+ case "$gl_cv_func_printf_enomem" in
+ *yes)
+ # vdprintf exists and is
+ # already POSIX compliant.
+ gl_cv_func_vdprintf_posix=yes
+ ;;
+ esac
;;
esac
;;
@@ -88,6 +93,7 @@ AC_DEFUN([gl_FUNC_VDPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vfprintf-posix.m4 b/m4/vfprintf-posix.m4
index ec68052214..17a8bad843 100644
--- a/m4/vfprintf-posix.m4
+++ b/m4/vfprintf-posix.m4
@@ -1,4 +1,4 @@
-# vfprintf-posix.m4 serial 14
+# vfprintf-posix.m4 serial 15
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -31,27 +32,31 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- # vfprintf exists and is
- # already POSIX compliant.
- gl_cv_func_vfprintf_posix=yes
+ case "$gl_cv_func_printf_enomem" in
+ *yes)
+ # vfprintf exists and is
+ # already POSIX compliant.
+ gl_cv_func_vfprintf_posix=yes
+ ;;
+ esac
;;
esac
;;
@@ -85,6 +90,7 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vsnprintf-posix.m4 b/m4/vsnprintf-posix.m4
index 5ea04a05e5..65805522d4 100644
--- a/m4/vsnprintf-posix.m4
+++ b/m4/vsnprintf-posix.m4
@@ -1,4 +1,4 @@
-# vsnprintf-posix.m4 serial 15
+# vsnprintf-posix.m4 serial 16
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -39,37 +40,41 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- case "$gl_cv_func_snprintf_truncation_c99" in
+ case "$gl_cv_func_printf_enomem" in
*yes)
- case "$gl_cv_func_snprintf_retval_c99" in
+ case "$gl_cv_func_snprintf_truncation_c99" in
*yes)
- case "$gl_cv_func_snprintf_directive_n" in
+ case "$gl_cv_func_snprintf_retval_c99" in
*yes)
- case "$gl_cv_func_snprintf_size1" in
+ case "$gl_cv_func_snprintf_directive_n" in
*yes)
- case "$gl_cv_func_vsnprintf_zerosize_c99" in
+ case "$gl_cv_func_snprintf_size1" in
*yes)
- # vsnprintf exists and is
- # already POSIX compliant.
- gl_cv_func_vsnprintf_posix=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
;;
@@ -114,6 +119,7 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/m4/vsprintf-posix.m4 b/m4/vsprintf-posix.m4
index 3ca0178ebd..716f58f761 100644
--- a/m4/vsprintf-posix.m4
+++ b/m4/vsprintf-posix.m4
@@ -1,4 +1,4 @@
-# vsprintf-posix.m4 serial 12
+# vsprintf-posix.m4 serial 13
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX]
AC_REQUIRE([gl_PRINTF_INFINITE])
AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_A])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_B])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_F])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_N])
AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS])
@@ -31,27 +32,31 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX]
*yes)
case "$gl_cv_func_printf_directive_a" in
*yes)
- case "$gl_cv_func_printf_directive_f" in
+ case "$gl_cv_func_printf_directive_b" in
*yes)
- case "$gl_cv_func_printf_directive_n" in
+ case "$gl_cv_func_printf_directive_f" in
*yes)
- case "$gl_cv_func_printf_directive_ls" in
+ case "$gl_cv_func_printf_directive_n" in
*yes)
- case "$gl_cv_func_printf_positions" in
+ case "$gl_cv_func_printf_directive_ls" in
*yes)
- case "$gl_cv_func_printf_flag_grouping" in
+ case "$gl_cv_func_printf_positions" in
*yes)
- case "$gl_cv_func_printf_flag_leftadjust" in
+ case "$gl_cv_func_printf_flag_grouping" in
*yes)
- case "$gl_cv_func_printf_flag_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_precision" in
*yes)
- # vsprintf exists and is
- # already POSIX compliant.
- gl_cv_func_vsprintf_posix=yes
+ case "$gl_cv_func_printf_enomem" in
+ *yes)
+ # vsprintf exists and is
+ # already POSIX compliant.
+ gl_cv_func_vsprintf_posix=yes
+ ;;
+ esac
;;
esac
;;
@@ -85,6 +90,7 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX]
gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
gl_PREREQ_VASNPRINTF_DIRECTIVE_A
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_B
gl_PREREQ_VASNPRINTF_DIRECTIVE_F
gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
gl_PREREQ_VASNPRINTF_FLAG_GROUPING
diff --git a/tests/test-snprintf-posix.h b/tests/test-snprintf-posix.h
index 4db76deb75..579d34583d 100644
--- a/tests/test-snprintf-posix.h
+++ b/tests/test-snprintf-posix.h
@@ -435,6 +435,8 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
{ /* Positive infinity. */
int retval =
my_snprintf (result, sizeof (result), "%La %d", Infinityl (), 33, 44, 55);
+ /* Note: This assertion fails under valgrind.
+ Reported at <https://bugs.kde.org/show_bug.cgi?id=424044>. */
ASSERT (strcmp (result, "inf 33") == 0);
ASSERT (retval == strlen (result));
}
@@ -3053,4 +3055,70 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
ASSERT (retval == strlen (result));
}
#endif
+
+ /* Test the support of the 'b' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%b %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A large positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%b %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width given as argument. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%*b %d", 20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ int retval =
+ my_snprintf (result, sizeof (result), "%*b %d", -20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%-20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with zero. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#b %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
}
diff --git a/tests/test-sprintf-posix.h b/tests/test-sprintf-posix.h
index 979254acc7..863d084b99 100644
--- a/tests/test-sprintf-posix.h
+++ b/tests/test-sprintf-posix.h
@@ -421,6 +421,8 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
{ /* Positive infinity. */
int retval =
my_sprintf (result, "%La %d", Infinityl (), 33, 44, 55);
+ /* Note: This assertion fails under valgrind.
+ Reported at <https://bugs.kde.org/show_bug.cgi?id=424044>. */
ASSERT (strcmp (result, "inf 33") == 0);
ASSERT (retval == strlen (result));
}
@@ -3035,4 +3037,70 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
ASSERT (retval == strlen (result));
}
#endif
+
+ /* Test the support of the 'b' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ int retval =
+ my_sprintf (result, "%b %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ int retval =
+ my_sprintf (result, "%b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A large positive number. */
+ int retval =
+ my_sprintf (result, "%b %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ int retval =
+ my_sprintf (result, "%20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width given as argument. */
+ int retval =
+ my_sprintf (result, "%*b %d", 20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ int retval =
+ my_sprintf (result, "%*b %d", -20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ int retval =
+ my_sprintf (result, "%-20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with zero. */
+ int retval =
+ my_sprintf (result, "%#b %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ int retval =
+ my_sprintf (result, "%#b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
}
diff --git a/tests/test-vasnprintf-posix.c b/tests/test-vasnprintf-posix.c
index 4a83f6d243..c6e1e2f650 100644
--- a/tests/test-vasnprintf-posix.c
+++ b/tests/test-vasnprintf-posix.c
@@ -562,6 +562,8 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
char *result =
my_asnprintf (NULL, &length, "%La %d", Infinityl (), 33, 44, 55);
ASSERT (result != NULL);
+ /* Note: This assertion fails under valgrind.
+ Reported at <https://bugs.kde.org/show_bug.cgi?id=424044>. */
ASSERT (strcmp (result, "inf 33") == 0);
ASSERT (length == strlen (result));
free (result);
@@ -3974,6 +3976,97 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
}
#endif
+ /* Test the support of the 'b' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%b %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%*b %d", 20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%*b %d", -20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#b %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
/* Test that the 'I' flag is supported. */
{
diff --git a/tests/test-vasnwprintf-posix.c b/tests/test-vasnwprintf-posix.c
index f686bfb9fe..c609a104ff 100644
--- a/tests/test-vasnwprintf-posix.c
+++ b/tests/test-vasnwprintf-posix.c
@@ -562,6 +562,8 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
wchar_t *result =
my_asnwprintf (NULL, &length, L"%La %d", Infinityl (), 33, 44, 55);
ASSERT (result != NULL);
+ /* Note: This assertion fails under valgrind.
+ Reported at <https://bugs.kde.org/show_bug.cgi?id=424044>. */
ASSERT (wcscmp (result, L"inf 33") == 0);
ASSERT (length == wcslen (result));
free (result);
@@ -3982,6 +3984,97 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
}
#endif
+ /* Test the support of the 'b' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%b %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11111111111111111111111111111110 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%*b %d", 20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%*b %d", -20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%-20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#b %d", 0, 33, 44, 55);
+ ASSERT (wcscmp (result, L"0 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#b %d", 12345, 33, 44, 55);
+ ASSERT (wcscmp (result, L"0b11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
/* Test that the 'I' flag is supported. */
{
diff --git a/tests/test-vasprintf-posix.c b/tests/test-vasprintf-posix.c
index 8563502c47..13b3a1bca9 100644
--- a/tests/test-vasprintf-posix.c
+++ b/tests/test-vasprintf-posix.c
@@ -543,6 +543,8 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
int retval =
my_asprintf (&result, "%La %d", Infinityl (), 33, 44, 55);
ASSERT (result != NULL);
+ /* Note: This assertion fails under valgrind.
+ Reported at <https://bugs.kde.org/show_bug.cgi?id=424044>. */
ASSERT (strcmp (result, "inf 33") == 0);
ASSERT (retval == strlen (result));
free (result);
@@ -3914,6 +3916,97 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
free (result);
}
#endif
+
+ /* Test the support of the 'b' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%b %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%*b %d", 20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%*b %d", -20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#b %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
}
static int
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: *printf-posix: ISO C 23: Add %b directive for binary output of integers
2023-03-17 21:51 *printf-posix: ISO C 23: Add %b directive for binary output of integers Bruno Haible
@ 2023-03-18 11:50 ` Pádraig Brady
2023-03-18 12:47 ` Eric Blake
2023-03-22 21:13 ` *printf-posix: ISO C 23: Add %b directive for binary output of integers Bruno Haible
1 sibling, 1 reply; 9+ messages in thread
From: Pádraig Brady @ 2023-03-18 11:50 UTC (permalink / raw)
To: Bruno Haible, bug-gnulib
On 17/03/2023 21:51, Bruno Haible wrote:
> This set of patches adds support for the %b format string directive, required
> by ISO C 23, to the *printf family of functions.
>
> So far, only glibc implements it (since version 2.35). For portability to the
> other platforms, use the *printf-posix modules.
For my reference mainly...
It's interesting that this conflicts with the POSIX specified %b directive
for the printf(1) utility.
cheers,
Pádraig
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: *printf-posix: ISO C 23: Add %b directive for binary output of integers
2023-03-18 11:50 ` Pádraig Brady
@ 2023-03-18 12:47 ` Eric Blake
2023-03-24 11:37 ` new modules *printf-gnu Bruno Haible
0 siblings, 1 reply; 9+ messages in thread
From: Eric Blake @ 2023-03-18 12:47 UTC (permalink / raw)
To: Pádraig Brady; +Cc: Bruno Haible, bug-gnulib
On Sat, Mar 18, 2023 at 11:50:47AM +0000, Pádraig Brady wrote:
> On 17/03/2023 21:51, Bruno Haible wrote:
> > This set of patches adds support for the %b format string directive, required
> > by ISO C 23, to the *printf family of functions.
> >
> > So far, only glibc implements it (since version 2.35). For portability to the
> > other platforms, use the *printf-posix modules.
>
> For my reference mainly...
>
> It's interesting that this conflicts with the POSIX specified %b directive
> for the printf(1) utility.
Another consideration: C23 admits that %#B is not available for
portable use of outputting uppercase '0B...', you would have to
manually write 0B%b instead. However, since glibc DOES support %B as
the uppercase counterpart to %b, should we add that in gnulib (but
this time under the auspices of *printf-gnu, rather than
*printf-posix)?
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: *printf-posix: ISO C 23: Add %b directive for binary output of integers
2023-03-17 21:51 *printf-posix: ISO C 23: Add %b directive for binary output of integers Bruno Haible
2023-03-18 11:50 ` Pádraig Brady
@ 2023-03-22 21:13 ` Bruno Haible
1 sibling, 0 replies; 9+ messages in thread
From: Bruno Haible @ 2023-03-22 21:13 UTC (permalink / raw)
To: bug-gnulib
Some details of the %b implementation that I added on 2023-03-17 were incorrect.
This patch fixes them, while adding new unit tests.
2023-03-22 Bruno Haible <bruno@clisp.org>
*printf-posix: Fix implementation of %b directive.
* lib/vasnprintf.c (VASNPRINTF): In the %b directive implementation, fix
the precision handling, and ignore the '0' flag when a width and a
precision are both present.
* tests/test-snprintf-posix.h (test_function): Add test cases for the %x
directive and more test cases for the %b directive.
* tests/test-sprintf-posix.h (test_function): Likewise.
* tests/test-vasnprintf-posix.c (test_function): Likewise.
* tests/test-vasnwprintf-posix.c (test_function): Likewise.
* tests/test-vasprintf-posix.c (test_function): Likewise.
* modules/vasnwprintf-posix-tests (Files): Add m4/musl.m4.
(configure.ac): Invoke gl_MUSL_LIBC.
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 5cd52b5b6e..248444ca23 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -3217,6 +3217,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
arg_type type = a.arg[dp->arg_index].type;
int flags = dp->flags;
+ int has_width;
size_t width;
int has_precision;
size_t precision;
@@ -3229,6 +3230,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
DCHAR_T *pad_ptr;
DCHAR_T *p;
+ has_width = 0;
width = 0;
if (dp->width_start != dp->width_end)
{
@@ -3256,10 +3258,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
width = xsum (xtimes (width, 10), *digitp++ - '0');
while (digitp != dp->width_end);
}
+ has_width = 1;
}
has_precision = 0;
- precision = 0;
+ precision = 1;
if (dp->precision_start != dp->precision_end)
{
if (dp->precision_arg_index != ARG_NONE)
@@ -3333,12 +3336,24 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
int need_prefix = ((flags & FLAG_ALT) && arg != 0);
p = tmp_end;
- do
+ /* "The result of converting a zero value with a precision
+ of zero is no characters." */
+ if (!(has_precision && precision == 0 && arg == 0))
+ {
+ do
+ {
+ *--p = '0' + (arg & 1);
+ arg = arg >> 1;
+ }
+ while (arg != 0);
+ }
+
+ if (has_precision)
{
- *--p = '0' + (arg & 1);
- arg = arg >> 1;
+ DCHAR_T *digits_start = tmp_end - precision;
+ while (p > digits_start)
+ *--p = '0';
}
- while (arg != 0);
pad_ptr = p;
@@ -3365,7 +3380,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
for (p = tmp_end - pad; p < tmp_end; p++)
*p = ' ';
}
- else if (flags & FLAG_ZERO)
+ else if ((flags & FLAG_ZERO)
+ /* Neither ISO C nor POSIX specify that the '0'
+ flag is ignored when a width and a precision
+ are both present. But most implementations
+ do so. */
+ && !(has_width && has_precision))
{
/* Pad with zeroes. */
for (p = tmp_start; p < pad_ptr; p++)
diff --git a/modules/vasnwprintf-posix-tests b/modules/vasnwprintf-posix-tests
index 667eb61103..6354e79f75 100644
--- a/modules/vasnwprintf-posix-tests
+++ b/modules/vasnwprintf-posix-tests
@@ -7,6 +7,7 @@ tests/minus-zero.h
tests/infinity.h
tests/nan.h
tests/macros.h
+m4/musl.m4
m4/locale-fr.m4
m4/codeset.m4
@@ -21,6 +22,7 @@ wmemcpy
configure.ac:
AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
+gl_MUSL_LIBC
gt_LOCALE_FR
gt_LOCALE_FR_UTF8
diff --git a/tests/test-snprintf-posix.h b/tests/test-snprintf-posix.h
index 05c7be8059..a8993f947a 100644
--- a/tests/test-snprintf-posix.h
+++ b/tests/test-snprintf-posix.h
@@ -3091,6 +3091,190 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
}
#endif
+ /* Test the support of the 'x' conversion specifier for hexadecimal output of
+ integers. */
+
+ { /* Zero. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%x %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A large positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (strcmp (result, "fffffffe 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width given as argument. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%*x %d", 10, 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ int retval =
+ my_snprintf (result, sizeof (result), "%*x %d", -10, 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a zero number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0x %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%15.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Padding and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%015.10x %d", 12348, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "00000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ #endif
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%-10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with zero. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#x %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0x303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0x0000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0x000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#15.10x %d", 12348, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ #endif
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.0x %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Uppercase 'X'. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%X %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303C 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#X %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0X303C 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.0X %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
/* Test the support of the 'b' conversion specifier for binary output of
integers. */
@@ -3136,6 +3320,45 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
ASSERT (retval == strlen (result));
}
+ { /* Precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a zero number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0b %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%25.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Padding and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%025.20b %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
{ /* FLAG_LEFT. */
int retval =
my_snprintf (result, sizeof (result), "%-20b %d", 12345, 33, 44, 55);
@@ -3156,4 +3379,51 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
ASSERT (strcmp (result, "0b11000000111001 33") == 0);
ASSERT (retval == strlen (result));
}
+
+ { /* FLAG_ALT with a positive number and width. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#25.20b %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.0b %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
}
diff --git a/tests/test-sprintf-posix.h b/tests/test-sprintf-posix.h
index d745a1109b..7f280d3c32 100644
--- a/tests/test-sprintf-posix.h
+++ b/tests/test-sprintf-posix.h
@@ -3069,6 +3069,190 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
}
#endif
+ /* Test the support of the 'x' conversion specifier for hexadecimal output of
+ integers. */
+
+ { /* Zero. */
+ int retval =
+ my_sprintf (result, "%x %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ int retval =
+ my_sprintf (result, "%x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A large positive number. */
+ int retval =
+ my_sprintf (result, "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (strcmp (result, "fffffffe 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ int retval =
+ my_sprintf (result, "%10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width given as argument. */
+ int retval =
+ my_sprintf (result, "%*x %d", 10, 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ int retval =
+ my_sprintf (result, "%*x %d", -10, 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ int retval =
+ my_sprintf (result, "%.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a positive number. */
+ int retval =
+ my_sprintf (result, "%.0x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a zero number. */
+ int retval =
+ my_sprintf (result, "%.0x %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width and precision. */
+ int retval =
+ my_sprintf (result, "%15.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Padding and precision. */
+ int retval =
+ my_sprintf (result, "%015.10x %d", 12348, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "00000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ #endif
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ int retval =
+ my_sprintf (result, "%-10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with zero. */
+ int retval =
+ my_sprintf (result, "%#x %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ int retval =
+ my_sprintf (result, "%#x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0x303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ int retval =
+ my_sprintf (result, "%#10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ int retval =
+ my_sprintf (result, "%0#10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0x0000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ int retval =
+ my_sprintf (result, "%0#.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0x000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ int retval =
+ my_sprintf (result, "%#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ int retval =
+ my_sprintf (result, "%0#15.10x %d", 12348, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ #endif
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ int retval =
+ my_sprintf (result, "%#.0x %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Uppercase 'X'. */
+ int retval =
+ my_sprintf (result, "%X %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "303C 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT. */
+ int retval =
+ my_sprintf (result, "%#X %d", 12348, 33, 44, 55);
+ ASSERT (strcmp (result, "0X303C 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number. */
+ int retval =
+ my_sprintf (result, "%#.0X %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
/* Test the support of the 'b' conversion specifier for binary output of
integers. */
@@ -3114,6 +3298,45 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
ASSERT (retval == strlen (result));
}
+ { /* Precision. */
+ int retval =
+ my_sprintf (result, "%.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a positive number. */
+ int retval =
+ my_sprintf (result, "%.0b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a zero number. */
+ int retval =
+ my_sprintf (result, "%.0b %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width and precision. */
+ int retval =
+ my_sprintf (result, "%25.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Padding and precision. */
+ int retval =
+ my_sprintf (result, "%025.20b %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
{ /* FLAG_LEFT. */
int retval =
my_sprintf (result, "%-20b %d", 12345, 33, 44, 55);
@@ -3134,4 +3357,51 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
ASSERT (strcmp (result, "0b11000000111001 33") == 0);
ASSERT (retval == strlen (result));
}
+
+ { /* FLAG_ALT with a positive number and width. */
+ int retval =
+ my_sprintf (result, "%#20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ int retval =
+ my_sprintf (result, "%0#20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ int retval =
+ my_sprintf (result, "%0#.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ int retval =
+ my_sprintf (result, "%#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ int retval =
+ my_sprintf (result, "%0#25.20b %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ int retval =
+ my_sprintf (result, "%#.0b %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
}
diff --git a/tests/test-vasnprintf-posix.c b/tests/test-vasnprintf-posix.c
index ecbb8bcda0..87f4fc290b 100644
--- a/tests/test-vasnprintf-posix.c
+++ b/tests/test-vasnprintf-posix.c
@@ -4017,6 +4017,259 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
}
#endif
+ /* Test the support of the 'x' conversion specifier for hexadecimal output of
+ integers. */
+
+ { /* Zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "fffffffe 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%*x %d", 10, 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%*x %d", -10, 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "000000303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%015.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "00000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ #endif
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x0000303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x000000303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ #endif
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.0x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X'. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%X %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303C 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#X %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0X303C 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.0X %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
/* Test the support of the 'b' conversion specifier for binary output of
integers. */
@@ -4080,6 +4333,60 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
free (result);
}
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%025.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
{ /* FLAG_LEFT. */
size_t length;
char *result =
@@ -4094,6 +4401,7 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
size_t length;
char *result =
my_asnprintf (NULL, &length, "%#b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
ASSERT (strcmp (result, "0 33") == 0);
ASSERT (length == strlen (result));
free (result);
@@ -4103,11 +4411,77 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
size_t length;
char *result =
my_asnprintf (NULL, &length, "%#b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
ASSERT (strcmp (result, "0b11000000111001 33") == 0);
ASSERT (length == strlen (result));
free (result);
}
+ { /* FLAG_ALT with a positive number and width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0b11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
/* Test that the 'I' flag is supported. */
{
diff --git a/tests/test-vasnwprintf-posix.c b/tests/test-vasnwprintf-posix.c
index e53c6a33f3..49f5f91ebe 100644
--- a/tests/test-vasnwprintf-posix.c
+++ b/tests/test-vasnwprintf-posix.c
@@ -4022,6 +4022,259 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
}
#endif
+ /* Test the support of the 'x' conversion specifier for hexadecimal output of
+ integers. */
+
+ { /* Zero. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%x %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"fffffffe 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%*x %d", 10, 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%*x %d", -10, 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"000000303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.0x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.0x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (wcscmp (result, L" 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 000000303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%015.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #if MUSL_LIBC || defined __MINGW32__
+ ASSERT (wcscmp (result, L"00000000000303c 33") == 0);
+ #else
+ ASSERT (wcscmp (result, L" 000000303c 33") == 0);
+ #endif
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%-10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0x303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 0x303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0x0000303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0x000000303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 0x000000303c 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #if MUSL_LIBC || defined __MINGW32__
+ ASSERT (wcscmp (result, L"0x000000000303c 33") == 0);
+ #else
+ ASSERT (wcscmp (result, L" 0x000000303c 33") == 0);
+ #endif
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#.0x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (wcscmp (result, L" 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X'. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%X %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"303C 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#X %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0X303C 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#.0X %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (wcscmp (result, L" 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
/* Test the support of the 'b' conversion specifier for binary output of
integers. */
@@ -4085,6 +4338,60 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
free (result);
}
+ { /* Precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.0b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (wcscmp (result, L" 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%025.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (wcscmp (result, L" 00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
{ /* FLAG_LEFT. */
size_t length;
wchar_t *result =
@@ -4099,6 +4406,7 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
size_t length;
wchar_t *result =
my_asnwprintf (NULL, &length, L"%#b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
ASSERT (wcscmp (result, L"0 33") == 0);
ASSERT (length == wcslen (result));
free (result);
@@ -4108,11 +4416,77 @@ test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *,
size_t length;
wchar_t *result =
my_asnwprintf (NULL, &length, L"%#b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
ASSERT (wcscmp (result, L"0b11000000111001 33") == 0);
ASSERT (length == wcslen (result));
free (result);
}
+ { /* FLAG_ALT with a positive number and width. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 0b11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0b000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0b00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 0b00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (wcscmp (result, L" 0b00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (wcscmp (result, L" 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
/* Test that the 'I' flag is supported. */
{
diff --git a/tests/test-vasprintf-posix.c b/tests/test-vasprintf-posix.c
index 46086ef251..0da0c7441b 100644
--- a/tests/test-vasprintf-posix.c
+++ b/tests/test-vasprintf-posix.c
@@ -3956,6 +3956,259 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
}
#endif
+ /* Test the support of the 'x' conversion specifier for hexadecimal output of
+ integers. */
+
+ { /* Zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%x %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "fffffffe 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%*x %d", 10, 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%*x %d", -10, 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%015.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "00000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 000000303c 33") == 0);
+ #endif
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x0000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#15.10x %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when a width
+ and a precision are both present. But most implementations do so. */
+ #ifdef __MINGW32__
+ ASSERT (strcmp (result, "0x000000000303c 33") == 0);
+ #else
+ ASSERT (strcmp (result, " 0x000000303c 33") == 0);
+ #endif
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.0x %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X'. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%X %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "303C 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#X %d", 12348, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0X303C 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Uppercase 'X' with FLAG_ALT and zero precision and a zero number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.0X %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
/* Test the support of the 'b' conversion specifier for binary output of
integers. */
@@ -4019,6 +4272,60 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
free (result);
}
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%025.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
{ /* FLAG_LEFT. */
char *result;
int retval =
@@ -4033,6 +4340,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
char *result;
int retval =
my_asprintf (&result, "%#b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
ASSERT (strcmp (result, "0 33") == 0);
ASSERT (retval == strlen (result));
free (result);
@@ -4042,10 +4350,76 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
char *result;
int retval =
my_asprintf (&result, "%#b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
ASSERT (strcmp (result, "0b11000000111001 33") == 0);
ASSERT (retval == strlen (result));
free (result);
}
+
+ { /* FLAG_ALT with a positive number and width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
}
static int
^ permalink raw reply related [flat|nested] 9+ messages in thread
* new modules *printf-gnu
2023-03-18 12:47 ` Eric Blake
@ 2023-03-24 11:37 ` Bruno Haible
2023-03-24 16:11 ` Eric Blake
0 siblings, 1 reply; 9+ messages in thread
From: Bruno Haible @ 2023-03-24 11:37 UTC (permalink / raw)
To: Pádraig Brady, Eric Blake; +Cc: bug-gnulib
[-- Attachment #1: Type: text/plain, Size: 12676 bytes --]
Eric Blake wrote in
<https://lists.gnu.org/archive/html/bug-gnulib/2023-03/msg00060.html>:
> C23 admits that %#B is not available for
> portable use of outputting uppercase '0B...', you would have to
> manually write 0B%b instead. However, since glibc DOES support %B as
> the uppercase counterpart to %b, should we add that in gnulib (but
> this time under the auspices of *printf-gnu, rather than
> *printf-posix)?
Nice idea. I was pondering what to do with the wording in ISO C23
"Implementations that did not use an uppercase B as their own
extension before are encouraged to implement it similar to
conversion specifier b as standardized above, with the
alternative form (#B) generating 0B as prefix for nonzero values."
"encouraged" - should we add it to the *printf-posix modules or not?
Your suggestion to put it under *printf-gnu, that being an extension
of *printf-posix, makes perfect sense, since glibc implements %B
since version 2.35. Implemented as follows.
2023-03-24 Bruno Haible <bruno@clisp.org>
xprintf-gnu: New module.
* modules/xprintf-gnu: New file, based on modules/vasnprintf-gnu and
modules/xprintf-posix.
2023-03-24 Bruno Haible <bruno@clisp.org>
xvasprintf-gnu: New module.
* modules/xvasprintf-gnu: New file, based on modules/xvasprintf-posix.
2023-03-24 Bruno Haible <bruno@clisp.org>
vasnwprintf-gnu: Add tests.
* tests/test-vasnwprintf-gnu.c: New file, based on
tests/test-vasnwprintf-posix.c and tests/test-vasnprintf-gnu.c.
* modules/vasnwprintf-gnu-tests: New file, based on
modules/vasnwprintf-posix-tests.
vasnwprintf-gnu: New module.
* m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_IS_POSIX): New macro.
(gl_FUNC_VASNWPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vasnwprintf-gnu.m4: New file, based on m4/vasnprintf-gnu.m4.
* modules/vasnwprintf-gnu: New file, based on modules/vasnprintf-gnu.
2023-03-24 Bruno Haible <bruno@clisp.org>
obstack-printf-gnu: Add tests.
* modules/obstack-printf-gnu-tests: New file, based on
modules/obstack-printf-posix-tests.
obstack-printf-gnu: New module.
* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_IS_POSIX): New
macro, extracted from gl_FUNC_OBSTACK_PRINTF_POSIX.
(gl_FUNC_OBSTACK_PRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/obstack-printf-gnu.m4: New file, based on
m4/obstack-printf-posix.m4.
* modules/obstack-printf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/glibc-functions/obstack_printf.texi: Mention the new module.
* doc/glibc-functions/obstack_vprintf.texi: Likewise.
2023-03-24 Bruno Haible <bruno@clisp.org>
dprintf-gnu: Add tests.
* tests/test-dprintf-gnu.sh: New file, based on
tests/test-dprintf-posix.sh.
* tests/test-dprintf-gnu.c: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/dprintf-gnu-tests: New file, based on
modules/dprintf-posix-tests.
dprintf-gnu: New module.
* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_DPRINTF_POSIX.
(gl_FUNC_DPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/dprintf-gnu.m4: New file, based on m4/dprintf-posix.m4.
* modules/dprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/dprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
vdprintf-gnu: Add tests.
* tests/test-vdprintf-gnu.sh: New file, based on
tests/test-vdprintf-posix.sh.
* tests/test-vdprintf-gnu.c: New file, based on
tests/test-vdprintf-posix.c.
* modules/vdprintf-gnu-tests: New file, based on
modules/vdprintf-posix-tests.
vdprintf-gnu: New module.
* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VDPRINTF_POSIX.
(gl_FUNC_VDPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vdprintf-gnu.m4: New file, based on m4/vdprintf-posix.m4.
* modules/vdprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vdprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
printf-gnu: Add tests.
* tests/test-printf-gnu.sh: New file, based on
tests/test-printf-posix.sh.
* tests/test-printf-gnu.c: New file, based on tests/test-printf-posix.c.
* modules/printf-gnu-tests: New file, based on
modules/printf-posix-tests.
printf-gnu: New module.
* m4/printf-posix.m4: Renamed from m4/printf-posix-rpl.m4.
(gl_FUNC_PRINTF_IS_POSIX): New macro.
(gl_FUNC_PRINTF_POSIX): Require it. Don't require
gl_FUNC_VFPRINTF_POSIX. Invoke gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
and gl_REPLACE_VASNPRINTF.
* m4/printf-gnu.m4: New file, based on m4/fprintf-posix.m4.
* modules/printf-posix (Files): Update.
* modules/printf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/printf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
vprintf-gnu: Add tests.
* tests/test-vprintf-gnu.sh: New file, based on
tests/test-vprintf-posix.sh.
* tests/test-vprintf-gnu.c: New file, based on
tests/test-vprintf-posix.c.
* tests/test-printf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vprintf-gnu-tests: New file, based on
modules/vprintf-posix-tests.
vprintf-gnu: New module.
* m4/vprintf-posix.m4 (gl_FUNC_VPRINTF_IS_POSIX): New macro.
(gl_FUNC_VPRINTF_POSIX): Require it. Don't require
gl_FUNC_VFPRINTF_POSIX. Invoke gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
and gl_REPLACE_VASNPRINTF.
* m4/vprintf-gnu.m4: New file, based on m4/vfprintf-posix.m4.
* modules/vprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
fprintf-gnu: Add tests.
* tests/test-fprintf-gnu.sh: New file, based on
tests/test-fprintf-posix.sh.
* tests/test-fprintf-gnu.c: New file, based on
tests/test-fprintf-posix.c.
* modules/fprintf-gnu-tests: New file, based on
modules/fprintf-posix-tests.
fprintf-gnu: New module.
* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_FPRINTF_POSIX.
(gl_FUNC_FPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/fprintf-gnu.m4: New file, based on m4/fprintf-posix.m4.
* modules/fprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/fprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
vfprintf-gnu: Add tests.
* tests/test-vfprintf-gnu.sh: New file, based on
tests/test-vfprintf-posix.sh.
* tests/test-vfprintf-gnu.c: New file, based on
tests/test-vfprintf-posix.c.
* tests/test-fprintf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* tests/test-printf-gnu.output: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vfprintf-gnu-tests: New file, based on
modules/vfprintf-posix-tests.
vfprintf-gnu: New module.
* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VFPRINTF_POSIX.
(gl_FUNC_VFPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vfprintf-gnu.m4: New file, based on m4/vfprintf-posix.m4.
* modules/vfprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vfprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
vasprintf-gnu: Add tests.
* tests/test-vasprintf-gnu.c: New file, based on
tests/test-vasprintf-posix.c and tests/test-vasnprintf-gnu.c.
* modules/vasprintf-gnu-tests: New file, based on
modules/vasprintf-posix-tests.
vasprintf-gnu: New module.
* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VASPRINTF_POSIX.
(gl_FUNC_VASPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vasprintf-gnu.m4: New file, based on m4/vasprintf-posix.m4.
* modules/vasprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/glibc-functions/vasprintf.texi: Mention the new module.
* doc/glibc-functions/asprintf.texi: Likewise.
2023-03-24 Bruno Haible <bruno@clisp.org>
sprintf-gnu: Add tests.
* tests/test-sprintf-gnu.c: New file, based on
tests/test-sprintf-posix.c.
* modules/sprintf-gnu-tests: New file, based on
modules/sprintf-posix-tests.
sprintf-gnu: New module.
* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_SPRINTF_POSIX.
(gl_FUNC_SPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/sprintf-gnu.m4: New file, based on m4/sprintf-posix.m4.
* modules/sprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/sprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
vsprintf-gnu: Add tests.
* tests/test-vsprintf-gnu.c: New file, based on
tests/test-vsprintf-posix.c.
* tests/test-sprintf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vsprintf-gnu-tests: New file, based on
modules/vsprintf-posix-tests.
vsprintf-gnu: New module.
* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VSPRINTF_POSIX.
(gl_FUNC_VSPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vsprintf-gnu.m4: New file, based on m4/vsprintf-posix.m4.
* modules/vsprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vsprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
snprintf-gnu: Add tests.
* tests/test-snprintf-gnu.c: New file, based on
tests/test-snprintf-posix.c.
* modules/snprintf-gnu-tests: New file, based on
modules/snprintf-posix-tests.
snprintf-gnu: New module.
* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_SNPRINTF_POSIX.
(gl_FUNC_SNPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/snprintf-gnu.m4: New file, based on m4/snprintf-posix.m4.
* modules/snprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/snprintf.texi: Mention the new module.
2023-03-24 Bruno Haible <bruno@clisp.org>
vsnprintf-gnu: Add tests.
* tests/test-vsnprintf-gnu.c: New file, based on
tests/test-vsnprintf-posix.c.
* tests/test-snprintf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vsnprintf-gnu-tests: New file, based on
modules/vsnprintf-posix-tests.
vsnprintf-gnu: New module.
* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VSNPRINTF_POSIX.
(gl_FUNC_VSNPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vsnprintf-gnu.m4: New file, based on m4/vsnprintf-posix.m4.
* modules/vsnprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vsnprintf.texi: Mention the new module.
2023-03-23 Bruno Haible <bruno@clisp.org>
vasnprintf-gnu: Add tests.
* tests/test-vasnprintf-gnu.c: New file, based on
tests/test-vasnprintf-posix.c.
* modules/vasnprintf-gnu-tests: New file.
vasnprintf-gnu: New module.
Suggested by Eric Blake in
<https://lists.gnu.org/archive/html/bug-gnulib/2023-03/msg00060.html>.
* lib/printf-parse.c (PRINTF_PARSE): Recognize the 'B' conversion.
* lib/printf-parse.h: Update comments.
* lib/wprintf-parse.h: Likewise.
* lib/vasnprintf.c (MAX_ROOM_NEEDED): Treat the 'B' conversion like 'b'.
(VASNPRINTF): Implement 'B' conversion if
NEED_PRINTF_DIRECTIVE_UPPERCASE_B is set. Support the 'B' conversion if
requested.
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_B): When cross-compiling, guess yes
on glibc >= 2.35.
(gl_PRINTF_DIRECTIVE_UPPERCASE_B): New macro.
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS): Renamed
from gl_PREREQ_VASNPRINTF_WITH_EXTRAS.
(gl_PREREQ_VASNPRINTF_DIRECTIVE_UPPERCASE_B,
gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS): New macros.
* m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VASNPRINTF_POSIX.
(gl_FUNC_VASNPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vasnprintf-gnu.m4: New file.
* modules/vasnprintf-gnu: New file.
* modules/c-vasnprintf (configure.ac): Update.
* modules/unistdio/u8-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u8-u8-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u16-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u16-u16-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u32-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u32-u32-vasnprintf (configure.ac): Likewise.
* modules/unistdio/ulc-vasnprintf (configure.ac): Likewise.
2023-03-23 Bruno Haible <bruno@clisp.org>
printf-posix tests: Fix compilation error (regression 2021-08-28).
* modules/printf-posix-tests (Files): Add tests/qemu.h.
[-- Attachment #2: 0001-printf-posix-tests-Fix-compilation-error-regression-.patch --]
[-- Type: text/x-patch, Size: 1162 bytes --]
From f9a4ee73c3e7b544f640d0d04b55983d3a7b894e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 02:45:09 +0100
Subject: [PATCH 01/31] printf-posix tests: Fix compilation error (regression
2021-08-28).
* modules/printf-posix-tests (Files): Add tests/qemu.h.
---
ChangeLog | 5 +++++
modules/printf-posix-tests | 1 +
2 files changed, 6 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index ac12201885..4a70e323ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2023-03-23 Bruno Haible <bruno@clisp.org>
+
+ printf-posix tests: Fix compilation error (regression 2021-08-28).
+ * modules/printf-posix-tests (Files): Add tests/qemu.h.
+
2023-03-22 Jim Meyering <meyering@fb.com>
gnu-web-doc-update: don't use host alias, cvs.sv.gnu.org
diff --git a/modules/printf-posix-tests b/modules/printf-posix-tests
index 8a99cd6cdd..c602aa40f1 100644
--- a/modules/printf-posix-tests
+++ b/modules/printf-posix-tests
@@ -6,6 +6,7 @@ tests/test-printf-posix.output
tests/test-printf-posix2.sh
tests/test-printf-posix2.c
tests/infinity.h
+tests/qemu.h
tests/signature.h
tests/macros.h
--
2.34.1
[-- Attachment #3: 0002-vasnprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 35135 bytes --]
From 0645e170eadd356967b0690ba8208d85e8042edd Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Thu, 23 Mar 2023 13:51:41 +0100
Subject: [PATCH 02/31] vasnprintf-gnu: New module.
Suggested by Eric Blake in
<https://lists.gnu.org/archive/html/bug-gnulib/2023-03/msg00060.html>.
* lib/printf-parse.c (PRINTF_PARSE): Recognize the 'B' conversion.
* lib/printf-parse.h: Update comments.
* lib/wprintf-parse.h: Likewise.
* lib/vasnprintf.c (MAX_ROOM_NEEDED): Treat the 'B' conversion like 'b'.
(VASNPRINTF): Implement 'B' conversion if
NEED_PRINTF_DIRECTIVE_UPPERCASE_B is set. Support the 'B' conversion if
requested.
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_B): When cross-compiling, guess yes
on glibc >= 2.35.
(gl_PRINTF_DIRECTIVE_UPPERCASE_B): New macro.
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS): Renamed
from gl_PREREQ_VASNPRINTF_WITH_EXTRAS.
(gl_PREREQ_VASNPRINTF_DIRECTIVE_UPPERCASE_B,
gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS): New macros.
* m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VASNPRINTF_POSIX.
(gl_FUNC_VASNPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vasnprintf-gnu.m4: New file.
* modules/vasnprintf-gnu: New file.
* modules/c-vasnprintf (configure.ac): Update.
* modules/unistdio/u8-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u8-u8-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u16-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u16-u16-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u32-vasnprintf (configure.ac): Likewise.
* modules/unistdio/u32-u32-vasnprintf (configure.ac): Likewise.
* modules/unistdio/ulc-vasnprintf (configure.ac): Likewise.
---
ChangeLog | 34 +++++
lib/printf-parse.c | 4 +
lib/printf-parse.h | 8 +-
lib/vasnprintf.c | 28 +++-
lib/wprintf-parse.h | 2 +-
m4/printf.m4 | 224 ++++++++++++++++++----------
m4/vasnprintf-gnu.m4 | 24 +++
m4/vasnprintf-posix.m4 | 29 ++--
m4/vasnprintf.m4 | 30 +++-
modules/c-vasnprintf | 2 +-
modules/unistdio/u16-u16-vasnprintf | 2 +-
modules/unistdio/u16-vasnprintf | 2 +-
modules/unistdio/u32-u32-vasnprintf | 2 +-
modules/unistdio/u32-vasnprintf | 2 +-
modules/unistdio/u8-u8-vasnprintf | 2 +-
modules/unistdio/u8-vasnprintf | 2 +-
modules/unistdio/ulc-vasnprintf | 2 +-
modules/vasnprintf-gnu | 29 ++++
18 files changed, 315 insertions(+), 113 deletions(-)
create mode 100644 m4/vasnprintf-gnu.m4
create mode 100644 modules/vasnprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 4a70e323ae..ccab8c88cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2023-03-23 Bruno Haible <bruno@clisp.org>
+
+ vasnprintf-gnu: New module.
+ Suggested by Eric Blake in
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-03/msg00060.html>.
+ * lib/printf-parse.c (PRINTF_PARSE): Recognize the 'B' conversion.
+ * lib/printf-parse.h: Update comments.
+ * lib/wprintf-parse.h: Likewise.
+ * lib/vasnprintf.c (MAX_ROOM_NEEDED): Treat the 'B' conversion like 'b'.
+ (VASNPRINTF): Implement 'B' conversion if
+ NEED_PRINTF_DIRECTIVE_UPPERCASE_B is set. Support the 'B' conversion if
+ requested.
+ * m4/printf.m4 (gl_PRINTF_DIRECTIVE_B): When cross-compiling, guess yes
+ on glibc >= 2.35.
+ (gl_PRINTF_DIRECTIVE_UPPERCASE_B): New macro.
+ * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS): Renamed
+ from gl_PREREQ_VASNPRINTF_WITH_EXTRAS.
+ (gl_PREREQ_VASNPRINTF_DIRECTIVE_UPPERCASE_B,
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS): New macros.
+ * m4/vasnprintf-posix.m4 (gl_FUNC_VASNPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_VASNPRINTF_POSIX.
+ (gl_FUNC_VASNPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/vasnprintf-gnu.m4: New file.
+ * modules/vasnprintf-gnu: New file.
+ * modules/c-vasnprintf (configure.ac): Update.
+ * modules/unistdio/u8-vasnprintf (configure.ac): Likewise.
+ * modules/unistdio/u8-u8-vasnprintf (configure.ac): Likewise.
+ * modules/unistdio/u16-vasnprintf (configure.ac): Likewise.
+ * modules/unistdio/u16-u16-vasnprintf (configure.ac): Likewise.
+ * modules/unistdio/u32-vasnprintf (configure.ac): Likewise.
+ * modules/unistdio/u32-u32-vasnprintf (configure.ac): Likewise.
+ * modules/unistdio/ulc-vasnprintf (configure.ac): Likewise.
+
2023-03-23 Bruno Haible <bruno@clisp.org>
printf-posix tests: Fix compilation error (regression 2021-08-28).
diff --git a/lib/printf-parse.c b/lib/printf-parse.c
index 6273dd773f..7fbd1d4b53 100644
--- a/lib/printf-parse.c
+++ b/lib/printf-parse.c
@@ -454,6 +454,10 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
type = TYPE_INT;
break;
case 'b': case 'o': case 'u': case 'x': case 'X':
+ #if SUPPORT_GNU_PRINTF_DIRECTIVES \
+ || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
+ case 'B':
+ #endif
/* If 'unsigned long long' is larger than 'unsigned long': */
if (flags >= 16 || (flags & 4))
type = TYPE_ULONGLONGINT;
diff --git a/lib/printf-parse.h b/lib/printf-parse.h
index dc4bcfe2a3..45febac1f0 100644
--- a/lib/printf-parse.h
+++ b/lib/printf-parse.h
@@ -61,7 +61,7 @@ typedef struct
const char* precision_start;
const char* precision_end;
size_t precision_arg_index;
- char conversion; /* d i b o u x X f F e E g G a A c s p n U % but not C S */
+ char conversion; /* d i b B o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
char_directive;
@@ -91,7 +91,7 @@ typedef struct
const uint8_t* precision_start;
const uint8_t* precision_end;
size_t precision_arg_index;
- uint8_t conversion; /* d i b o u x X f F e E g G a A c s p n U % but not C S */
+ uint8_t conversion; /* d i b B o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
u8_directive;
@@ -119,7 +119,7 @@ typedef struct
const uint16_t* precision_start;
const uint16_t* precision_end;
size_t precision_arg_index;
- uint16_t conversion; /* d i b o u x X f F e E g G a A c s p n U % but not C S */
+ uint16_t conversion; /* d i b B o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
u16_directive;
@@ -147,7 +147,7 @@ typedef struct
const uint32_t* precision_start;
const uint32_t* precision_end;
size_t precision_arg_index;
- uint32_t conversion; /* d i b o u x X f F e E g G a A c s p n U % but not C S */
+ uint32_t conversion; /* d i b B o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
u32_directive;
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 248444ca23..bb7d0aec25 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -1660,6 +1660,10 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
break;
case 'b':
+ #if SUPPORT_GNU_PRINTF_DIRECTIVES \
+ || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
+ case 'B':
+ #endif
if (type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT)
@@ -3212,8 +3216,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#endif
-#if NEED_PRINTF_DIRECTIVE_B
- else if (dp->conversion == 'b')
+#if NEED_PRINTF_DIRECTIVE_B || NEED_PRINTF_DIRECTIVE_UPPERCASE_B
+ else if (0
+# if NEED_PRINTF_DIRECTIVE_B
+ || (dp->conversion == 'b')
+# endif
+# if NEED_PRINTF_DIRECTIVE_UPPERCASE_B
+ || (dp->conversion == 'B')
+# endif
+ )
{
arg_type type = a.arg[dp->arg_index].type;
int flags = dp->flags;
@@ -3359,7 +3370,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (need_prefix)
{
- *--p = 'b'; *--p = '0';
+# if NEED_PRINTF_DIRECTIVE_B && !NEED_PRINTF_DIRECTIVE_UPPERCASE_B
+ *--p = 'b';
+# elif NEED_PRINTF_DIRECTIVE_UPPERCASE_B && !NEED_PRINTF_DIRECTIVE_B
+ *--p = 'B';
+# else
+ *--p = dp->conversion;
+# endif
+ *--p = '0';
}
tmp_start = p;
@@ -5209,6 +5227,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
case 'd': case 'i': case 'u':
case 'b':
+ #if SUPPORT_GNU_PRINTF_DIRECTIVES \
+ || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
+ case 'B':
+ #endif
case 'o':
case 'x': case 'X': case 'p':
prec_ourselves = has_precision && (precision > 0);
diff --git a/lib/wprintf-parse.h b/lib/wprintf-parse.h
index 86bdec9a21..fe46298278 100644
--- a/lib/wprintf-parse.h
+++ b/lib/wprintf-parse.h
@@ -55,7 +55,7 @@ typedef struct
const wchar_t* precision_start;
const wchar_t* precision_end;
size_t precision_arg_index;
- wchar_t conversion; /* d i b o u x X f F e E g G a A c s p n U % but not C S */
+ wchar_t conversion; /* d i b B o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
wchar_t_directive;
diff --git a/m4/printf.m4 b/m4/printf.m4
index 3cf8c87b1a..2f15df1e76 100644
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 77
+# printf.m4 serial 78
dnl Copyright (C) 2003, 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -632,8 +632,19 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_B]
[gl_cv_func_printf_directive_b=no],
[
case "$host_os" in
- # Guess no on glibc systems.
- *-gnu* | gnu*) gl_cv_func_printf_directive_b="guessing no";;
+ # Guess yes on glibc >= 2.35 systems.
+ *-gnu* | gnu*)
+ AC_EGREP_CPP([Lucky], [
+ #include <features.h>
+ #ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 35) || (__GLIBC__ > 2)
+ Lucky user
+ #endif
+ #endif
+ ],
+ [gl_cv_func_printf_directive_uppercase_b="guessing yes"],
+ [gl_cv_func_printf_directive_uppercase_b="guessing no"])
+ ;;
# Guess no on musl systems.
*-musl* | midipix*) gl_cv_func_printf_directive_b="guessing no";;
# Guess no on Android.
@@ -647,6 +658,61 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_B]
])
])
+dnl Test whether the *printf family of functions supports the 'B' conversion
+dnl specifier for binary output of integers.
+dnl (GNU, encouraged by ISO C23 § 7.23.6.1)
+dnl Result is gl_cv_func_printf_directive_uppercase_b.
+
+AC_DEFUN([gl_PRINTF_DIRECTIVE_UPPERCASE_B],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether printf supports the 'B' directive],
+ [gl_cv_func_printf_directive_uppercase_b],
+ [
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <string.h>
+static char buf[100];
+int main ()
+{
+ int result = 0;
+ if (sprintf (buf, "%#B %d", 12345, 33, 44, 55) < 0
+ || strcmp (buf, "0B11000000111001 33") != 0)
+ result |= 1;
+ return result;
+}]])],
+ [gl_cv_func_printf_directive_uppercase_b=yes],
+ [gl_cv_func_printf_directive_uppercase_b=no],
+ [
+ case "$host_os" in
+ # Guess yes on glibc >= 2.35 systems.
+ *-gnu* | gnu*)
+ AC_EGREP_CPP([Lucky], [
+ #include <features.h>
+ #ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 35) || (__GLIBC__ > 2)
+ Lucky user
+ #endif
+ #endif
+ ],
+ [gl_cv_func_printf_directive_uppercase_b="guessing yes"],
+ [gl_cv_func_printf_directive_uppercase_b="guessing no"])
+ ;;
+ # Guess no on musl systems.
+ *-musl* | midipix*) gl_cv_func_printf_directive_uppercase_b="guessing no";;
+ # Guess no on Android.
+ linux*-android*) gl_cv_func_printf_directive_uppercase_b="guessing no";;
+ # Guess no on native Windows.
+ mingw*) gl_cv_func_printf_directive_uppercase_b="guessing no";;
+ # If we don't know, obey --enable-cross-guesses.
+ *) gl_cv_func_printf_directive_uppercase_b="$gl_cross_guess_normal";;
+ esac
+ ])
+ ])
+])
+
dnl Test whether the *printf family of functions supports the %F format
dnl directive. (ISO C99, POSIX:2001)
dnl Result is gl_cv_func_printf_directive_f.
@@ -1806,23 +1872,24 @@ AC_DEFUN([gl_SWPRINTF_WORKS]
dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE
dnl 5 = gl_PRINTF_DIRECTIVE_A
dnl 6 = gl_PRINTF_DIRECTIVE_B
-dnl 7 = gl_PRINTF_DIRECTIVE_F
-dnl 8 = gl_PRINTF_DIRECTIVE_N
-dnl 9 = gl_PRINTF_DIRECTIVE_LS
-dnl 10 = gl_PRINTF_DIRECTIVE_LC
-dnl 11 = gl_PRINTF_POSITIONS
-dnl 12 = gl_PRINTF_FLAG_GROUPING
-dnl 13 = gl_PRINTF_FLAG_LEFTADJUST
-dnl 14 = gl_PRINTF_FLAG_ZERO
-dnl 15 = gl_PRINTF_PRECISION
-dnl 16 = gl_PRINTF_ENOMEM
-dnl 17 = gl_SNPRINTF_PRESENCE
-dnl 18 = gl_SNPRINTF_TRUNCATION_C99
-dnl 19 = gl_SNPRINTF_RETVAL_C99
-dnl 10 = gl_SNPRINTF_DIRECTIVE_N
-dnl 21 = gl_SNPRINTF_SIZE1
-dnl 22 = gl_VSNPRINTF_ZEROSIZE_C99
-dnl 23 = gl_SWPRINTF_WORKS
+dnl 7 = gl_PRINTF_DIRECTIVE_UPPERCASE_B
+dnl 8 = gl_PRINTF_DIRECTIVE_F
+dnl 9 = gl_PRINTF_DIRECTIVE_N
+dnl 10 = gl_PRINTF_DIRECTIVE_LS
+dnl 11 = gl_PRINTF_DIRECTIVE_LC
+dnl 12 = gl_PRINTF_POSITIONS
+dnl 13 = gl_PRINTF_FLAG_GROUPING
+dnl 14 = gl_PRINTF_FLAG_LEFTADJUST
+dnl 15 = gl_PRINTF_FLAG_ZERO
+dnl 16 = gl_PRINTF_PRECISION
+dnl 17 = gl_PRINTF_ENOMEM
+dnl 18 = gl_SNPRINTF_PRESENCE
+dnl 19 = gl_SNPRINTF_TRUNCATION_C99
+dnl 20 = gl_SNPRINTF_RETVAL_C99
+dnl 21 = gl_SNPRINTF_DIRECTIVE_N
+dnl 22 = gl_SNPRINTF_SIZE1
+dnl 23 = gl_VSNPRINTF_ZEROSIZE_C99
+dnl 24 = gl_SWPRINTF_WORKS
dnl
dnl 1 = checking whether printf supports size specifiers as in C99...
dnl 2 = checking whether printf supports 'long double' arguments...
@@ -1830,64 +1897,65 @@ AC_DEFUN([gl_SWPRINTF_WORKS]
dnl 4 = checking whether printf supports infinite 'long double' arguments...
dnl 5 = checking whether printf supports the 'a' and 'A' directives...
dnl 6 = checking whether printf supports the 'b' directive...
-dnl 7 = checking whether printf supports the 'F' directive...
-dnl 8 = checking whether printf supports the 'n' directive...
-dnl 9 = checking whether printf supports the 'ls' directive...
-dnl 10 = checking whether printf supports the 'lc' directive correctly...
-dnl 11 = checking whether printf supports POSIX/XSI format strings with positions...
-dnl 12 = checking whether printf supports the grouping flag...
-dnl 13 = checking whether printf supports the left-adjust flag correctly...
-dnl 14 = checking whether printf supports the zero flag correctly...
-dnl 15 = checking whether printf supports large precisions...
-dnl 16 = checking whether printf survives out-of-memory conditions...
-dnl 17 = checking for snprintf...
-dnl 18 = checking whether snprintf truncates the result as in C99...
-dnl 19 = checking whether snprintf returns a byte count as in C99...
-dnl 20 = checking whether snprintf fully supports the 'n' directive...
-dnl 21 = checking whether snprintf respects a size of 1...
-dnl 22 = checking whether vsnprintf respects a zero size as in C99...
-dnl 23 = checking whether swprintf works...
+dnl 7 = checking whether printf supports the 'B' directive...
+dnl 8 = checking whether printf supports the 'F' directive...
+dnl 9 = checking whether printf supports the 'n' directive...
+dnl 10 = checking whether printf supports the 'ls' directive...
+dnl 11 = checking whether printf supports the 'lc' directive correctly...
+dnl 12 = checking whether printf supports POSIX/XSI format strings with positions...
+dnl 13 = checking whether printf supports the grouping flag...
+dnl 14 = checking whether printf supports the left-adjust flag correctly...
+dnl 15 = checking whether printf supports the zero flag correctly...
+dnl 16 = checking whether printf supports large precisions...
+dnl 17 = checking whether printf survives out-of-memory conditions...
+dnl 18 = checking for snprintf...
+dnl 19 = checking whether snprintf truncates the result as in C99...
+dnl 20 = checking whether snprintf returns a byte count as in C99...
+dnl 21 = checking whether snprintf fully supports the 'n' directive...
+dnl 22 = checking whether snprintf respects a size of 1...
+dnl 23 = checking whether vsnprintf respects a zero size as in C99...
+dnl 24 = checking whether swprintf works...
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
-dnl musl libc 1.2.3 . . . . . # . . . . . . . . . . . . . . . . #
-dnl glibc 2.35 . . . . . . . . . # . . . . . . . . . . . . .
-dnl glibc 2.5 . . . . . # . . . # . . . . . . . . . . . . ?
-dnl glibc 2.3.6 . . . . # # . . . # . . . . . . . . . . . . ?
-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
+dnl musl libc 1.2.3 . . . . . # # . . . . . . . . . . . . . . . . #
+dnl glibc 2.35 . . . . . . . . . . # . . . . . . . . . . . . .
+dnl glibc 2.5 . . . . . # # . . . # . . . . . . . . . . . . ?
+dnl glibc 2.3.6 . . . . # # # . . . # . . . . . . . . . . . . ?
+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 # # # # # # # # . . ? # # . # # ? . # # # . . #
diff --git a/m4/vasnprintf-gnu.m4 b/m4/vasnprintf-gnu.m4
new file mode 100644
index 0000000000..8c7124f6cf
--- /dev/null
+++ b/m4/vasnprintf-gnu.m4
@@ -0,0 +1,24 @@
+# vasnprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VASNPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VASNPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vasnprintf_gnu=no
+ if test $gl_cv_func_vasnprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vasnprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_vasnprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vasnprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ fi
+])
diff --git a/m4/vasnprintf-posix.m4 b/m4/vasnprintf-posix.m4
index d061d3136e..b4d1e3d0aa 100644
--- a/m4/vasnprintf-posix.m4
+++ b/m4/vasnprintf-posix.m4
@@ -1,10 +1,21 @@
-# vasnprintf-posix.m4 serial 15
+# vasnprintf-posix.m4 serial 16
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VASNPRINTF_IS_POSIX])
+ if test $gl_cv_func_vasnprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ fi
+])
+
+dnl Test whether vasnprintf exists and is POSIX compliant.
+dnl Result is gl_cv_func_vasnprintf_posix.
+AC_DEFUN_ONCE([gl_FUNC_VASNPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -93,20 +104,4 @@ AC_DEFUN([gl_FUNC_VASNPRINTF_POSIX]
esac
;;
esac
- if test $gl_cv_func_vasnprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- fi
])
diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4
index a42b5f83ac..929f3d80af 100644
--- a/m4/vasnprintf.m4
+++ b/m4/vasnprintf.m4
@@ -1,4 +1,4 @@
-# vasnprintf.m4 serial 46
+# vasnprintf.m4 serial 47
dnl Copyright (C) 2002-2004, 2006-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -341,7 +341,7 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_ENOMEM]
])
# Prerequisites of lib/vasnprintf.c including all extras for POSIX compliance.
-AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS],
+AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS],
[
AC_REQUIRE([gl_PREREQ_VASNPRINTF])
gl_PREREQ_VASNPRINTF_LONG_DOUBLE
@@ -359,6 +359,32 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS]
gl_PREREQ_VASNPRINTF_ENOMEM
])
+# Extra prerequisites of lib/vasnprintf.c for supporting the 'B' directive.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_UPPERCASE_B],
+[
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ ;;
+ *)
+ AC_DEFINE([NEED_PRINTF_DIRECTIVE_UPPERCASE_B], [1],
+ [Define if the vasnprintf implementation needs special code for
+ the 'B' directive.])
+ ;;
+ esac
+])
+
+# Prerequisites of lib/vasnprintf.c including all extras for POSIX compliance
+# and GNU compatibility.
+AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS],
+[
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ AC_DEFINE([SUPPORT_GNU_PRINTF_DIRECTIVES], [1],
+ [Define if the vasnprintf implementation should support GNU compatible
+ printf directives.])
+ gl_PREREQ_VASNPRINTF_DIRECTIVE_UPPERCASE_B
+])
+
# Prerequisites of lib/asnprintf.c.
# Prerequisites of lib/asnwprintf.c.
AC_DEFUN([gl_PREREQ_ASNPRINTF],
diff --git a/modules/c-vasnprintf b/modules/c-vasnprintf
index 44259c1f0e..35adfbbbdf 100644
--- a/modules/c-vasnprintf
+++ b/modules/c-vasnprintf
@@ -43,7 +43,7 @@ multiarch
configure.ac:
AC_REQUIRE([AC_C_RESTRICT])
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
Makefile.am:
lib_SOURCES += c-vasnprintf.c
diff --git a/modules/unistdio/u16-u16-vasnprintf b/modules/unistdio/u16-u16-vasnprintf
index ac8df9f1b1..d3ad4ffe92 100644
--- a/modules/unistdio/u16-u16-vasnprintf
+++ b/modules/unistdio/u16-u16-vasnprintf
@@ -50,7 +50,7 @@ multiarch
assert-h
configure.ac:
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
gl_LIBUNISTRING_MODULE([0.9], [unistdio/u16-u16-vasnprintf])
Makefile.am:
diff --git a/modules/unistdio/u16-vasnprintf b/modules/unistdio/u16-vasnprintf
index e767f54bd3..908f043a4e 100644
--- a/modules/unistdio/u16-vasnprintf
+++ b/modules/unistdio/u16-vasnprintf
@@ -50,7 +50,7 @@ multiarch
assert-h
configure.ac:
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
gl_LIBUNISTRING_MODULE([0.9], [unistdio/u16-vasnprintf])
Makefile.am:
diff --git a/modules/unistdio/u32-u32-vasnprintf b/modules/unistdio/u32-u32-vasnprintf
index 86e669723b..e64e97d4dd 100644
--- a/modules/unistdio/u32-u32-vasnprintf
+++ b/modules/unistdio/u32-u32-vasnprintf
@@ -50,7 +50,7 @@ multiarch
assert-h
configure.ac:
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
gl_LIBUNISTRING_MODULE([0.9], [unistdio/u32-u32-vasnprintf])
Makefile.am:
diff --git a/modules/unistdio/u32-vasnprintf b/modules/unistdio/u32-vasnprintf
index 58185bc34b..8fb0187382 100644
--- a/modules/unistdio/u32-vasnprintf
+++ b/modules/unistdio/u32-vasnprintf
@@ -50,7 +50,7 @@ multiarch
assert-h
configure.ac:
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
gl_LIBUNISTRING_MODULE([0.9], [unistdio/u32-vasnprintf])
Makefile.am:
diff --git a/modules/unistdio/u8-u8-vasnprintf b/modules/unistdio/u8-u8-vasnprintf
index 63ab8d8768..f91638bf83 100644
--- a/modules/unistdio/u8-u8-vasnprintf
+++ b/modules/unistdio/u8-u8-vasnprintf
@@ -50,7 +50,7 @@ multiarch
assert-h
configure.ac:
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
gl_LIBUNISTRING_MODULE([0.9], [unistdio/u8-u8-vasnprintf])
Makefile.am:
diff --git a/modules/unistdio/u8-vasnprintf b/modules/unistdio/u8-vasnprintf
index f6be0a5de3..f8d7e79d68 100644
--- a/modules/unistdio/u8-vasnprintf
+++ b/modules/unistdio/u8-vasnprintf
@@ -50,7 +50,7 @@ multiarch
assert-h
configure.ac:
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
gl_LIBUNISTRING_MODULE([0.9], [unistdio/u8-vasnprintf])
Makefile.am:
diff --git a/modules/unistdio/ulc-vasnprintf b/modules/unistdio/ulc-vasnprintf
index 7f7614d8ac..c950cbf62a 100644
--- a/modules/unistdio/ulc-vasnprintf
+++ b/modules/unistdio/ulc-vasnprintf
@@ -48,7 +48,7 @@ multiarch
assert-h
configure.ac:
-gl_PREREQ_VASNPRINTF_WITH_EXTRAS
+gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
gl_LIBUNISTRING_MODULE([0.9.11], [unistdio/ulc-vasnprintf])
Makefile.am:
diff --git a/modules/vasnprintf-gnu b/modules/vasnprintf-gnu
new file mode 100644
index 0000000000..b5551f3011
--- /dev/null
+++ b/modules/vasnprintf-gnu
@@ -0,0 +1,29 @@
+Description:
+POSIX and GNU compatible vsprintf with automatic memory allocation and bounded
+output size.
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vasnprintf-gnu.m4
+
+Depends-on:
+vasnprintf-posix
+
+configure.ac:
+gl_FUNC_VASNPRINTF_GNU
+
+Makefile.am:
+
+Include:
+"vasnprintf.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #4: 0003-vasnprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 10149 bytes --]
From 1bd54c4369bfaef729b85505e70b62a115a3de69 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Thu, 23 Mar 2023 13:53:44 +0100
Subject: [PATCH 03/31] vasnprintf-gnu: Add tests.
* tests/test-vasnprintf-gnu.c: New file, based on
tests/test-vasnprintf-posix.c.
* modules/vasnprintf-gnu-tests: New file.
---
ChangeLog | 5 +
modules/vasnprintf-gnu-tests | 12 ++
tests/test-vasnprintf-gnu.c | 275 +++++++++++++++++++++++++++++++++++
3 files changed, 292 insertions(+)
create mode 100644 modules/vasnprintf-gnu-tests
create mode 100644 tests/test-vasnprintf-gnu.c
diff --git a/ChangeLog b/ChangeLog
index ccab8c88cf..cd2f17b2f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2023-03-23 Bruno Haible <bruno@clisp.org>
+ vasnprintf-gnu: Add tests.
+ * tests/test-vasnprintf-gnu.c: New file, based on
+ tests/test-vasnprintf-posix.c.
+ * modules/vasnprintf-gnu-tests: New file.
+
vasnprintf-gnu: New module.
Suggested by Eric Blake in
<https://lists.gnu.org/archive/html/bug-gnulib/2023-03/msg00060.html>.
diff --git a/modules/vasnprintf-gnu-tests b/modules/vasnprintf-gnu-tests
new file mode 100644
index 0000000000..baead05526
--- /dev/null
+++ b/modules/vasnprintf-gnu-tests
@@ -0,0 +1,12 @@
+Files:
+tests/test-vasnprintf-gnu.c
+tests/macros.h
+
+Depends-on:
+vasnprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vasnprintf-gnu
+check_PROGRAMS += test-vasnprintf-gnu
diff --git a/tests/test-vasnprintf-gnu.c b/tests/test-vasnprintf-gnu.c
new file mode 100644
index 0000000000..cb75fa6135
--- /dev/null
+++ b/tests/test-vasnprintf-gnu.c
@@ -0,0 +1,275 @@
+/* Test of POSIX and GNU compatible vasnprintf() and asnprintf() functions.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+#include <config.h>
+
+#include "vasnprintf.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+static void
+test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
+{
+ /* Test the support of the 'B' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%B %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%B %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%*B %d", 20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%*B %d", -20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.0B %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%25.20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%025.20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%-20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#B %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0B11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0B11000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0B000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#.20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0B00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#25.20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0B00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%0#25.20B %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0B00000011000000111001 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%#.0B %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+}
+
+static char *
+my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
+{
+ va_list args;
+ char *ret;
+
+ va_start (args, format);
+ ret = vasnprintf (resultbuf, lengthp, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_vasnprintf ()
+{
+ test_function (my_asnprintf);
+}
+
+static void
+test_asnprintf ()
+{
+ test_function (asnprintf);
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasnprintf ();
+ test_asnprintf ();
+ return 0;
+}
--
2.34.1
[-- Attachment #5: 0004-vsnprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6613 bytes --]
From 1d4cd9aec717ac8f914fcdb6e1c997dffde6a079 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:05:38 +0100
Subject: [PATCH 04/31] vsnprintf-gnu: New module.
* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VSNPRINTF_POSIX.
(gl_FUNC_VSNPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vsnprintf-gnu.m4: New file, based on m4/vsnprintf-posix.m4.
* modules/vsnprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vsnprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/vsnprintf.texi | 13 ++++++++++---
m4/vsnprintf-gnu.m4 | 25 ++++++++++++++++++++++++
m4/vsnprintf-posix.m4 | 31 +++++++++++++-----------------
modules/vsnprintf-gnu | 29 ++++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 21 deletions(-)
create mode 100644 m4/vsnprintf-gnu.m4
create mode 100644 modules/vsnprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index cd2f17b2f9..e152b9cd55 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ vsnprintf-gnu: New module.
+ * m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_VSNPRINTF_POSIX.
+ (gl_FUNC_VSNPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/vsnprintf-gnu.m4: New file, based on m4/vsnprintf-posix.m4.
+ * modules/vsnprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/vsnprintf.texi: Mention the new module.
+
2023-03-23 Bruno Haible <bruno@clisp.org>
vasnprintf-gnu: Add tests.
diff --git a/doc/posix-functions/vsnprintf.texi b/doc/posix-functions/vsnprintf.texi
index 3531644660..e99292f178 100644
--- a/doc/posix-functions/vsnprintf.texi
+++ b/doc/posix-functions/vsnprintf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/vsnprintf.html}
-Gnulib module: vsnprintf or vsnprintf-posix
+Gnulib module: vsnprintf or vsnprintf-posix or vsnprintf-gnu
-Portability problems fixed by either Gnulib module @code{vsnprintf} or @code{vsnprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vsnprintf} or @code{vsnprintf-posix} or @code{vsnprintf-gnu}:
@itemize
@item
This function does not support format directives that access arguments in an
@@ -18,7 +18,7 @@
HP-UX 11, IRIX 6.5, Solaris 9, mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{vsnprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vsnprintf-posix} or @code{vsnprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -92,6 +92,13 @@
HP-UX 11.
@end itemize
+Portability problems fixed by Gnulib module @code{vsnprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/vsnprintf-gnu.m4 b/m4/vsnprintf-gnu.m4
new file mode 100644
index 0000000000..98098b52d9
--- /dev/null
+++ b/m4/vsnprintf-gnu.m4
@@ -0,0 +1,25 @@
+# vsnprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VSNPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VSNPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vsnprintf_gnu=no
+ if test $gl_cv_func_vsnprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vsnprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_vsnprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vsnprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VSNPRINTF
+ fi
+])
diff --git a/m4/vsnprintf-posix.m4 b/m4/vsnprintf-posix.m4
index d1e1933aa3..d65ca929a3 100644
--- a/m4/vsnprintf-posix.m4
+++ b/m4/vsnprintf-posix.m4
@@ -1,10 +1,22 @@
-# vsnprintf-posix.m4 serial 17
+# vsnprintf-posix.m4 serial 18
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VSNPRINTF_IS_POSIX])
+ if test $gl_cv_func_vsnprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VSNPRINTF
+ fi
+])
+
+dnl Test whether vsnprintf exists and is POSIX compliant.
+dnl Result is gl_cv_func_vsnprintf_posix.
+AC_DEFUN([gl_FUNC_VSNPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -119,21 +131,4 @@ AC_DEFUN([gl_FUNC_VSNPRINTF_POSIX]
;;
esac
fi
- if test $gl_cv_func_vsnprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_VSNPRINTF
- fi
])
diff --git a/modules/vsnprintf-gnu b/modules/vsnprintf-gnu
new file mode 100644
index 0000000000..36c4cbd586
--- /dev/null
+++ b/modules/vsnprintf-gnu
@@ -0,0 +1,29 @@
+Description:
+POSIX and GNU compatible vsnprintf() function: print formatted output to
+a fixed length string
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vsnprintf-gnu.m4
+
+Depends-on:
+vsnprintf-posix
+
+configure.ac:
+gl_FUNC_VSNPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #6: 0005-vsnprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 10114 bytes --]
From e396564a334c9467ea919068f58678ccdb821e72 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:06:44 +0100
Subject: [PATCH 05/31] vsnprintf-gnu: Add tests.
* tests/test-vsnprintf-gnu.c: New file, based on
tests/test-vsnprintf-posix.c.
* tests/test-snprintf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vsnprintf-gnu-tests: New file, based on
modules/vsnprintf-posix-tests.
---
ChangeLog | 8 ++
modules/vsnprintf-gnu-tests | 13 +++
tests/test-snprintf-gnu.h | 175 ++++++++++++++++++++++++++++++++++++
tests/test-vsnprintf-gnu.c | 48 ++++++++++
4 files changed, 244 insertions(+)
create mode 100644 modules/vsnprintf-gnu-tests
create mode 100644 tests/test-snprintf-gnu.h
create mode 100644 tests/test-vsnprintf-gnu.c
diff --git a/ChangeLog b/ChangeLog
index e152b9cd55..21b11ddca4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ vsnprintf-gnu: Add tests.
+ * tests/test-vsnprintf-gnu.c: New file, based on
+ tests/test-vsnprintf-posix.c.
+ * tests/test-snprintf-gnu.h: New file, based on
+ tests/test-vasnprintf-gnu.c.
+ * modules/vsnprintf-gnu-tests: New file, based on
+ modules/vsnprintf-posix-tests.
+
vsnprintf-gnu: New module.
* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VSNPRINTF_POSIX.
diff --git a/modules/vsnprintf-gnu-tests b/modules/vsnprintf-gnu-tests
new file mode 100644
index 0000000000..6749904cc6
--- /dev/null
+++ b/modules/vsnprintf-gnu-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-vsnprintf-gnu.c
+tests/test-snprintf-gnu.h
+tests/macros.h
+
+Depends-on:
+vsnprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vsnprintf-gnu
+check_PROGRAMS += test-vsnprintf-gnu
diff --git a/tests/test-snprintf-gnu.h b/tests/test-snprintf-gnu.h
new file mode 100644
index 0000000000..eda2c80334
--- /dev/null
+++ b/tests/test-snprintf-gnu.h
@@ -0,0 +1,175 @@
+/* Test of POSIX and GNU compatible vsnprintf() and snprintf() functions.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+static void
+test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
+{
+ char result[5000];
+
+ /* Test the support of the 'B' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%B %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A large positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%B %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width given as argument. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%*B %d", 20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ int retval =
+ my_snprintf (result, sizeof (result), "%*B %d", -20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a zero number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%.0B %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%25.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Padding and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%025.20B %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%-20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with zero. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#B %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0B11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0B11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0B000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0B00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#25.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0B00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%0#25.20B %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0B00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ int retval =
+ my_snprintf (result, sizeof (result), "%#.0B %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+}
diff --git a/tests/test-vsnprintf-gnu.c b/tests/test-vsnprintf-gnu.c
new file mode 100644
index 0000000000..420930f7d0
--- /dev/null
+++ b/tests/test-vsnprintf-gnu.c
@@ -0,0 +1,48 @@
+/* Test of POSIX and GNU compatible vsnprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-snprintf-gnu.h"
+
+static int
+my_snprintf (char *str, size_t size, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vsnprintf (str, size, format, args);
+ va_end (args);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (my_snprintf);
+ return 0;
+}
--
2.34.1
[-- Attachment #7: 0006-snprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6510 bytes --]
From f18c0053d6103e00ae6a0c954982b5ecd317536b Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:12:47 +0100
Subject: [PATCH 06/31] snprintf-gnu: New module.
* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_SNPRINTF_POSIX.
(gl_FUNC_SNPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/snprintf-gnu.m4: New file, based on m4/snprintf-posix.m4.
* modules/snprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/snprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/snprintf.texi | 13 ++++++++++---
m4/snprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/snprintf-posix.m4 | 31 +++++++++++++------------------
modules/snprintf-gnu | 29 +++++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 21 deletions(-)
create mode 100644 m4/snprintf-gnu.m4
create mode 100644 modules/snprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 21b11ddca4..1b5e632a96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ snprintf-gnu: New module.
+ * m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_SNPRINTF_POSIX.
+ (gl_FUNC_SNPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/snprintf-gnu.m4: New file, based on m4/snprintf-posix.m4.
+ * modules/snprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/snprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
vsnprintf-gnu: Add tests.
diff --git a/doc/posix-functions/snprintf.texi b/doc/posix-functions/snprintf.texi
index 9ea76cfa8b..a5a7550c7d 100644
--- a/doc/posix-functions/snprintf.texi
+++ b/doc/posix-functions/snprintf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html}
-Gnulib module: snprintf or snprintf-posix
+Gnulib module: snprintf or snprintf-posix or snprintf-gnu
-Portability problems fixed by either Gnulib module @code{snprintf} or @code{snprintf-posix}:
+Portability problems fixed by either Gnulib module @code{snprintf} or @code{snprintf-posix} or @code{snprintf-gnu}:
@itemize
@item
This function is missing on some platforms:
@@ -21,7 +21,7 @@
HP-UX 11, IRIX 6.5, Solaris 9, mingw.
@end itemize
-Portability problems fixed by Gnulib module @code{snprintf-posix}:
+Portability problems fixed by either Gnulib module @code{snprintf-posix} or @code{snprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -94,6 +94,13 @@
HP-UX 11, mingw, MSVC 14.
@end itemize
+Portability problems fixed by Gnulib module @code{snprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/snprintf-gnu.m4 b/m4/snprintf-gnu.m4
new file mode 100644
index 0000000000..cc3ab77c78
--- /dev/null
+++ b/m4/snprintf-gnu.m4
@@ -0,0 +1,25 @@
+# snprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_SNPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_SNPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_snprintf_gnu=no
+ if test $gl_cv_func_snprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # snprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_snprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_snprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_SNPRINTF
+ fi
+])
diff --git a/m4/snprintf-posix.m4 b/m4/snprintf-posix.m4
index 1a0147f3b6..303db27a84 100644
--- a/m4/snprintf-posix.m4
+++ b/m4/snprintf-posix.m4
@@ -1,10 +1,22 @@
-# snprintf-posix.m4 serial 16
+# snprintf-posix.m4 serial 17
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_SNPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_SNPRINTF_IS_POSIX])
+ if test $gl_cv_func_snprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_SNPRINTF
+ fi
+])
+
+dnl Test whether snprintf exists and is POSIX compliant.
+dnl Result is gl_cv_func_snprintf_posix.
+AC_DEFUN([gl_FUNC_SNPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -118,21 +130,4 @@ AC_DEFUN([gl_FUNC_SNPRINTF_POSIX]
;;
esac
fi
- if test $gl_cv_func_snprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_SNPRINTF
- fi
])
diff --git a/modules/snprintf-gnu b/modules/snprintf-gnu
new file mode 100644
index 0000000000..2850c16a34
--- /dev/null
+++ b/modules/snprintf-gnu
@@ -0,0 +1,29 @@
+Description:
+POSIX and GNU compatible snprintf() function: print formatted output to
+a fixed length string
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/snprintf-gnu.m4
+
+Depends-on:
+snprintf-posix
+
+configure.ac:
+gl_FUNC_SNPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #8: 0007-snprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 2791 bytes --]
From 0bba8aca9171f8b2e8835b0e2733541e8f119496 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:13:47 +0100
Subject: [PATCH 07/31] snprintf-gnu: Add tests.
* tests/test-snprintf-gnu.c: New file, based on
tests/test-snprintf-posix.c.
* modules/snprintf-gnu-tests: New file, based on
modules/snprintf-posix-tests.
---
ChangeLog | 6 ++++++
modules/snprintf-gnu-tests | 13 +++++++++++++
tests/test-snprintf-gnu.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+)
create mode 100644 modules/snprintf-gnu-tests
create mode 100644 tests/test-snprintf-gnu.c
diff --git a/ChangeLog b/ChangeLog
index 1b5e632a96..826526d567 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ snprintf-gnu: Add tests.
+ * tests/test-snprintf-gnu.c: New file, based on
+ tests/test-snprintf-posix.c.
+ * modules/snprintf-gnu-tests: New file, based on
+ modules/snprintf-posix-tests.
+
snprintf-gnu: New module.
* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_SNPRINTF_POSIX.
diff --git a/modules/snprintf-gnu-tests b/modules/snprintf-gnu-tests
new file mode 100644
index 0000000000..57ff66dc95
--- /dev/null
+++ b/modules/snprintf-gnu-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-snprintf-gnu.c
+tests/test-snprintf-gnu.h
+tests/macros.h
+
+Depends-on:
+snprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-snprintf-gnu
+check_PROGRAMS += test-snprintf-gnu
diff --git a/tests/test-snprintf-gnu.c b/tests/test-snprintf-gnu.c
new file mode 100644
index 0000000000..29f40cadfd
--- /dev/null
+++ b/tests/test-snprintf-gnu.c
@@ -0,0 +1,35 @@
+/* Test of POSIX and GNU compatible snprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-snprintf-gnu.h"
+
+int
+main (int argc, char *argv[])
+{
+ test_function (snprintf);
+ return 0;
+}
--
2.34.1
[-- Attachment #9: 0008-vsprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6093 bytes --]
From 21cb2b8ed03e0dd628c9be30734f563627a9b7e5 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:17:22 +0100
Subject: [PATCH 08/31] vsprintf-gnu: New module.
* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VSPRINTF_POSIX.
(gl_FUNC_VSPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vsprintf-gnu.m4: New file, based on m4/vsprintf-posix.m4.
* modules/vsprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vsprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/vsprintf.texi | 11 +++++++++--
m4/vsprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/vsprintf-posix.m4 | 31 +++++++++++++------------------
modules/vsprintf-gnu | 28 ++++++++++++++++++++++++++++
5 files changed, 86 insertions(+), 20 deletions(-)
create mode 100644 m4/vsprintf-gnu.m4
create mode 100644 modules/vsprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 826526d567..67b9dd7483 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ vsprintf-gnu: New module.
+ * m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_VSPRINTF_POSIX.
+ (gl_FUNC_VSPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/vsprintf-gnu.m4: New file, based on m4/vsprintf-posix.m4.
+ * modules/vsprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/vsprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
snprintf-gnu: Add tests.
diff --git a/doc/posix-functions/vsprintf.texi b/doc/posix-functions/vsprintf.texi
index 27ec5b9141..5ae3644e00 100644
--- a/doc/posix-functions/vsprintf.texi
+++ b/doc/posix-functions/vsprintf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/vsprintf.html}
-Gnulib module: vsprintf-posix
+Gnulib module: vsprintf-posix or vsprintf-gnu
-Portability problems fixed by Gnulib:
+Portability problems fixed by either Gnulib module @code{vsprintf-posix} or @code{vsprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -80,6 +80,13 @@
macOS 13.0.
@end itemize
+Portability problems fixed by Gnulib module @code{vsprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/vsprintf-gnu.m4 b/m4/vsprintf-gnu.m4
new file mode 100644
index 0000000000..4569e3599b
--- /dev/null
+++ b/m4/vsprintf-gnu.m4
@@ -0,0 +1,25 @@
+# vsprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VSPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VSPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vsprintf_gnu=no
+ if test $gl_cv_func_vsprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vsprintf is already POSIX compliant and GNU compatible.
+ gl_cv_func_vsprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vsprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VSPRINTF
+ fi
+])
diff --git a/m4/vsprintf-posix.m4 b/m4/vsprintf-posix.m4
index 94ef61e9dd..bc9e19f99a 100644
--- a/m4/vsprintf-posix.m4
+++ b/m4/vsprintf-posix.m4
@@ -1,10 +1,22 @@
-# vsprintf-posix.m4 serial 14
+# vsprintf-posix.m4 serial 15
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VSPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VSPRINTF_IS_POSIX])
+ if test $gl_cv_func_vsprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VSPRINTF
+ fi
+])
+
+dnl Test whether vsprintf is POSIX compliant.
+dnl Result is gl_cv_func_vsprintf_posix.
+AC_DEFUN([gl_FUNC_VSPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -90,23 +102,6 @@ AC_DEFUN([gl_FUNC_VSPRINTF_POSIX]
esac
;;
esac
- if test $gl_cv_func_vsprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_VSPRINTF
- fi
])
AC_DEFUN([gl_REPLACE_VSPRINTF],
diff --git a/modules/vsprintf-gnu b/modules/vsprintf-gnu
new file mode 100644
index 0000000000..d86b062e2e
--- /dev/null
+++ b/modules/vsprintf-gnu
@@ -0,0 +1,28 @@
+Description:
+POSIX and GNU compatible vsprintf() function: print formatted output to a string
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vsprintf-gnu.m4
+
+Depends-on:
+vsprintf-posix
+
+configure.ac:
+gl_FUNC_VSPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #10: 0009-vsprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 9683 bytes --]
From 63c2d4a0256c9c6927d9ccb18fdd7391ea10afcc Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:19:18 +0100
Subject: [PATCH 09/31] vsprintf-gnu: Add tests.
* tests/test-vsprintf-gnu.c: New file, based on
tests/test-vsprintf-posix.c.
* tests/test-sprintf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vsprintf-gnu-tests: New file, based on
modules/vsprintf-posix-tests.
---
ChangeLog | 8 ++
modules/vsprintf-gnu-tests | 13 +++
tests/test-sprintf-gnu.h | 175 +++++++++++++++++++++++++++++++++++++
tests/test-vsprintf-gnu.c | 48 ++++++++++
4 files changed, 244 insertions(+)
create mode 100644 modules/vsprintf-gnu-tests
create mode 100644 tests/test-sprintf-gnu.h
create mode 100644 tests/test-vsprintf-gnu.c
diff --git a/ChangeLog b/ChangeLog
index 67b9dd7483..385e6c4f17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ vsprintf-gnu: Add tests.
+ * tests/test-vsprintf-gnu.c: New file, based on
+ tests/test-vsprintf-posix.c.
+ * tests/test-sprintf-gnu.h: New file, based on
+ tests/test-vasnprintf-gnu.c.
+ * modules/vsprintf-gnu-tests: New file, based on
+ modules/vsprintf-posix-tests.
+
vsprintf-gnu: New module.
* m4/vsprintf-posix.m4 (gl_FUNC_VSPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VSPRINTF_POSIX.
diff --git a/modules/vsprintf-gnu-tests b/modules/vsprintf-gnu-tests
new file mode 100644
index 0000000000..86d3969d68
--- /dev/null
+++ b/modules/vsprintf-gnu-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-vsprintf-gnu.c
+tests/test-sprintf-gnu.h
+tests/macros.h
+
+Depends-on:
+vsprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vsprintf-gnu
+check_PROGRAMS += test-vsprintf-gnu
diff --git a/tests/test-sprintf-gnu.h b/tests/test-sprintf-gnu.h
new file mode 100644
index 0000000000..ff951f1bd5
--- /dev/null
+++ b/tests/test-sprintf-gnu.h
@@ -0,0 +1,175 @@
+/* Test of POSIX and GNU compatible vsprintf() and sprintf() functions.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+static void
+test_function (int (*my_sprintf) (char *, const char *, ...))
+{
+ char result[5000];
+
+ /* Test the support of the 'B' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ int retval =
+ my_sprintf (result, "%B %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A positive number. */
+ int retval =
+ my_sprintf (result, "%B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* A large positive number. */
+ int retval =
+ my_sprintf (result, "%B %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width. */
+ int retval =
+ my_sprintf (result, "%20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width given as argument. */
+ int retval =
+ my_sprintf (result, "%*B %d", 20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ int retval =
+ my_sprintf (result, "%*B %d", -20, 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Precision. */
+ int retval =
+ my_sprintf (result, "%.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a positive number. */
+ int retval =
+ my_sprintf (result, "%.0B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Zero precision and a zero number. */
+ int retval =
+ my_sprintf (result, "%.0B %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Width and precision. */
+ int retval =
+ my_sprintf (result, "%25.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* Padding and precision. */
+ int retval =
+ my_sprintf (result, "%025.20B %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_LEFT. */
+ int retval =
+ my_sprintf (result, "%-20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with zero. */
+ int retval =
+ my_sprintf (result, "%#B %d", 0, 33, 44, 55);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ int retval =
+ my_sprintf (result, "%#B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0B11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ int retval =
+ my_sprintf (result, "%#20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0B11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ int retval =
+ my_sprintf (result, "%0#20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0B000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ int retval =
+ my_sprintf (result, "%0#.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, "0B00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ int retval =
+ my_sprintf (result, "%#25.20B %d", 12345, 33, 44, 55);
+ ASSERT (strcmp (result, " 0B00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ int retval =
+ my_sprintf (result, "%0#25.20B %d", 12345, 33, 44, 55);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0B00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ int retval =
+ my_sprintf (result, "%#.0B %d", 0, 33, 44, 55);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ }
+}
diff --git a/tests/test-vsprintf-gnu.c b/tests/test-vsprintf-gnu.c
new file mode 100644
index 0000000000..d7782c097f
--- /dev/null
+++ b/tests/test-vsprintf-gnu.c
@@ -0,0 +1,48 @@
+/* Test of POSIX and GNU compatible vsprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-sprintf-gnu.h"
+
+static int
+my_sprintf (char *str, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vsprintf (str, format, args);
+ va_end (args);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (my_sprintf);
+ return 0;
+}
--
2.34.1
[-- Attachment #11: 0010-sprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6021 bytes --]
From 0139749ca02e6db4b42fe48363126efa52fbb44e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:22:20 +0100
Subject: [PATCH 10/31] sprintf-gnu: New module.
* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_SPRINTF_POSIX.
(gl_FUNC_SPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/sprintf-gnu.m4: New file, based on m4/sprintf-posix.m4.
* modules/sprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/sprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/sprintf.texi | 11 +++++++++--
m4/sprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/sprintf-posix.m4 | 31 +++++++++++++------------------
modules/sprintf-gnu | 28 ++++++++++++++++++++++++++++
5 files changed, 86 insertions(+), 20 deletions(-)
create mode 100644 m4/sprintf-gnu.m4
create mode 100644 modules/sprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 385e6c4f17..4656a575ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ sprintf-gnu: New module.
+ * m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_SPRINTF_POSIX.
+ (gl_FUNC_SPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/sprintf-gnu.m4: New file, based on m4/sprintf-posix.m4.
+ * modules/sprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/sprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
vsprintf-gnu: Add tests.
diff --git a/doc/posix-functions/sprintf.texi b/doc/posix-functions/sprintf.texi
index 57c42c294d..54816f26ab 100644
--- a/doc/posix-functions/sprintf.texi
+++ b/doc/posix-functions/sprintf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/sprintf.html}
-Gnulib module: sprintf-posix
+Gnulib module: sprintf-posix or sprintf-gnu
-Portability problems fixed by Gnulib:
+Portability problems fixed by either Gnulib module @code{sprintf-posix} or @code{sprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -80,6 +80,13 @@
macOS 13.0.
@end itemize
+Portability problems fixed by Gnulib module @code{sprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/sprintf-gnu.m4 b/m4/sprintf-gnu.m4
new file mode 100644
index 0000000000..963cfcf847
--- /dev/null
+++ b/m4/sprintf-gnu.m4
@@ -0,0 +1,25 @@
+# sprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_SPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_SPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_sprintf_gnu=no
+ if test $gl_cv_func_sprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # sprintf is already POSIX compliant and GNU compatible.
+ gl_cv_func_sprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_sprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_SPRINTF
+ fi
+])
diff --git a/m4/sprintf-posix.m4 b/m4/sprintf-posix.m4
index 96d0e0dacc..fe152d4eff 100644
--- a/m4/sprintf-posix.m4
+++ b/m4/sprintf-posix.m4
@@ -1,10 +1,22 @@
-# sprintf-posix.m4 serial 14
+# sprintf-posix.m4 serial 15
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_SPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_SPRINTF_IS_POSIX])
+ if test $gl_cv_func_sprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_SPRINTF
+ fi
+])
+
+dnl Test whether sprintf is POSIX compliant.
+dnl Result is gl_cv_func_sprintf_posix.
+AC_DEFUN([gl_FUNC_SPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -90,23 +102,6 @@ AC_DEFUN([gl_FUNC_SPRINTF_POSIX]
esac
;;
esac
- if test $gl_cv_func_sprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_SPRINTF
- fi
])
AC_DEFUN([gl_REPLACE_SPRINTF],
diff --git a/modules/sprintf-gnu b/modules/sprintf-gnu
new file mode 100644
index 0000000000..87daff3832
--- /dev/null
+++ b/modules/sprintf-gnu
@@ -0,0 +1,28 @@
+Description:
+POSIX and GNU compatible sprintf() function: print formatted output to a string
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/sprintf-gnu.m4
+
+Depends-on:
+sprintf-posix
+
+configure.ac:
+gl_FUNC_SPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #12: 0011-sprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 2758 bytes --]
From 20ba9bfff2e3970493ef0f2ad04d7635c3f44adf Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:23:51 +0100
Subject: [PATCH 11/31] sprintf-gnu: Add tests.
* tests/test-sprintf-gnu.c: New file, based on
tests/test-sprintf-posix.c.
* modules/sprintf-gnu-tests: New file, based on
modules/sprintf-posix-tests.
---
ChangeLog | 6 ++++++
modules/sprintf-gnu-tests | 13 +++++++++++++
tests/test-sprintf-gnu.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+)
create mode 100644 modules/sprintf-gnu-tests
create mode 100644 tests/test-sprintf-gnu.c
diff --git a/ChangeLog b/ChangeLog
index 4656a575ea..d9421f29bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ sprintf-gnu: Add tests.
+ * tests/test-sprintf-gnu.c: New file, based on
+ tests/test-sprintf-posix.c.
+ * modules/sprintf-gnu-tests: New file, based on
+ modules/sprintf-posix-tests.
+
sprintf-gnu: New module.
* m4/sprintf-posix.m4 (gl_FUNC_SPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_SPRINTF_POSIX.
diff --git a/modules/sprintf-gnu-tests b/modules/sprintf-gnu-tests
new file mode 100644
index 0000000000..90b9636fc5
--- /dev/null
+++ b/modules/sprintf-gnu-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-sprintf-gnu.c
+tests/test-sprintf-gnu.h
+tests/macros.h
+
+Depends-on:
+sprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-sprintf-gnu
+check_PROGRAMS += test-sprintf-gnu
diff --git a/tests/test-sprintf-gnu.c b/tests/test-sprintf-gnu.c
new file mode 100644
index 0000000000..cb22fb4fb4
--- /dev/null
+++ b/tests/test-sprintf-gnu.c
@@ -0,0 +1,35 @@
+/* Test of POSIX and GNU compatible sprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-sprintf-gnu.h"
+
+int
+main (int argc, char *argv[])
+{
+ test_function (sprintf);
+ return 0;
+}
--
2.34.1
[-- Attachment #13: 0012-vasprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 8173 bytes --]
From 891708e6f2a0d348660f45102958b27f5fce3c2c Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:28:38 +0100
Subject: [PATCH 12/31] vasprintf-gnu: New module.
* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VASPRINTF_POSIX.
(gl_FUNC_VASPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vasprintf-gnu.m4: New file, based on m4/vasprintf-posix.m4.
* modules/vasprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/glibc-functions/vasprintf.texi: Mention the new module.
* doc/glibc-functions/asprintf.texi: Likewise.
---
ChangeLog | 12 ++++++++++++
doc/glibc-functions/asprintf.texi | 13 ++++++++++---
doc/glibc-functions/vasprintf.texi | 13 ++++++++++---
m4/vasprintf-gnu.m4 | 25 ++++++++++++++++++++++++
m4/vasprintf-posix.m4 | 31 +++++++++++++-----------------
modules/vasprintf-gnu | 28 +++++++++++++++++++++++++++
6 files changed, 98 insertions(+), 24 deletions(-)
create mode 100644 m4/vasprintf-gnu.m4
create mode 100644 modules/vasprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index d9421f29bf..4810cf6291 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ vasprintf-gnu: New module.
+ * m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_VASPRINTF_POSIX.
+ (gl_FUNC_VASPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/vasprintf-gnu.m4: New file, based on m4/vasprintf-posix.m4.
+ * modules/vasprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/glibc-functions/vasprintf.texi: Mention the new module.
+ * doc/glibc-functions/asprintf.texi: Likewise.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
sprintf-gnu: Add tests.
diff --git a/doc/glibc-functions/asprintf.texi b/doc/glibc-functions/asprintf.texi
index 70de08dd1c..017220f66f 100644
--- a/doc/glibc-functions/asprintf.texi
+++ b/doc/glibc-functions/asprintf.texi
@@ -17,16 +17,16 @@
@uref{https://www.kernel.org/doc/man-pages/online/pages/man3/asprintf.3.html,,man asprintf}.
@end itemize
-Gnulib module: vasprintf or vasprintf-posix
+Gnulib module: vasprintf or vasprintf-posix or vasprintf-gnu
-Portability problems fixed by either Gnulib module @code{vasprintf} or @code{vasprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vasprintf} or @code{vasprintf-posix} or @code{vasprintf-gnu}:
@itemize
@item
This function is missing on some platforms:
AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 10, mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{vasprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vasprintf-posix} or @code{vasprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -79,6 +79,13 @@
FreeBSD 13.0, NetBSD 5.0.
@end itemize
+Portability problems fixed by Gnulib module @code{vasprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/doc/glibc-functions/vasprintf.texi b/doc/glibc-functions/vasprintf.texi
index ef1be6bb88..91cf7d5635 100644
--- a/doc/glibc-functions/vasprintf.texi
+++ b/doc/glibc-functions/vasprintf.texi
@@ -17,16 +17,16 @@
@uref{https://www.kernel.org/doc/man-pages/online/pages/man3/vasprintf.3.html,,man vasprintf}.
@end itemize
-Gnulib module: vasprintf or vasprintf-posix
+Gnulib module: vasprintf or vasprintf-posix or vasprintf-gnu
-Portability problems fixed by either Gnulib module @code{vasprintf} or @code{vasprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vasprintf} or @code{vasprintf-posix} or @code{vasprintf-gnu}:
@itemize
@item
This function is missing on some platforms:
AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 10, mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{vasprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vasprintf-posix} or @code{vasprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -79,6 +79,13 @@
FreeBSD 13.0, NetBSD 5.0.
@end itemize
+Portability problems fixed by Gnulib module @code{vasprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/vasprintf-gnu.m4 b/m4/vasprintf-gnu.m4
new file mode 100644
index 0000000000..be4e13be34
--- /dev/null
+++ b/m4/vasprintf-gnu.m4
@@ -0,0 +1,25 @@
+# vasprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VASPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VASPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vasprintf_gnu=no
+ if test $gl_cv_func_vasprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vasprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_vasprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vasprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VASPRINTF
+ fi
+])
diff --git a/m4/vasprintf-posix.m4 b/m4/vasprintf-posix.m4
index aa879de711..1be95c2f22 100644
--- a/m4/vasprintf-posix.m4
+++ b/m4/vasprintf-posix.m4
@@ -1,10 +1,22 @@
-# vasprintf-posix.m4 serial 15
+# vasprintf-posix.m4 serial 16
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VASPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VASPRINTF_IS_POSIX])
+ if test $gl_cv_func_vasprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VASPRINTF
+ fi
+])
+
+dnl Test whether vasprintf exists and is POSIX compliant.
+dnl Result is gl_cv_func_vasprintf_posix.
+AC_DEFUN([gl_FUNC_VASPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -93,21 +105,4 @@ AC_DEFUN([gl_FUNC_VASPRINTF_POSIX]
esac
;;
esac
- if test $gl_cv_func_vasprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_VASPRINTF
- fi
])
diff --git a/modules/vasprintf-gnu b/modules/vasprintf-gnu
new file mode 100644
index 0000000000..9635b10f84
--- /dev/null
+++ b/modules/vasprintf-gnu
@@ -0,0 +1,28 @@
+Description:
+POSIX and GNU compatible vsprintf with automatic memory allocation.
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vasprintf-gnu.m4
+
+Depends-on:
+vasprintf-posix
+
+configure.ac:
+gl_FUNC_VASPRINTF_GNU
+
+Makefile.am:
+
+Include:
+"vasprintf.h"
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #14: 0013-vasprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 10015 bytes --]
From fa8e2b3669b60f3e316ac7d0fd638e19d960672f Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:29:58 +0100
Subject: [PATCH 13/31] vasprintf-gnu: Add tests.
* tests/test-vasprintf-gnu.c: New file, based on
tests/test-vasprintf-posix.c and tests/test-vasnprintf-gnu.c.
* modules/vasprintf-gnu-tests: New file, based on
modules/vasprintf-posix-tests.
---
ChangeLog | 6 +
modules/vasprintf-gnu-tests | 12 ++
tests/test-vasprintf-gnu.c | 275 ++++++++++++++++++++++++++++++++++++
3 files changed, 293 insertions(+)
create mode 100644 modules/vasprintf-gnu-tests
create mode 100644 tests/test-vasprintf-gnu.c
diff --git a/ChangeLog b/ChangeLog
index 4810cf6291..6ab03e83a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ vasprintf-gnu: Add tests.
+ * tests/test-vasprintf-gnu.c: New file, based on
+ tests/test-vasprintf-posix.c and tests/test-vasnprintf-gnu.c.
+ * modules/vasprintf-gnu-tests: New file, based on
+ modules/vasprintf-posix-tests.
+
vasprintf-gnu: New module.
* m4/vasprintf-posix.m4 (gl_FUNC_VASPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VASPRINTF_POSIX.
diff --git a/modules/vasprintf-gnu-tests b/modules/vasprintf-gnu-tests
new file mode 100644
index 0000000000..5dc0974d04
--- /dev/null
+++ b/modules/vasprintf-gnu-tests
@@ -0,0 +1,12 @@
+Files:
+tests/test-vasprintf-gnu.c
+tests/macros.h
+
+Depends-on:
+vasprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vasprintf-gnu
+check_PROGRAMS += test-vasprintf-gnu
diff --git a/tests/test-vasprintf-gnu.c b/tests/test-vasprintf-gnu.c
new file mode 100644
index 0000000000..f039515b72
--- /dev/null
+++ b/tests/test-vasprintf-gnu.c
@@ -0,0 +1,275 @@
+/* Test of POSIX and GNU compatible vasprintf() and asprintf() functions.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+
+static void
+test_function (int (*my_asprintf) (char **, const char *, ...))
+{
+ /* Test the support of the 'b' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%b %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11111111111111111111111111111110 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%*b %d", 20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%*b %d", -20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%025.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%-20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0b11000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0b000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%0#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (strcmp (result, " 0b00000011000000111001 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%#.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (strcmp (result, " 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+}
+
+static int
+my_asprintf (char **result, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vasprintf (result, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_vasprintf ()
+{
+ test_function (my_asprintf);
+}
+
+static void
+test_asprintf ()
+{
+ test_function (asprintf);
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasprintf ();
+ test_asprintf ();
+ return 0;
+}
--
2.34.1
[-- Attachment #15: 0014-vfprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6918 bytes --]
From 3968e4d4f1b2ad9afb1ff162509d0abf0dc22d2d Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:35:26 +0100
Subject: [PATCH 14/31] vfprintf-gnu: New module.
* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VFPRINTF_POSIX.
(gl_FUNC_VFPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vfprintf-gnu.m4: New file, based on m4/vfprintf-posix.m4.
* modules/vfprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vfprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/vfprintf.texi | 15 +++++++++++----
m4/vfprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/vfprintf-posix.m4 | 31 +++++++++++++------------------
modules/vfprintf-gnu | 28 ++++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 22 deletions(-)
create mode 100644 m4/vfprintf-gnu.m4
create mode 100644 modules/vfprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 6ab03e83a1..e5af17568f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ vfprintf-gnu: New module.
+ * m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_VFPRINTF_POSIX.
+ (gl_FUNC_VFPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/vfprintf-gnu.m4: New file, based on m4/vfprintf-posix.m4.
+ * modules/vfprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/vfprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
vasprintf-gnu: Add tests.
diff --git a/doc/posix-functions/vfprintf.texi b/doc/posix-functions/vfprintf.texi
index 252ac10e2b..719bba0698 100644
--- a/doc/posix-functions/vfprintf.texi
+++ b/doc/posix-functions/vfprintf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/vfprintf.html}
-Gnulib module: vfprintf-posix or stdio, nonblocking, sigpipe
+Gnulib module: vfprintf-posix or vfprintf-gnu or stdio, nonblocking, sigpipe
-Portability problems fixed by Gnulib module @code{vfprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vfprintf-posix} or @code{vfprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -77,7 +77,14 @@
FreeBSD 13.0, NetBSD 5.0.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{vfprintf-posix}, together with module @code{nonblocking}:
+Portability problems fixed by Gnulib module @code{vfprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
+Portability problems fixed by Gnulib module @code{stdio} or @code{vfprintf-posix} or @code{vfprintf-gnu}, together with module @code{nonblocking}:
@itemize
@item
When writing to a non-blocking pipe whose buffer is full, this function fails
@@ -86,7 +93,7 @@
mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{vfprintf-posix}, together with module @code{sigpipe}:
+Portability problems fixed by Gnulib module @code{stdio} or @code{vfprintf-posix} or @code{vfprintf-gnu}, together with module @code{sigpipe}:
@itemize
@item
When writing to a pipe with no readers, this function fails, instead of
diff --git a/m4/vfprintf-gnu.m4 b/m4/vfprintf-gnu.m4
new file mode 100644
index 0000000000..bb60781c17
--- /dev/null
+++ b/m4/vfprintf-gnu.m4
@@ -0,0 +1,25 @@
+# vfprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VFPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VFPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vfprintf_gnu=no
+ if test $gl_cv_func_vfprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vfprintf is already POSIX compliant and GNU compatible.
+ gl_cv_func_vfprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vfprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VFPRINTF
+ fi
+])
diff --git a/m4/vfprintf-posix.m4 b/m4/vfprintf-posix.m4
index f248292cc4..f7e97a862a 100644
--- a/m4/vfprintf-posix.m4
+++ b/m4/vfprintf-posix.m4
@@ -1,10 +1,22 @@
-# vfprintf-posix.m4 serial 16
+# vfprintf-posix.m4 serial 17
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VFPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VFPRINTF_IS_POSIX])
+ if test $gl_cv_func_vfprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VFPRINTF
+ fi
+])
+
+dnl Test whether vfprintf is POSIX compliant.
+dnl Result is gl_cv_func_vfprintf_posix.
+AC_DEFUN([gl_FUNC_VFPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -90,23 +102,6 @@ AC_DEFUN([gl_FUNC_VFPRINTF_POSIX]
esac
;;
esac
- if test $gl_cv_func_vfprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_VFPRINTF
- fi
])
AC_DEFUN([gl_REPLACE_VFPRINTF],
diff --git a/modules/vfprintf-gnu b/modules/vfprintf-gnu
new file mode 100644
index 0000000000..71a8c82d3b
--- /dev/null
+++ b/modules/vfprintf-gnu
@@ -0,0 +1,28 @@
+Description:
+POSIX and GNU compatible vfprintf() function: print formatted output to a stream
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vfprintf-gnu.m4
+
+Depends-on:
+vfprintf-posix
+
+configure.ac:
+gl_FUNC_VFPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #16: 0015-vfprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 8132 bytes --]
From dc8fb6206a8eb11243b538981c969ec2fe9aa375 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:36:53 +0100
Subject: [PATCH 15/31] vfprintf-gnu: Add tests.
* tests/test-vfprintf-gnu.sh: New file, based on
tests/test-vfprintf-posix.sh.
* tests/test-vfprintf-gnu.c: New file, based on
tests/test-vfprintf-posix.c.
* tests/test-fprintf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* tests/test-printf-gnu.output: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vfprintf-gnu-tests: New file, based on
modules/vfprintf-posix-tests.
---
ChangeLog | 12 ++++++
modules/vfprintf-gnu-tests | 15 +++++++
tests/test-fprintf-gnu.h | 81 ++++++++++++++++++++++++++++++++++++
tests/test-printf-gnu.output | 18 ++++++++
tests/test-vfprintf-gnu.c | 48 +++++++++++++++++++++
tests/test-vfprintf-gnu.sh | 16 +++++++
6 files changed, 190 insertions(+)
create mode 100644 modules/vfprintf-gnu-tests
create mode 100644 tests/test-fprintf-gnu.h
create mode 100644 tests/test-printf-gnu.output
create mode 100644 tests/test-vfprintf-gnu.c
create mode 100755 tests/test-vfprintf-gnu.sh
diff --git a/ChangeLog b/ChangeLog
index e5af17568f..46d1665f2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ vfprintf-gnu: Add tests.
+ * tests/test-vfprintf-gnu.sh: New file, based on
+ tests/test-vfprintf-posix.sh.
+ * tests/test-vfprintf-gnu.c: New file, based on
+ tests/test-vfprintf-posix.c.
+ * tests/test-fprintf-gnu.h: New file, based on
+ tests/test-vasnprintf-gnu.c.
+ * tests/test-printf-gnu.output: New file, based on
+ tests/test-vasnprintf-gnu.c.
+ * modules/vfprintf-gnu-tests: New file, based on
+ modules/vfprintf-posix-tests.
+
vfprintf-gnu: New module.
* m4/vfprintf-posix.m4 (gl_FUNC_VFPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VFPRINTF_POSIX.
diff --git a/modules/vfprintf-gnu-tests b/modules/vfprintf-gnu-tests
new file mode 100644
index 0000000000..a8ca45be68
--- /dev/null
+++ b/modules/vfprintf-gnu-tests
@@ -0,0 +1,15 @@
+Files:
+tests/test-vfprintf-gnu.sh
+tests/test-vfprintf-gnu.c
+tests/test-fprintf-gnu.h
+tests/test-printf-gnu.output
+tests/macros.h
+
+Depends-on:
+vfprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vfprintf-gnu.sh
+check_PROGRAMS += test-vfprintf-gnu
diff --git a/tests/test-fprintf-gnu.h b/tests/test-fprintf-gnu.h
new file mode 100644
index 0000000000..a535273e55
--- /dev/null
+++ b/tests/test-fprintf-gnu.h
@@ -0,0 +1,81 @@
+/* Test of POSIX and GNU compatible vsprintf() and sprintf() functions.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+static void
+test_function (int (*my_fprintf) (FILE *, const char *, ...))
+{
+ /* Here we don't test output that may be platform dependent.
+ The bulk of the tests is done as part of the 'vasnprintf-posix' module. */
+
+ /* Test the support of the 'B' conversion specifier for binary output of
+ integers. */
+
+ /* Zero. */
+ my_fprintf (stdout, "%B %d\n", 0, 33, 44, 55);
+
+ /* A positive number. */
+ my_fprintf (stdout, "%B %d\n", 12345, 33, 44, 55);
+
+ /* A large positive number. */
+ my_fprintf (stdout, "%B %d\n", 0xFFFFFFFEU, 33, 44, 55);
+
+ /* Width. */
+ my_fprintf (stdout, "%20B %d\n", 12345, 33, 44, 55);
+
+ /* Width given as argument. */
+ my_fprintf (stdout, "%*B %d\n", 20, 12345, 33, 44, 55);
+
+ /* Negative width given as argument (cf. FLAG_LEFT below). */
+ my_fprintf (stdout, "%*B %d\n", -20, 12345, 33, 44, 55);
+
+ /* Precision. */
+ my_fprintf (stdout, "%.20B %d\n", 12345, 33, 44, 55);
+
+ /* Zero precision and a positive number. */
+ my_fprintf (stdout, "%.0B %d\n", 12345, 33, 44, 55);
+
+ /* Zero precision and a zero number. */
+ my_fprintf (stdout, "%.0B %d\n", 0, 33, 44, 55);
+
+ /* Width and precision. */
+ my_fprintf (stdout, "%25.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_LEFT. */
+ my_fprintf (stdout, "%-20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with zero. */
+ my_fprintf (stdout, "%#B %d\n", 0, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number. */
+ my_fprintf (stdout, "%#B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and width. */
+ my_fprintf (stdout, "%#20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and padding. */
+ my_fprintf (stdout, "%0#20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and precision. */
+ my_fprintf (stdout, "%0#.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and width and precision. */
+ my_fprintf (stdout, "%#25.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a zero precision and a zero number. */
+ my_fprintf (stdout, "%#.0B %d\n", 0, 33, 44, 55);
+}
diff --git a/tests/test-printf-gnu.output b/tests/test-printf-gnu.output
new file mode 100644
index 0000000000..99586c3ae1
--- /dev/null
+++ b/tests/test-printf-gnu.output
@@ -0,0 +1,18 @@
+0 33
+11000000111001 33
+11111111111111111111111111111110 33
+ 11000000111001 33
+ 11000000111001 33
+11000000111001 33
+00000011000000111001 33
+11000000111001 33
+ 33
+ 00000011000000111001 33
+11000000111001 33
+0 33
+0B11000000111001 33
+ 0B11000000111001 33
+0B000011000000111001 33
+0B00000011000000111001 33
+ 0B00000011000000111001 33
+ 33
diff --git a/tests/test-vfprintf-gnu.c b/tests/test-vfprintf-gnu.c
new file mode 100644
index 0000000000..fb964159b9
--- /dev/null
+++ b/tests/test-vfprintf-gnu.c
@@ -0,0 +1,48 @@
+/* Test of POSIX and GNU compatible vfprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-fprintf-gnu.h"
+
+static int
+my_fprintf (FILE *fp, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vfprintf (fp, format, args);
+ va_end (args);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (my_fprintf);
+ return 0;
+}
diff --git a/tests/test-vfprintf-gnu.sh b/tests/test-vfprintf-gnu.sh
new file mode 100755
index 0000000000..a61beeffb5
--- /dev/null
+++ b/tests/test-vfprintf-gnu.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' HUP INT QUIT TERM
+
+tmpfiles="$tmpfiles t-vfprintf-gnu.tmp t-vfprintf-gnu.out"
+${CHECKER} ./test-vfprintf-gnu${EXEEXT} > t-vfprintf-gnu.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-vfprintf-gnu.tmp > t-vfprintf-gnu.out || exit 1
+
+: "${DIFF=diff}"
+${DIFF} "${srcdir}/test-printf-gnu.output" t-vfprintf-gnu.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
--
2.34.1
[-- Attachment #17: 0016-fprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6838 bytes --]
From 005377bde6a0a65271754752f8e5e89a51ca53a9 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:39:47 +0100
Subject: [PATCH 16/31] fprintf-gnu: New module.
* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_FPRINTF_POSIX.
(gl_FUNC_FPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/fprintf-gnu.m4: New file, based on m4/fprintf-posix.m4.
* modules/fprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/fprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/fprintf.texi | 15 +++++++++++----
m4/fprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/fprintf-posix.m4 | 31 +++++++++++++------------------
modules/fprintf-gnu | 28 ++++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 22 deletions(-)
create mode 100644 m4/fprintf-gnu.m4
create mode 100644 modules/fprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 46d1665f2b..07ef028cff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ fprintf-gnu: New module.
+ * m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_FPRINTF_POSIX.
+ (gl_FUNC_FPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/fprintf-gnu.m4: New file, based on m4/fprintf-posix.m4.
+ * modules/fprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/fprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
vfprintf-gnu: Add tests.
diff --git a/doc/posix-functions/fprintf.texi b/doc/posix-functions/fprintf.texi
index 513777c0a4..3ee74b41ae 100644
--- a/doc/posix-functions/fprintf.texi
+++ b/doc/posix-functions/fprintf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html}
-Gnulib module: fprintf-posix or stdio, nonblocking, sigpipe
+Gnulib module: fprintf-posix or fprintf-gnu or stdio, nonblocking, sigpipe
-Portability problems fixed by Gnulib module @code{fprintf-posix}:
+Portability problems fixed by either Gnulib module @code{fprintf-posix} or @code{fprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -77,7 +77,14 @@
FreeBSD 13.0, NetBSD 5.0.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{fprintf-posix}, together with module @code{nonblocking}:
+Portability problems fixed by Gnulib module @code{fprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
+Portability problems fixed by Gnulib module @code{stdio} or @code{fprintf-posix} or @code{fprintf-gnu}, together with module @code{nonblocking}:
@itemize
@item
When writing to a non-blocking pipe whose buffer is full, this function fails
@@ -86,7 +93,7 @@
mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{fprintf-posix}, together with module @code{sigpipe}:
+Portability problems fixed by Gnulib module @code{stdio} or @code{fprintf-posix} or @code{fprintf-gnu}, together with module @code{sigpipe}:
@itemize
@item
When writing to a pipe with no readers, this function fails, instead of
diff --git a/m4/fprintf-gnu.m4 b/m4/fprintf-gnu.m4
new file mode 100644
index 0000000000..b1a32ce188
--- /dev/null
+++ b/m4/fprintf-gnu.m4
@@ -0,0 +1,25 @@
+# fprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_FPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_FPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_fprintf_gnu=no
+ if test $gl_cv_func_fprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # fprintf is already POSIX compliant and GNU compatible.
+ gl_cv_func_fprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_fprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_FPRINTF
+ fi
+])
diff --git a/m4/fprintf-posix.m4 b/m4/fprintf-posix.m4
index 1eb669fd5d..4d016c4fc5 100644
--- a/m4/fprintf-posix.m4
+++ b/m4/fprintf-posix.m4
@@ -1,10 +1,22 @@
-# fprintf-posix.m4 serial 16
+# fprintf-posix.m4 serial 17
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_FPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_FPRINTF_IS_POSIX])
+ if test $gl_cv_func_fprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_FPRINTF
+ fi
+])
+
+dnl Test whether fprintf is POSIX compliant.
+dnl Result is gl_cv_func_fprintf_posix.
+AC_DEFUN([gl_FUNC_FPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -90,23 +102,6 @@ AC_DEFUN([gl_FUNC_FPRINTF_POSIX]
esac
;;
esac
- if test $gl_cv_func_fprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_FPRINTF
- fi
])
AC_DEFUN([gl_REPLACE_FPRINTF],
diff --git a/modules/fprintf-gnu b/modules/fprintf-gnu
new file mode 100644
index 0000000000..fce7578459
--- /dev/null
+++ b/modules/fprintf-gnu
@@ -0,0 +1,28 @@
+Description:
+POSIX and GNU compatible fprintf() function: print formatted output to a stream
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/fprintf-gnu.m4
+
+Depends-on:
+fprintf-posix
+
+configure.ac:
+gl_FUNC_FPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #18: 0017-fprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 3676 bytes --]
From d00bce3996ec46b0c4ad1690c1d153b9101d2239 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:41:10 +0100
Subject: [PATCH 17/31] fprintf-gnu: Add tests.
* tests/test-fprintf-gnu.sh: New file, based on
tests/test-fprintf-posix.sh.
* tests/test-fprintf-gnu.c: New file, based on
tests/test-fprintf-posix.c.
* modules/fprintf-gnu-tests: New file, based on
modules/fprintf-posix-tests.
---
ChangeLog | 8 ++++++++
modules/fprintf-gnu-tests | 15 +++++++++++++++
tests/test-fprintf-gnu.c | 36 ++++++++++++++++++++++++++++++++++++
tests/test-fprintf-gnu.sh | 16 ++++++++++++++++
4 files changed, 75 insertions(+)
create mode 100644 modules/fprintf-gnu-tests
create mode 100644 tests/test-fprintf-gnu.c
create mode 100755 tests/test-fprintf-gnu.sh
diff --git a/ChangeLog b/ChangeLog
index 07ef028cff..54de6d019e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ fprintf-gnu: Add tests.
+ * tests/test-fprintf-gnu.sh: New file, based on
+ tests/test-fprintf-posix.sh.
+ * tests/test-fprintf-gnu.c: New file, based on
+ tests/test-fprintf-posix.c.
+ * modules/fprintf-gnu-tests: New file, based on
+ modules/fprintf-posix-tests.
+
fprintf-gnu: New module.
* m4/fprintf-posix.m4 (gl_FUNC_FPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_FPRINTF_POSIX.
diff --git a/modules/fprintf-gnu-tests b/modules/fprintf-gnu-tests
new file mode 100644
index 0000000000..383e5b6426
--- /dev/null
+++ b/modules/fprintf-gnu-tests
@@ -0,0 +1,15 @@
+Files:
+tests/test-fprintf-gnu.sh
+tests/test-fprintf-gnu.c
+tests/test-fprintf-gnu.h
+tests/test-printf-gnu.output
+tests/macros.h
+
+Depends-on:
+fprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-fprintf-gnu.sh
+check_PROGRAMS += test-fprintf-gnu
diff --git a/tests/test-fprintf-gnu.c b/tests/test-fprintf-gnu.c
new file mode 100644
index 0000000000..08def42d82
--- /dev/null
+++ b/tests/test-fprintf-gnu.c
@@ -0,0 +1,36 @@
+/* Test of POSIX and GNU compatible fprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-fprintf-gnu.h"
+
+int
+main (int argc, char *argv[])
+{
+ test_function (fprintf);
+ return 0;
+}
diff --git a/tests/test-fprintf-gnu.sh b/tests/test-fprintf-gnu.sh
new file mode 100755
index 0000000000..346f13c010
--- /dev/null
+++ b/tests/test-fprintf-gnu.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' HUP INT QUIT TERM
+
+tmpfiles="$tmpfiles t-fprintf-gnu.tmp t-fprintf-gnu.out"
+${CHECKER} ./test-fprintf-gnu${EXEEXT} > t-fprintf-gnu.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-fprintf-gnu.tmp > t-fprintf-gnu.out || exit 1
+
+: "${DIFF=diff}"
+${DIFF} "${srcdir}/test-printf-gnu.output" t-fprintf-gnu.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
--
2.34.1
[-- Attachment #19: 0018-vprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6295 bytes --]
From 9b58230c21b08eec75539978269668e0213f4608 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:46:24 +0100
Subject: [PATCH 18/31] vprintf-gnu: New module.
* m4/vprintf-posix.m4 (gl_FUNC_VPRINTF_IS_POSIX): New macro.
(gl_FUNC_VPRINTF_POSIX): Require it. Don't require
gl_FUNC_VFPRINTF_POSIX. Invoke gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
and gl_REPLACE_VASNPRINTF.
* m4/vprintf-gnu.m4: New file, based on m4/vfprintf-posix.m4.
* modules/vprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/vprintf.texi | 15 +++++++++++----
m4/vprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/vprintf-posix.m4 | 16 +++++++++++++---
modules/vprintf-gnu | 29 +++++++++++++++++++++++++++++
5 files changed, 89 insertions(+), 7 deletions(-)
create mode 100644 m4/vprintf-gnu.m4
create mode 100644 modules/vprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 54de6d019e..8b6d0f41ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ vprintf-gnu: New module.
+ * m4/vprintf-posix.m4 (gl_FUNC_VPRINTF_IS_POSIX): New macro.
+ (gl_FUNC_VPRINTF_POSIX): Require it. Don't require
+ gl_FUNC_VFPRINTF_POSIX. Invoke gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ and gl_REPLACE_VASNPRINTF.
+ * m4/vprintf-gnu.m4: New file, based on m4/vfprintf-posix.m4.
+ * modules/vprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/vprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
fprintf-gnu: Add tests.
diff --git a/doc/posix-functions/vprintf.texi b/doc/posix-functions/vprintf.texi
index 8272e50fd9..051aef880d 100644
--- a/doc/posix-functions/vprintf.texi
+++ b/doc/posix-functions/vprintf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/vprintf.html}
-Gnulib module: vprintf-posix or stdio, nonblocking, sigpipe
+Gnulib module: vprintf-posix or vprintf-gnu or stdio, nonblocking, sigpipe
-Portability problems fixed by Gnulib module @code{vprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vprintf-posix} or @code{vprintf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -77,7 +77,14 @@
FreeBSD 13.0, NetBSD 5.0.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{vprintf-posix}, together with module @code{nonblocking}:
+Portability problems fixed by Gnulib module @code{vprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
+Portability problems fixed by Gnulib module @code{stdio} or @code{vprintf-posix} or @code{vprintf-gnu}, together with module @code{nonblocking}:
@itemize
@item
When writing to a non-blocking pipe whose buffer is full, this function fails
@@ -86,7 +93,7 @@
mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{vprintf-posix}, together with module @code{sigpipe}:
+Portability problems fixed by Gnulib module @code{stdio} or @code{vprintf-posix} or @code{vprintf-gnu}, together with module @code{sigpipe}:
@itemize
@item
When writing to a pipe with no readers, this function fails, instead of
diff --git a/m4/vprintf-gnu.m4 b/m4/vprintf-gnu.m4
new file mode 100644
index 0000000000..4e30a77712
--- /dev/null
+++ b/m4/vprintf-gnu.m4
@@ -0,0 +1,25 @@
+# vprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vprintf_gnu=no
+ if test $gl_cv_func_vprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_vprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VPRINTF
+ fi
+])
diff --git a/m4/vprintf-posix.m4 b/m4/vprintf-posix.m4
index b25d326bf8..9161c70f90 100644
--- a/m4/vprintf-posix.m4
+++ b/m4/vprintf-posix.m4
@@ -1,4 +1,4 @@
-# vprintf-posix.m4 serial 3
+# vprintf-posix.m4 serial 4
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,12 +6,22 @@
AC_DEFUN([gl_FUNC_VPRINTF_POSIX],
[
- AC_REQUIRE([gl_FUNC_VFPRINTF_POSIX])
- if test $gl_cv_func_vfprintf_posix = no; then
+ AC_REQUIRE([gl_FUNC_VPRINTF_IS_POSIX])
+ if test $gl_cv_func_vprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
gl_REPLACE_VPRINTF
fi
])
+dnl Test whether vprintf is POSIX compliant.
+dnl Result is gl_cv_func_vprintf_posix.
+AC_DEFUN([gl_FUNC_VPRINTF_IS_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VFPRINTF_IS_POSIX])
+ gl_cv_func_vprintf_posix="$gl_cv_func_vfprintf_posix"
+])
+
AC_DEFUN([gl_REPLACE_VPRINTF],
[
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
diff --git a/modules/vprintf-gnu b/modules/vprintf-gnu
new file mode 100644
index 0000000000..0fbefc85ba
--- /dev/null
+++ b/modules/vprintf-gnu
@@ -0,0 +1,29 @@
+Description:
+POSIX and GNU compatible vprintf() function: print formatted output to
+standard output
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vprintf-gnu.m4
+
+Depends-on:
+vprintf-posix
+
+configure.ac:
+gl_FUNC_VPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #20: 0019-vprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 7072 bytes --]
From 57e16895ad2925f394c2244efa6660bc72c8c3fe Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:47:20 +0100
Subject: [PATCH 19/31] vprintf-gnu: Add tests.
* tests/test-vprintf-gnu.sh: New file, based on
tests/test-vprintf-posix.sh.
* tests/test-vprintf-gnu.c: New file, based on
tests/test-vprintf-posix.c.
* tests/test-printf-gnu.h: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/vprintf-gnu-tests: New file, based on
modules/vprintf-posix-tests.
---
ChangeLog | 10 +++++
modules/vprintf-gnu-tests | 15 ++++++++
tests/test-printf-gnu.h | 81 +++++++++++++++++++++++++++++++++++++++
tests/test-vprintf-gnu.c | 48 +++++++++++++++++++++++
tests/test-vprintf-gnu.sh | 16 ++++++++
5 files changed, 170 insertions(+)
create mode 100644 modules/vprintf-gnu-tests
create mode 100644 tests/test-printf-gnu.h
create mode 100644 tests/test-vprintf-gnu.c
create mode 100755 tests/test-vprintf-gnu.sh
diff --git a/ChangeLog b/ChangeLog
index 8b6d0f41ec..aa826b376a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ vprintf-gnu: Add tests.
+ * tests/test-vprintf-gnu.sh: New file, based on
+ tests/test-vprintf-posix.sh.
+ * tests/test-vprintf-gnu.c: New file, based on
+ tests/test-vprintf-posix.c.
+ * tests/test-printf-gnu.h: New file, based on
+ tests/test-vasnprintf-gnu.c.
+ * modules/vprintf-gnu-tests: New file, based on
+ modules/vprintf-posix-tests.
+
vprintf-gnu: New module.
* m4/vprintf-posix.m4 (gl_FUNC_VPRINTF_IS_POSIX): New macro.
(gl_FUNC_VPRINTF_POSIX): Require it. Don't require
diff --git a/modules/vprintf-gnu-tests b/modules/vprintf-gnu-tests
new file mode 100644
index 0000000000..4b3132180b
--- /dev/null
+++ b/modules/vprintf-gnu-tests
@@ -0,0 +1,15 @@
+Files:
+tests/test-vprintf-gnu.sh
+tests/test-vprintf-gnu.c
+tests/test-printf-gnu.h
+tests/test-printf-gnu.output
+tests/macros.h
+
+Depends-on:
+vprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vprintf-gnu.sh
+check_PROGRAMS += test-vprintf-gnu
diff --git a/tests/test-printf-gnu.h b/tests/test-printf-gnu.h
new file mode 100644
index 0000000000..d42a1bf22a
--- /dev/null
+++ b/tests/test-printf-gnu.h
@@ -0,0 +1,81 @@
+/* Test of POSIX and GNU compatible vsprintf() and sprintf() functions.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+static void
+test_function (int (*my_printf) (const char *, ...))
+{
+ /* Here we don't test output that may be platform dependent.
+ The bulk of the tests is done as part of the 'vasnprintf-posix' module. */
+
+ /* Test the support of the 'B' conversion specifier for binary output of
+ integers. */
+
+ /* Zero. */
+ my_printf ("%B %d\n", 0, 33, 44, 55);
+
+ /* A positive number. */
+ my_printf ("%B %d\n", 12345, 33, 44, 55);
+
+ /* A large positive number. */
+ my_printf ("%B %d\n", 0xFFFFFFFEU, 33, 44, 55);
+
+ /* Width. */
+ my_printf ("%20B %d\n", 12345, 33, 44, 55);
+
+ /* Width given as argument. */
+ my_printf ("%*B %d\n", 20, 12345, 33, 44, 55);
+
+ /* Negative width given as argument (cf. FLAG_LEFT below). */
+ my_printf ("%*B %d\n", -20, 12345, 33, 44, 55);
+
+ /* Precision. */
+ my_printf ("%.20B %d\n", 12345, 33, 44, 55);
+
+ /* Zero precision and a positive number. */
+ my_printf ("%.0B %d\n", 12345, 33, 44, 55);
+
+ /* Zero precision and a zero number. */
+ my_printf ("%.0B %d\n", 0, 33, 44, 55);
+
+ /* Width and precision. */
+ my_printf ("%25.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_LEFT. */
+ my_printf ("%-20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with zero. */
+ my_printf ("%#B %d\n", 0, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number. */
+ my_printf ("%#B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and width. */
+ my_printf ("%#20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and padding. */
+ my_printf ("%0#20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and precision. */
+ my_printf ("%0#.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and width and precision. */
+ my_printf ("%#25.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a zero precision and a zero number. */
+ my_printf ("%#.0B %d\n", 0, 33, 44, 55);
+}
diff --git a/tests/test-vprintf-gnu.c b/tests/test-vprintf-gnu.c
new file mode 100644
index 0000000000..d6cf8655f4
--- /dev/null
+++ b/tests/test-vprintf-gnu.c
@@ -0,0 +1,48 @@
+/* Test of POSIX and GNU compatible vfprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-printf-gnu.h"
+
+static int
+my_printf (const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vprintf (format, args);
+ va_end (args);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (my_printf);
+ return 0;
+}
diff --git a/tests/test-vprintf-gnu.sh b/tests/test-vprintf-gnu.sh
new file mode 100755
index 0000000000..47da3e673c
--- /dev/null
+++ b/tests/test-vprintf-gnu.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' HUP INT QUIT TERM
+
+tmpfiles="$tmpfiles t-vprintf-gnu.tmp t-vprintf-gnu.out"
+${CHECKER} ./test-vprintf-gnu${EXEEXT} > t-vprintf-gnu.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-vprintf-gnu.tmp > t-vprintf-gnu.out || exit 1
+
+: "${DIFF=diff}"
+${DIFF} "${srcdir}/test-printf-gnu.output" t-vprintf-gnu.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
--
2.34.1
[-- Attachment #21: 0020-printf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6932 bytes --]
From 171d2a5f80f3d0dc720a291c349486944fd35243 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:55:38 +0100
Subject: [PATCH 20/31] printf-gnu: New module.
* m4/printf-posix.m4: Renamed from m4/printf-posix-rpl.m4.
(gl_FUNC_PRINTF_IS_POSIX): New macro.
(gl_FUNC_PRINTF_POSIX): Require it. Don't require
gl_FUNC_VFPRINTF_POSIX. Invoke gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
and gl_REPLACE_VASNPRINTF.
* m4/printf-gnu.m4: New file, based on m4/fprintf-posix.m4.
* modules/printf-posix (Files): Update.
* modules/printf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/printf.texi: Mention the new module.
---
ChangeLog | 13 +++++++++
doc/posix-functions/printf.texi | 15 ++++++++---
m4/printf-gnu.m4 | 25 ++++++++++++++++++
m4/{printf-posix-rpl.m4 => printf-posix.m4} | 16 +++++++++---
modules/printf-gnu | 29 +++++++++++++++++++++
modules/printf-posix | 2 +-
6 files changed, 92 insertions(+), 8 deletions(-)
create mode 100644 m4/printf-gnu.m4
rename m4/{printf-posix-rpl.m4 => printf-posix.m4} (61%)
create mode 100644 modules/printf-gnu
diff --git a/ChangeLog b/ChangeLog
index aa826b376a..cbab39bd9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ printf-gnu: New module.
+ * m4/printf-posix.m4: Renamed from m4/printf-posix-rpl.m4.
+ (gl_FUNC_PRINTF_IS_POSIX): New macro.
+ (gl_FUNC_PRINTF_POSIX): Require it. Don't require
+ gl_FUNC_VFPRINTF_POSIX. Invoke gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ and gl_REPLACE_VASNPRINTF.
+ * m4/printf-gnu.m4: New file, based on m4/fprintf-posix.m4.
+ * modules/printf-posix (Files): Update.
+ * modules/printf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/printf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
vprintf-gnu: Add tests.
diff --git a/doc/posix-functions/printf.texi b/doc/posix-functions/printf.texi
index 8a3971aa30..382873e9e0 100644
--- a/doc/posix-functions/printf.texi
+++ b/doc/posix-functions/printf.texi
@@ -4,9 +4,9 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html}
-Gnulib module: printf-posix or stdio, nonblocking, sigpipe
+Gnulib module: printf-posix or printf-gnu or stdio, nonblocking, sigpipe
-Portability problems fixed by Gnulib module @code{printf-posix}:
+Portability problems fixed by either Gnulib module @code{printf-posix} or @code{printf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -77,7 +77,14 @@
FreeBSD 13.0, NetBSD 5.0.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{printf-posix}, together with module @code{nonblocking}:
+Portability problems fixed by Gnulib module @code{printf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
+Portability problems fixed by Gnulib module @code{stdio} or @code{printf-posix} or @code{printf-gnu}, together with module @code{nonblocking}:
@itemize
@item
When writing to a non-blocking pipe whose buffer is full, this function fails
@@ -86,7 +93,7 @@
mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{stdio} or @code{printf-posix}, together with module @code{sigpipe}:
+Portability problems fixed by Gnulib module @code{stdio} or @code{printf-posix} or @code{printf-gnu}, together with module @code{sigpipe}:
@itemize
@item
When writing to a pipe with no readers, this function fails, instead of
diff --git a/m4/printf-gnu.m4 b/m4/printf-gnu.m4
new file mode 100644
index 0000000000..4d8f3c70ff
--- /dev/null
+++ b/m4/printf-gnu.m4
@@ -0,0 +1,25 @@
+# printf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_PRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_PRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_printf_gnu=no
+ if test $gl_cv_func_printf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # printf is already POSIX compliant and GNU compatible.
+ gl_cv_func_printf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_printf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_PRINTF
+ fi
+])
diff --git a/m4/printf-posix-rpl.m4 b/m4/printf-posix.m4
similarity index 61%
rename from m4/printf-posix-rpl.m4
rename to m4/printf-posix.m4
index 36156d4350..9aebf4002d 100644
--- a/m4/printf-posix-rpl.m4
+++ b/m4/printf-posix.m4
@@ -1,4 +1,4 @@
-# printf-posix-rpl.m4 serial 4
+# printf-posix.m4 serial 5
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,12 +6,22 @@
AC_DEFUN([gl_FUNC_PRINTF_POSIX],
[
- AC_REQUIRE([gl_FUNC_VFPRINTF_POSIX])
- if test $gl_cv_func_vfprintf_posix = no; then
+ AC_REQUIRE([gl_FUNC_PRINTF_IS_POSIX])
+ if test $gl_cv_func_printf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
gl_REPLACE_PRINTF
fi
])
+dnl Test whether printf is POSIX compliant.
+dnl Result is gl_cv_func_printf_posix.
+AC_DEFUN([gl_FUNC_PRINTF_IS_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VFPRINTF_IS_POSIX])
+ gl_cv_func_printf_posix="$gl_cv_func_vfprintf_posix"
+])
+
AC_DEFUN([gl_REPLACE_PRINTF],
[
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
diff --git a/modules/printf-gnu b/modules/printf-gnu
new file mode 100644
index 0000000000..f42a18fd5b
--- /dev/null
+++ b/modules/printf-gnu
@@ -0,0 +1,29 @@
+Description:
+POSIX and GNU compatible printf() function: print formatted output to
+standard output
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/printf-gnu.m4
+
+Depends-on:
+printf-posix
+
+configure.ac:
+gl_FUNC_PRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
diff --git a/modules/printf-posix b/modules/printf-posix
index 51e2c1ac2a..8ad5c75810 100644
--- a/modules/printf-posix
+++ b/modules/printf-posix
@@ -9,7 +9,7 @@ that module occurs among the main modules in lib/.
Files:
lib/printf.c
-m4/printf-posix-rpl.m4
+m4/printf-posix.m4
m4/printf.m4
m4/asm-underscore.m4
--
2.34.1
[-- Attachment #22: 0021-printf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 3602 bytes --]
From 6a8aeae6854226579bbd42a496e8a07f4d8bb8ec Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 11:57:19 +0100
Subject: [PATCH 21/31] printf-gnu: Add tests.
* tests/test-printf-gnu.sh: New file, based on
tests/test-printf-posix.sh.
* tests/test-printf-gnu.c: New file, based on tests/test-printf-posix.c.
* modules/printf-gnu-tests: New file, based on
modules/printf-posix-tests.
---
ChangeLog | 7 +++++++
modules/printf-gnu-tests | 15 +++++++++++++++
tests/test-printf-gnu.c | 35 +++++++++++++++++++++++++++++++++++
tests/test-printf-gnu.sh | 16 ++++++++++++++++
4 files changed, 73 insertions(+)
create mode 100644 modules/printf-gnu-tests
create mode 100644 tests/test-printf-gnu.c
create mode 100755 tests/test-printf-gnu.sh
diff --git a/ChangeLog b/ChangeLog
index cbab39bd9d..71ddf71163 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ printf-gnu: Add tests.
+ * tests/test-printf-gnu.sh: New file, based on
+ tests/test-printf-posix.sh.
+ * tests/test-printf-gnu.c: New file, based on tests/test-printf-posix.c.
+ * modules/printf-gnu-tests: New file, based on
+ modules/printf-posix-tests.
+
printf-gnu: New module.
* m4/printf-posix.m4: Renamed from m4/printf-posix-rpl.m4.
(gl_FUNC_PRINTF_IS_POSIX): New macro.
diff --git a/modules/printf-gnu-tests b/modules/printf-gnu-tests
new file mode 100644
index 0000000000..0a0cd906db
--- /dev/null
+++ b/modules/printf-gnu-tests
@@ -0,0 +1,15 @@
+Files:
+tests/test-printf-gnu.sh
+tests/test-printf-gnu.c
+tests/test-printf-gnu.h
+tests/test-printf-gnu.output
+tests/macros.h
+
+Depends-on:
+printf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-printf-gnu.sh
+check_PROGRAMS += test-printf-gnu
diff --git a/tests/test-printf-gnu.c b/tests/test-printf-gnu.c
new file mode 100644
index 0000000000..ed7bf6bd95
--- /dev/null
+++ b/tests/test-printf-gnu.c
@@ -0,0 +1,35 @@
+/* Test of POSIX and GNU compatible printf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-printf-gnu.h"
+
+int
+main (int argc, char *argv[])
+{
+ test_function (printf);
+ return 0;
+}
diff --git a/tests/test-printf-gnu.sh b/tests/test-printf-gnu.sh
new file mode 100755
index 0000000000..179ade635f
--- /dev/null
+++ b/tests/test-printf-gnu.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' HUP INT QUIT TERM
+
+tmpfiles="$tmpfiles t-printf-gnu.tmp t-printf-gnu.out"
+${CHECKER} ./test-printf-gnu${EXEEXT} > t-printf-gnu.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-printf-gnu.tmp > t-printf-gnu.out || exit 1
+
+: "${DIFF=diff}"
+${DIFF} "${srcdir}/test-printf-gnu.output" t-printf-gnu.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
--
2.34.1
[-- Attachment #23: 0022-vdprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6652 bytes --]
From 459992e2602eb90fb7d62960a605a5245f522148 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:00:23 +0100
Subject: [PATCH 22/31] vdprintf-gnu: New module.
* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VDPRINTF_POSIX.
(gl_FUNC_VDPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vdprintf-gnu.m4: New file, based on m4/vdprintf-posix.m4.
* modules/vdprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/vdprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/vdprintf.texi | 13 ++++++++++---
m4/vdprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/vdprintf-posix.m4 | 31 +++++++++++++------------------
modules/vdprintf-gnu | 29 +++++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 21 deletions(-)
create mode 100644 m4/vdprintf-gnu.m4
create mode 100644 modules/vdprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 71ddf71163..e385339bb5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ vdprintf-gnu: New module.
+ * m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_VDPRINTF_POSIX.
+ (gl_FUNC_VDPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/vdprintf-gnu.m4: New file, based on m4/vdprintf-posix.m4.
+ * modules/vdprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/vdprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
printf-gnu: Add tests.
diff --git a/doc/posix-functions/vdprintf.texi b/doc/posix-functions/vdprintf.texi
index d533d32892..59138d5d15 100644
--- a/doc/posix-functions/vdprintf.texi
+++ b/doc/posix-functions/vdprintf.texi
@@ -4,16 +4,16 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/vdprintf.html}
-Gnulib module: vdprintf or vdprintf-posix
+Gnulib module: vdprintf or vdprintf-posix or vdprintf-gnu
-Portability problems fixed by either Gnulib module @code{vdprintf} or @code{vdprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vdprintf} or @code{vdprintf-posix} or @code{vdprintf-gnu}:
@itemize
@item
This function is missing on some platforms:
Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.3, Cygwin 1.5.x, mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{vdprintf-posix}:
+Portability problems fixed by either Gnulib module @code{vdprintf-posix} or @code{vdprintf-gnu}:
@itemize
@item
printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an
@@ -50,6 +50,13 @@
glibc 2.35, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
@end itemize
+Portability problems fixed by Gnulib module @code{vdprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/vdprintf-gnu.m4 b/m4/vdprintf-gnu.m4
new file mode 100644
index 0000000000..09cec803b2
--- /dev/null
+++ b/m4/vdprintf-gnu.m4
@@ -0,0 +1,25 @@
+# vdprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VDPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VDPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vdprintf_gnu=no
+ if test $gl_cv_func_vdprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vdprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_vdprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vdprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VDPRINTF
+ fi
+])
diff --git a/m4/vdprintf-posix.m4 b/m4/vdprintf-posix.m4
index ff74fdaab4..01664d4a52 100644
--- a/m4/vdprintf-posix.m4
+++ b/m4/vdprintf-posix.m4
@@ -1,10 +1,22 @@
-# vdprintf-posix.m4 serial 5
+# vdprintf-posix.m4 serial 6
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VDPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_VDPRINTF_IS_POSIX])
+ if test $gl_cv_func_vdprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_VDPRINTF
+ fi
+])
+
+dnl Test whether vdprintf exists and is POSIX compliant.
+dnl Result is gl_cv_func_vdprintf_posix.
+AC_DEFUN([gl_FUNC_VDPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -93,21 +105,4 @@ AC_DEFUN([gl_FUNC_VDPRINTF_POSIX]
;;
esac
fi
- if test $gl_cv_func_vdprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_VDPRINTF
- fi
])
diff --git a/modules/vdprintf-gnu b/modules/vdprintf-gnu
new file mode 100644
index 0000000000..b7bbb74fbe
--- /dev/null
+++ b/modules/vdprintf-gnu
@@ -0,0 +1,29 @@
+Description:
+POSIX and GNU compatible vdprintf() function: print formatted output to a file
+descriptor
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vdprintf-gnu.m4
+
+Depends-on:
+vdprintf-posix
+
+configure.ac:
+gl_FUNC_VDPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #24: 0023-vdprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 3928 bytes --]
From a8fa5b6d61c15ac945625d12c28aeb8258533188 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:01:45 +0100
Subject: [PATCH 23/31] vdprintf-gnu: Add tests.
* tests/test-vdprintf-gnu.sh: New file, based on
tests/test-vdprintf-posix.sh.
* tests/test-vdprintf-gnu.c: New file, based on
tests/test-vdprintf-posix.c.
* modules/vdprintf-gnu-tests: New file, based on
modules/vdprintf-posix-tests.
---
ChangeLog | 8 +++++++
modules/vdprintf-gnu-tests | 15 ++++++++++++
tests/test-vdprintf-gnu.c | 48 ++++++++++++++++++++++++++++++++++++++
tests/test-vdprintf-gnu.sh | 16 +++++++++++++
4 files changed, 87 insertions(+)
create mode 100644 modules/vdprintf-gnu-tests
create mode 100644 tests/test-vdprintf-gnu.c
create mode 100755 tests/test-vdprintf-gnu.sh
diff --git a/ChangeLog b/ChangeLog
index e385339bb5..a65107ca3a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ vdprintf-gnu: Add tests.
+ * tests/test-vdprintf-gnu.sh: New file, based on
+ tests/test-vdprintf-posix.sh.
+ * tests/test-vdprintf-gnu.c: New file, based on
+ tests/test-vdprintf-posix.c.
+ * modules/vdprintf-gnu-tests: New file, based on
+ modules/vdprintf-posix-tests.
+
vdprintf-gnu: New module.
* m4/vdprintf-posix.m4 (gl_FUNC_VDPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_VDPRINTF_POSIX.
diff --git a/modules/vdprintf-gnu-tests b/modules/vdprintf-gnu-tests
new file mode 100644
index 0000000000..73e57fac88
--- /dev/null
+++ b/modules/vdprintf-gnu-tests
@@ -0,0 +1,15 @@
+Files:
+tests/test-vdprintf-gnu.sh
+tests/test-vdprintf-gnu.c
+tests/test-fprintf-gnu.h
+tests/test-printf-gnu.output
+tests/macros.h
+
+Depends-on:
+vdprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vdprintf-gnu.sh
+check_PROGRAMS += test-vdprintf-gnu
diff --git a/tests/test-vdprintf-gnu.c b/tests/test-vdprintf-gnu.c
new file mode 100644
index 0000000000..fa5448dbc8
--- /dev/null
+++ b/tests/test-vdprintf-gnu.c
@@ -0,0 +1,48 @@
+/* Test of POSIX and GNU compatible vdprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2009. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+
+#include "test-fprintf-gnu.h"
+
+static int
+my_fprintf (FILE *fp, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, format);
+ ret = vdprintf (fileno (fp), format, args);
+ va_end (args);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (my_fprintf);
+ return 0;
+}
diff --git a/tests/test-vdprintf-gnu.sh b/tests/test-vdprintf-gnu.sh
new file mode 100755
index 0000000000..496d9054fd
--- /dev/null
+++ b/tests/test-vdprintf-gnu.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' HUP INT QUIT TERM
+
+tmpfiles="$tmpfiles t-vdprintf-gnu.tmp t-vdprintf-gnu.out"
+${CHECKER} ./test-vdprintf-gnu${EXEEXT} > t-vdprintf-gnu.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-vdprintf-gnu.tmp > t-vdprintf-gnu.out || exit 1
+
+: "${DIFF=diff}"
+${DIFF} "${srcdir}/test-printf-gnu.output" t-vdprintf-gnu.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
--
2.34.1
[-- Attachment #25: 0024-dprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 6585 bytes --]
From 75e63081831ef07462ce9f8d9f82865486db52e2 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:04:20 +0100
Subject: [PATCH 24/31] dprintf-gnu: New module.
* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_DPRINTF_POSIX.
(gl_FUNC_DPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/dprintf-gnu.m4: New file, based on m4/dprintf-posix.m4.
* modules/dprintf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/posix-functions/dprintf.texi: Mention the new module.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/dprintf.texi | 13 ++++++++++---
m4/dprintf-gnu.m4 | 25 +++++++++++++++++++++++++
m4/dprintf-posix.m4 | 31 +++++++++++++------------------
modules/dprintf-gnu | 29 +++++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 21 deletions(-)
create mode 100644 m4/dprintf-gnu.m4
create mode 100644 modules/dprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index a65107ca3a..2ae71f5bcf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ dprintf-gnu: New module.
+ * m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_IS_POSIX): New macro,
+ extracted from gl_FUNC_DPRINTF_POSIX.
+ (gl_FUNC_DPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/dprintf-gnu.m4: New file, based on m4/dprintf-posix.m4.
+ * modules/dprintf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/posix-functions/dprintf.texi: Mention the new module.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
vdprintf-gnu: Add tests.
diff --git a/doc/posix-functions/dprintf.texi b/doc/posix-functions/dprintf.texi
index 09e308c33b..54953d04a3 100644
--- a/doc/posix-functions/dprintf.texi
+++ b/doc/posix-functions/dprintf.texi
@@ -4,16 +4,16 @@
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/dprintf.html}
-Gnulib module: dprintf or dprintf-posix
+Gnulib module: dprintf or dprintf-posix or dprintf-gnu
-Portability problems fixed by either Gnulib module @code{dprintf} or @code{dprintf-posix}:
+Portability problems fixed by either Gnulib module @code{dprintf} or @code{dprintf-posix} or @code{dprintf-gnu}:
@itemize
@item
This function is missing on many non-glibc platforms:
Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.3, Cygwin 1.5.x, mingw, MSVC 14.
@end itemize
-Portability problems fixed by Gnulib module @code{dprintf-posix}:
+Portability problems fixed by either Gnulib module @code{dprintf-posix} or @code{dprintf-gnu}:
@itemize
@item
printf @code{"%f"}, @code{"%e"}, @code{"%g"} of Infinity and NaN yields an
@@ -50,6 +50,13 @@
glibc 2.35, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
@end itemize
+Portability problems fixed by Gnulib module @code{dprintf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/dprintf-gnu.m4 b/m4/dprintf-gnu.m4
new file mode 100644
index 0000000000..552e0b5a05
--- /dev/null
+++ b/m4/dprintf-gnu.m4
@@ -0,0 +1,25 @@
+# dprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_DPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_DPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_dprintf_gnu=no
+ if test $gl_cv_func_dprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # dprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_dprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_dprintf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_DPRINTF
+ fi
+])
diff --git a/m4/dprintf-posix.m4 b/m4/dprintf-posix.m4
index eb8bd634f8..8759beaa22 100644
--- a/m4/dprintf-posix.m4
+++ b/m4/dprintf-posix.m4
@@ -1,10 +1,22 @@
-# dprintf-posix.m4 serial 5
+# dprintf-posix.m4 serial 6
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_DPRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_DPRINTF_IS_POSIX])
+ if test $gl_cv_func_dprintf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_DPRINTF
+ fi
+])
+
+dnl Test whether dprintf exists and is POSIX compliant.
+dnl Result is gl_cv_func_dprintf_posix.
+AC_DEFUN([gl_FUNC_DPRINTF_IS_POSIX],
[
AC_REQUIRE([gl_PRINTF_SIZES_C99])
AC_REQUIRE([gl_PRINTF_LONG_DOUBLE])
@@ -93,21 +105,4 @@ AC_DEFUN([gl_FUNC_DPRINTF_POSIX]
;;
esac
fi
- if test $gl_cv_func_dprintf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_DPRINTF
- fi
])
diff --git a/modules/dprintf-gnu b/modules/dprintf-gnu
new file mode 100644
index 0000000000..b7228f9ec7
--- /dev/null
+++ b/modules/dprintf-gnu
@@ -0,0 +1,29 @@
+Description:
+POSIX and GNU compatible dprintf() function: print formatted output to a file
+descriptor
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/dprintf-gnu.m4
+
+Depends-on:
+dprintf-posix
+
+configure.ac:
+gl_FUNC_DPRINTF_GNU
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+LGPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #26: 0025-dprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 5828 bytes --]
From b54782e2765a43971b91ff637cefc446933022cc Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:05:26 +0100
Subject: [PATCH 25/31] dprintf-gnu: Add tests.
* tests/test-dprintf-gnu.sh: New file, based on
tests/test-dprintf-posix.sh.
* tests/test-dprintf-gnu.c: New file, based on
tests/test-vasnprintf-gnu.c.
* modules/dprintf-gnu-tests: New file, based on
modules/dprintf-posix-tests.
---
ChangeLog | 8 ++++
modules/dprintf-gnu-tests | 13 ++++++
tests/test-dprintf-gnu.c | 97 +++++++++++++++++++++++++++++++++++++++
tests/test-dprintf-gnu.sh | 16 +++++++
4 files changed, 134 insertions(+)
create mode 100644 modules/dprintf-gnu-tests
create mode 100644 tests/test-dprintf-gnu.c
create mode 100755 tests/test-dprintf-gnu.sh
diff --git a/ChangeLog b/ChangeLog
index 2ae71f5bcf..bb0463cba7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ dprintf-gnu: Add tests.
+ * tests/test-dprintf-gnu.sh: New file, based on
+ tests/test-dprintf-posix.sh.
+ * tests/test-dprintf-gnu.c: New file, based on
+ tests/test-vasnprintf-gnu.c.
+ * modules/dprintf-gnu-tests: New file, based on
+ modules/dprintf-posix-tests.
+
dprintf-gnu: New module.
* m4/dprintf-posix.m4 (gl_FUNC_DPRINTF_IS_POSIX): New macro,
extracted from gl_FUNC_DPRINTF_POSIX.
diff --git a/modules/dprintf-gnu-tests b/modules/dprintf-gnu-tests
new file mode 100644
index 0000000000..117e615649
--- /dev/null
+++ b/modules/dprintf-gnu-tests
@@ -0,0 +1,13 @@
+Files:
+tests/test-dprintf-gnu.sh
+tests/test-dprintf-gnu.c
+tests/test-printf-gnu.output
+
+Depends-on:
+dprintf-posix-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-dprintf-gnu.sh
+check_PROGRAMS += test-dprintf-gnu
diff --git a/tests/test-dprintf-gnu.c b/tests/test-dprintf-gnu.c
new file mode 100644
index 0000000000..4ea2b5905b
--- /dev/null
+++ b/tests/test-dprintf-gnu.c
@@ -0,0 +1,97 @@
+/* Test of POSIX and GNU compatible dprintf() function.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+
+static void
+test_function (int (*my_dprintf) (int, const char *, ...))
+{
+ /* Here we don't test output that may be platform dependent.
+ The bulk of the tests is done as part of the 'vasnprintf-posix' module. */
+
+ /* Test the support of the 'B' conversion specifier for binary output of
+ integers. */
+
+ /* Zero. */
+ my_dprintf (fileno (stdout), "%B %d\n", 0, 33, 44, 55);
+
+ /* A positive number. */
+ my_dprintf (fileno (stdout), "%B %d\n", 12345, 33, 44, 55);
+
+ /* A large positive number. */
+ my_dprintf (fileno (stdout), "%B %d\n", 0xFFFFFFFEU, 33, 44, 55);
+
+ /* Width. */
+ my_dprintf (fileno (stdout), "%20B %d\n", 12345, 33, 44, 55);
+
+ /* Width given as argument. */
+ my_dprintf (fileno (stdout), "%*B %d\n", 20, 12345, 33, 44, 55);
+
+ /* Negative width given as argument (cf. FLAG_LEFT below). */
+ my_dprintf (fileno (stdout), "%*B %d\n", -20, 12345, 33, 44, 55);
+
+ /* Precision. */
+ my_dprintf (fileno (stdout), "%.20B %d\n", 12345, 33, 44, 55);
+
+ /* Zero precision and a positive number. */
+ my_dprintf (fileno (stdout), "%.0B %d\n", 12345, 33, 44, 55);
+
+ /* Zero precision and a zero number. */
+ my_dprintf (fileno (stdout), "%.0B %d\n", 0, 33, 44, 55);
+
+ /* Width and precision. */
+ my_dprintf (fileno (stdout), "%25.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_LEFT. */
+ my_dprintf (fileno (stdout), "%-20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with zero. */
+ my_dprintf (fileno (stdout), "%#B %d\n", 0, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number. */
+ my_dprintf (fileno (stdout), "%#B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and width. */
+ my_dprintf (fileno (stdout), "%#20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and padding. */
+ my_dprintf (fileno (stdout), "%0#20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and precision. */
+ my_dprintf (fileno (stdout), "%0#.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a positive number and width and precision. */
+ my_dprintf (fileno (stdout), "%#25.20B %d\n", 12345, 33, 44, 55);
+
+ /* FLAG_ALT with a zero precision and a zero number. */
+ my_dprintf (fileno (stdout), "%#.0B %d\n", 0, 33, 44, 55);
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_function (dprintf);
+ return 0;
+}
diff --git a/tests/test-dprintf-gnu.sh b/tests/test-dprintf-gnu.sh
new file mode 100755
index 0000000000..8f2665446b
--- /dev/null
+++ b/tests/test-dprintf-gnu.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' HUP INT QUIT TERM
+
+tmpfiles="$tmpfiles t-dprintf-gnu.tmp t-dprintf-gnu.out"
+${CHECKER} ./test-dprintf-gnu${EXEEXT} > t-dprintf-gnu.tmp || exit 1
+LC_ALL=C tr -d '\r' < t-dprintf-gnu.tmp > t-dprintf-gnu.out || exit 1
+
+: "${DIFF=diff}"
+${DIFF} "${srcdir}/test-printf-gnu.output" t-dprintf-gnu.out
+result=$?
+
+rm -fr $tmpfiles
+
+exit $result
--
2.34.1
[-- Attachment #27: 0026-obstack-printf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 8976 bytes --]
From 7e73cf31ed32c3931a7f85cb863432d72e8af95f Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:11:52 +0100
Subject: [PATCH 26/31] obstack-printf-gnu: New module.
* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_IS_POSIX): New
macro, extracted from gl_FUNC_OBSTACK_PRINTF_POSIX.
(gl_FUNC_OBSTACK_PRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/obstack-printf-gnu.m4: New file, based on
m4/obstack-printf-posix.m4.
* modules/obstack-printf-gnu: New file, based on modules/vasnprintf-gnu.
* doc/glibc-functions/obstack_printf.texi: Mention the new module.
* doc/glibc-functions/obstack_vprintf.texi: Likewise.
---
ChangeLog | 13 ++++++++++
doc/glibc-functions/obstack_printf.texi | 13 +++++++---
doc/glibc-functions/obstack_vprintf.texi | 13 +++++++---
m4/obstack-printf-gnu.m4 | 26 +++++++++++++++++++
m4/obstack-printf-posix.m4 | 33 ++++++++++--------------
modules/obstack-printf-gnu | 31 ++++++++++++++++++++++
6 files changed, 104 insertions(+), 25 deletions(-)
create mode 100644 m4/obstack-printf-gnu.m4
create mode 100644 modules/obstack-printf-gnu
diff --git a/ChangeLog b/ChangeLog
index bb0463cba7..8c1abcf037 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ obstack-printf-gnu: New module.
+ * m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_IS_POSIX): New
+ macro, extracted from gl_FUNC_OBSTACK_PRINTF_POSIX.
+ (gl_FUNC_OBSTACK_PRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/obstack-printf-gnu.m4: New file, based on
+ m4/obstack-printf-posix.m4.
+ * modules/obstack-printf-gnu: New file, based on modules/vasnprintf-gnu.
+ * doc/glibc-functions/obstack_printf.texi: Mention the new module.
+ * doc/glibc-functions/obstack_vprintf.texi: Likewise.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
dprintf-gnu: Add tests.
diff --git a/doc/glibc-functions/obstack_printf.texi b/doc/glibc-functions/obstack_printf.texi
index 8b13e1296e..18d82a903c 100644
--- a/doc/glibc-functions/obstack_printf.texi
+++ b/doc/glibc-functions/obstack_printf.texi
@@ -10,17 +10,17 @@
@url{https://www.gnu.org/software/libc/manual/html_node/Dynamic-Output.html}.
@end ifnotinfo
-Gnulib module: obstack-printf or obstack-printf-posix
+Gnulib module: obstack-printf or obstack-printf-posix or obstack-printf-gnu
Portability problems fixed by either Gnulib module
-@code{obstack-printf} or @code{obstack-printf-posix}:
+@code{obstack-printf} or @code{obstack-printf-posix} or @code{obstack-printf-gnu}:
@itemize
@item
This function is missing on all non-glibc platforms:
macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
@end itemize
-Portability problems fixed by Gnulib module @code{obstack-printf-posix}:
+Portability problems fixed by either Gnulib module @code{obstack-printf-posix} or @code{obstack-printf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -88,6 +88,13 @@
HP-UX 11, mingw, MSVC 14.
@end itemize
+Portability problems fixed by Gnulib module @code{obstack-printf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/doc/glibc-functions/obstack_vprintf.texi b/doc/glibc-functions/obstack_vprintf.texi
index 2ea59ef4fa..6d7ba77b30 100644
--- a/doc/glibc-functions/obstack_vprintf.texi
+++ b/doc/glibc-functions/obstack_vprintf.texi
@@ -10,17 +10,17 @@
@url{https://www.gnu.org/software/libc/manual/html_node/Variable-Arguments-Output.html}.
@end ifnotinfo
-Gnulib module: obstack-printf or obstack-printf-posix
+Gnulib module: obstack-printf or obstack-printf-posix or obstack-printf-gnu
Portability problems fixed by either Gnulib module
-@code{obstack-printf} or @code{obstack-printf-posix}:
+@code{obstack-printf} or @code{obstack-printf-posix} or @code{obstack-printf-gnu}:
@itemize
@item
This function is missing on all non-glibc platforms:
macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
@end itemize
-Portability problems fixed by Gnulib module @code{obstack-printf-posix}:
+Portability problems fixed by either Gnulib module @code{obstack-printf-posix} or @code{obstack-printf-gnu}:
@itemize
@item
This function does not support size specifiers as in C99 (@code{hh}, @code{ll},
@@ -88,6 +88,13 @@
HP-UX 11, mingw, MSVC 14.
@end itemize
+Portability problems fixed by Gnulib module @code{obstack-printf-gnu}:
+@itemize
+@item
+This function does not support the @samp{B} directive on some platforms:
+glibc 2.34, FreeBSD 13.1, NetBSD 9.0, OpenBSD 7.2, macOS 12.5, AIX 7.2, Solaris 11.4, and others.
+@end itemize
+
Portability problems not fixed by Gnulib:
@itemize
@item
diff --git a/m4/obstack-printf-gnu.m4 b/m4/obstack-printf-gnu.m4
new file mode 100644
index 0000000000..9a722ee05f
--- /dev/null
+++ b/m4/obstack-printf-gnu.m4
@@ -0,0 +1,26 @@
+# obstack-printf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_OBSTACK_PRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_obstack_printf_gnu=no
+ if test $gl_cv_func_obstack_printf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # obstack_printf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_obstack_printf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_obstack_printf_gnu = no; then
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_OBSTACK_PRINTF
+ fi
+ gl_DECL_OBSTACK_PRINTF
+])
diff --git a/m4/obstack-printf-posix.m4 b/m4/obstack-printf-posix.m4
index 8092119906..751d6759cf 100644
--- a/m4/obstack-printf-posix.m4
+++ b/m4/obstack-printf-posix.m4
@@ -1,10 +1,23 @@
-# obstack-printf-posix.m4 serial 6
+# obstack-printf-posix.m4 serial 7
dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX],
+[
+ AC_REQUIRE([gl_FUNC_OBSTACK_PRINTF_IS_POSIX])
+ if test $gl_cv_func_obstack_printf_posix = no; then
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_REPLACE_VASNPRINTF
+ gl_REPLACE_OBSTACK_PRINTF
+ fi
+ gl_DECL_OBSTACK_PRINTF
+])
+
+dnl Test whether obstack_printf exists and is POSIX compliant.
+dnl Result is gl_cv_func_obstack_printf_posix.
+AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_IS_POSIX],
[
dnl Persuade glibc <stdio.h> to declare obstack_printf(), obstack_vprintf().
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
@@ -96,22 +109,4 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX]
;;
esac
fi
- if test $gl_cv_func_obstack_printf_posix = no; then
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LC
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
- gl_REPLACE_VASNPRINTF
- gl_REPLACE_OBSTACK_PRINTF
- fi
- gl_DECL_OBSTACK_PRINTF
])
diff --git a/modules/obstack-printf-gnu b/modules/obstack-printf-gnu
new file mode 100644
index 0000000000..c6538ba701
--- /dev/null
+++ b/modules/obstack-printf-gnu
@@ -0,0 +1,31 @@
+Description:
+POSIX and GNU compatible formatted printing into an obstack.
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/obstack-printf-gnu.m4
+
+Depends-on:
+obstack-printf-posix
+
+configure.ac:
+gl_FUNC_OBSTACK_PRINTF_GNU
+if test $ac_cv_func_obstack_printf = no || test $REPLACE_OBSTACK_PRINTF = 1; then
+ AC_LIBOBJ([obstack_printf])
+fi
+
+Makefile.am:
+
+Include:
+<stdio.h>
+
+License:
+GPL
+
+Maintainer:
+Eric Blake
--
2.34.1
[-- Attachment #28: 0027-obstack-printf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 1225 bytes --]
From f63b3b100f53df107de67e3314db2a19b945f220 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:12:36 +0100
Subject: [PATCH 27/31] obstack-printf-gnu: Add tests.
* modules/obstack-printf-gnu-tests: New file, based on
modules/obstack-printf-posix-tests.
---
ChangeLog | 4 ++++
modules/obstack-printf-gnu-tests | 8 ++++++++
2 files changed, 12 insertions(+)
create mode 100644 modules/obstack-printf-gnu-tests
diff --git a/ChangeLog b/ChangeLog
index 8c1abcf037..ddadbad8d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ obstack-printf-gnu: Add tests.
+ * modules/obstack-printf-gnu-tests: New file, based on
+ modules/obstack-printf-posix-tests.
+
obstack-printf-gnu: New module.
* m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_IS_POSIX): New
macro, extracted from gl_FUNC_OBSTACK_PRINTF_POSIX.
diff --git a/modules/obstack-printf-gnu-tests b/modules/obstack-printf-gnu-tests
new file mode 100644
index 0000000000..4afbcc337d
--- /dev/null
+++ b/modules/obstack-printf-gnu-tests
@@ -0,0 +1,8 @@
+Files:
+
+Depends-on:
+obstack-printf-posix-tests
+
+configure.ac:
+
+Makefile.am:
--
2.34.1
[-- Attachment #29: 0028-vasnwprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 4792 bytes --]
From e2cb98413b5b3536bb0404a96715e0dcfaeeb295 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:15:42 +0100
Subject: [PATCH 28/31] vasnwprintf-gnu: New module.
* m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_IS_POSIX): New macro.
(gl_FUNC_VASNWPRINTF_POSIX): Require it. Invoke
gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
* m4/vasnwprintf-gnu.m4: New file, based on m4/vasnprintf-gnu.m4.
* modules/vasnwprintf-gnu: New file, based on modules/vasnprintf-gnu.
---
ChangeLog | 9 +++++++++
m4/vasnwprintf-gnu.m4 | 26 ++++++++++++++++++++++++++
m4/vasnwprintf-posix.m4 | 29 +++++++++++++++--------------
modules/vasnwprintf-gnu | 32 ++++++++++++++++++++++++++++++++
4 files changed, 82 insertions(+), 14 deletions(-)
create mode 100644 m4/vasnwprintf-gnu.m4
create mode 100644 modules/vasnwprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index ddadbad8d1..994d8792f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ vasnwprintf-gnu: New module.
+ * m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_IS_POSIX): New macro.
+ (gl_FUNC_VASNWPRINTF_POSIX): Require it. Invoke
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS.
+ * m4/vasnwprintf-gnu.m4: New file, based on m4/vasnprintf-gnu.m4.
+ * modules/vasnwprintf-gnu: New file, based on modules/vasnprintf-gnu.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
obstack-printf-gnu: Add tests.
diff --git a/m4/vasnwprintf-gnu.m4 b/m4/vasnwprintf-gnu.m4
new file mode 100644
index 0000000000..ee89bef237
--- /dev/null
+++ b/m4/vasnwprintf-gnu.m4
@@ -0,0 +1,26 @@
+# vasnwprintf-gnu.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_VASNWPRINTF_GNU],
+[
+ AC_REQUIRE([gl_FUNC_VASNWPRINTF_IS_POSIX])
+ AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B])
+ gl_cv_func_vasnwprintf_gnu=no
+ if test $gl_cv_func_vasnwprintf_posix = yes; then
+ case "$gl_cv_func_printf_directive_uppercase_b" in
+ *yes)
+ # vasnwprintf exists and is already POSIX compliant and GNU compatible.
+ gl_cv_func_vasnwprintf_gnu=yes
+ ;;
+ esac
+ fi
+ if test $gl_cv_func_vasnwprintf_gnu = no; then
+ dnl Note: This invokes gl_PREREQ_VASNPRINTF_DIRECTIVE_LC although not needed
+ dnl here. Doesn't matter.
+ gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS
+ gl_FUNC_VASNWPRINTF
+ fi
+])
diff --git a/m4/vasnwprintf-posix.m4 b/m4/vasnwprintf-posix.m4
index d9dc41fa97..310b4ffe60 100644
--- a/m4/vasnwprintf-posix.m4
+++ b/m4/vasnwprintf-posix.m4
@@ -1,4 +1,4 @@
-# vasnwprintf-posix.m4 serial 2
+# vasnwprintf-posix.m4 serial 3
dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -6,17 +6,18 @@
AC_DEFUN([gl_FUNC_VASNWPRINTF_POSIX],
[
- gl_FUNC_VASNWPRINTF
- gl_PREREQ_VASNPRINTF_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE
- gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE
- gl_PREREQ_VASNPRINTF_DIRECTIVE_A
- gl_PREREQ_VASNPRINTF_DIRECTIVE_B
- gl_PREREQ_VASNPRINTF_DIRECTIVE_F
- gl_PREREQ_VASNPRINTF_DIRECTIVE_LS
- gl_PREREQ_VASNPRINTF_FLAG_GROUPING
- gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST
- gl_PREREQ_VASNPRINTF_FLAG_ZERO
- gl_PREREQ_VASNPRINTF_PRECISION
- gl_PREREQ_VASNPRINTF_ENOMEM
+ AC_REQUIRE([gl_FUNC_VASNWPRINTF_IS_POSIX])
+ if test $gl_cv_func_vasnwprintf_posix = no; then
+ dnl Note: This invokes gl_PREREQ_VASNPRINTF_DIRECTIVE_LC although not needed
+ dnl here. Doesn't matter.
+ gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS
+ gl_FUNC_VASNWPRINTF
+ fi
+])
+
+dnl Test whether vasnwprintf exists and is POSIX compliant.
+dnl Result is gl_cv_func_vasnwprintf_posix.
+AC_DEFUN([gl_FUNC_VASNWPRINTF_IS_POSIX],
+[
+ gl_cv_func_vasnwprintf_posix=no
])
diff --git a/modules/vasnwprintf-gnu b/modules/vasnwprintf-gnu
new file mode 100644
index 0000000000..582a185edd
--- /dev/null
+++ b/modules/vasnwprintf-gnu
@@ -0,0 +1,32 @@
+Description:
+POSIX and GNU compatible vswprintf with automatic memory allocation and bounded
+output size.
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnwprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+m4/vasnwprintf-gnu.m4
+
+Depends-on:
+vasnwprintf-posix
+
+configure.ac:
+gl_FUNC_VASNWPRINTF_GNU
+
+Makefile.am:
+
+Include:
+"vasnwprintf.h"
+
+Link:
+$(MBRTOWC_LIB)
+
+License:
+LGPLv2+
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #30: 0029-vasnwprintf-gnu-Add-tests.patch --]
[-- Type: text/x-patch, Size: 10576 bytes --]
From 5f7fefc9efdaad47c0d3e2cad9f1bccb3fa69b0e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:16:36 +0100
Subject: [PATCH 29/31] vasnwprintf-gnu: Add tests.
* tests/test-vasnwprintf-gnu.c: New file, based on
tests/test-vasnwprintf-posix.c and tests/test-vasnprintf-gnu.c.
* modules/vasnwprintf-gnu-tests: New file, based on
modules/vasnwprintf-posix-tests.
---
ChangeLog | 6 +
modules/vasnwprintf-gnu-tests | 14 ++
tests/test-vasnwprintf-gnu.c | 276 ++++++++++++++++++++++++++++++++++
3 files changed, 296 insertions(+)
create mode 100644 modules/vasnwprintf-gnu-tests
create mode 100644 tests/test-vasnwprintf-gnu.c
diff --git a/ChangeLog b/ChangeLog
index 994d8792f7..45d26931cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2023-03-24 Bruno Haible <bruno@clisp.org>
+ vasnwprintf-gnu: Add tests.
+ * tests/test-vasnwprintf-gnu.c: New file, based on
+ tests/test-vasnwprintf-posix.c and tests/test-vasnprintf-gnu.c.
+ * modules/vasnwprintf-gnu-tests: New file, based on
+ modules/vasnwprintf-posix-tests.
+
vasnwprintf-gnu: New module.
* m4/vasnwprintf-posix.m4 (gl_FUNC_VASNWPRINTF_IS_POSIX): New macro.
(gl_FUNC_VASNWPRINTF_POSIX): Require it. Invoke
diff --git a/modules/vasnwprintf-gnu-tests b/modules/vasnwprintf-gnu-tests
new file mode 100644
index 0000000000..db17443046
--- /dev/null
+++ b/modules/vasnwprintf-gnu-tests
@@ -0,0 +1,14 @@
+Files:
+tests/test-vasnwprintf-gnu.c
+tests/macros.h
+
+Depends-on:
+vasnwprintf-posix-tests
+wcscmp
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-vasnwprintf-gnu
+check_PROGRAMS += test-vasnwprintf-gnu
+test_vasnwprintf_gnu_LDADD = $(LDADD) $(MBRTOWC_LIB)
diff --git a/tests/test-vasnwprintf-gnu.c b/tests/test-vasnwprintf-gnu.c
new file mode 100644
index 0000000000..1d48cd8172
--- /dev/null
+++ b/tests/test-vasnwprintf-gnu.c
@@ -0,0 +1,276 @@
+/* Test of POSIX and GNU compatible vasnwprintf() and asnwprintf() functions.
+ Copyright (C) 2007-2023 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2023. */
+
+#include <config.h>
+
+#include "vasnwprintf.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "macros.h"
+
+static void
+test_function (wchar_t * (*my_asnwprintf) (wchar_t *, size_t *, const wchar_t *, ...))
+{
+ /* Test the support of the 'b' conversion specifier for binary output of
+ integers. */
+
+ { /* Zero. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* A positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* A large positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%b %d", 0xFFFFFFFEU, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11111111111111111111111111111110 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width given as argument. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%*b %d", 20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Negative width given as argument (cf. FLAG_LEFT below). */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%*b %d", -20, 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.0b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Zero precision and a zero number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters." */
+ ASSERT (wcscmp (result, L" 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Width and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* Padding and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%025.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (wcscmp (result, L" 00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_LEFT. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%-20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with zero. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0b11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 0b11000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0b000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L"0b00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and width and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (wcscmp (result, L" 0b00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a positive number and padding and precision. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%0#25.20b %d", 12345, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* Neither ISO C nor POSIX specify that the '0' flag is ignored when
+ a width and a precision are both present. But implementations do so. */
+ ASSERT (wcscmp (result, L" 0b00000011000000111001 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+
+ { /* FLAG_ALT with a zero precision and a zero number. */
+ size_t length;
+ wchar_t *result =
+ my_asnwprintf (NULL, &length, L"%#.0b %d", 0, 33, 44, 55);
+ ASSERT (result != NULL);
+ /* ISO C and POSIX specify that "The result of converting a zero value
+ with a precision of zero is no characters.", and the prefix is added
+ only for non-zero values. */
+ ASSERT (wcscmp (result, L" 33") == 0);
+ ASSERT (length == wcslen (result));
+ free (result);
+ }
+}
+
+static wchar_t *
+my_asnwprintf (wchar_t *resultbuf, size_t *lengthp, const wchar_t *format, ...)
+{
+ va_list args;
+ wchar_t *ret;
+
+ va_start (args, format);
+ ret = vasnwprintf (resultbuf, lengthp, format, args);
+ va_end (args);
+ return ret;
+}
+
+static void
+test_vasnwprintf ()
+{
+ test_function (my_asnwprintf);
+}
+
+static void
+test_asnwprintf ()
+{
+ test_function (asnwprintf);
+}
+
+int
+main (int argc, char *argv[])
+{
+ test_vasnwprintf ();
+ test_asnwprintf ();
+ return 0;
+}
--
2.34.1
[-- Attachment #31: 0030-xvasprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 1550 bytes --]
From 87493c24eca1aad255f6fa72035d701a36db131e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:18:24 +0100
Subject: [PATCH 30/31] xvasprintf-gnu: New module.
* modules/xvasprintf-gnu: New file, based on modules/xvasprintf-posix.
---
ChangeLog | 5 +++++
modules/xvasprintf-gnu | 28 ++++++++++++++++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 modules/xvasprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 45d26931cb..661b00942e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ xvasprintf-gnu: New module.
+ * modules/xvasprintf-gnu: New file, based on modules/xvasprintf-posix.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
vasnwprintf-gnu: Add tests.
diff --git a/modules/xvasprintf-gnu b/modules/xvasprintf-gnu
new file mode 100644
index 0000000000..e458046b6a
--- /dev/null
+++ b/modules/xvasprintf-gnu
@@ -0,0 +1,28 @@
+Description:
+vasprintf and asprintf with POSIX and GNU compatible format string
+interpretation and with out-of-memory checking. Also see xalloc-die.
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+
+Depends-on:
+xvasprintf
+vasprintf-gnu
+
+configure.ac:
+
+Makefile.am:
+
+Include:
+"xvasprintf.h"
+
+License:
+GPL
+
+Maintainer:
+all
--
2.34.1
[-- Attachment #32: 0031-xprintf-gnu-New-module.patch --]
[-- Type: text/x-patch, Size: 1572 bytes --]
From d4bf26d359cf758bee20b907352c5db68dda19d4 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Fri, 24 Mar 2023 12:20:26 +0100
Subject: [PATCH 31/31] xprintf-gnu: New module.
* modules/xprintf-gnu: New file, based on modules/vasnprintf-gnu and
modules/xprintf-posix.
---
ChangeLog | 6 ++++++
modules/xprintf-gnu | 29 +++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 modules/xprintf-gnu
diff --git a/ChangeLog b/ChangeLog
index 661b00942e..1a807e06c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2023-03-24 Bruno Haible <bruno@clisp.org>
+
+ xprintf-gnu: New module.
+ * modules/xprintf-gnu: New file, based on modules/vasnprintf-gnu and
+ modules/xprintf-posix.
+
2023-03-24 Bruno Haible <bruno@clisp.org>
xvasprintf-gnu: New module.
diff --git a/modules/xprintf-gnu b/modules/xprintf-gnu
new file mode 100644
index 0000000000..c0fd3f062b
--- /dev/null
+++ b/modules/xprintf-gnu
@@ -0,0 +1,29 @@
+Description:
+A wrapper around printf with POSIX and GNU compatible format string
+interpretation, that calls error upon ENOMEM or EILSEQ errors.
+
+Comment:
+This module should not be used as a dependency from a test module,
+otherwise when this module occurs as a tests-related module, it will
+have side effects on the compilation of the 'vasnprintf' module, if
+that module occurs among the main modules in lib/.
+
+Files:
+
+Depends-on:
+xprintf
+vprintf-gnu
+vfprintf-gnu
+
+configure.ac:
+
+Makefile.am:
+
+Include:
+"xprintf.h"
+
+License:
+GPL
+
+Maintainer:
+all
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: new modules *printf-gnu
2023-03-24 11:37 ` new modules *printf-gnu Bruno Haible
@ 2023-03-24 16:11 ` Eric Blake
2023-03-25 0:29 ` Bruno Haible
0 siblings, 1 reply; 9+ messages in thread
From: Eric Blake @ 2023-03-24 16:11 UTC (permalink / raw)
To: Bruno Haible; +Cc: Pádraig Brady, bug-gnulib
On Fri, Mar 24, 2023 at 12:37:42PM +0100, Bruno Haible wrote:
> Eric Blake wrote in
> <https://lists.gnu.org/archive/html/bug-gnulib/2023-03/msg00060.html>:
> > C23 admits that %#B is not available for
> > portable use of outputting uppercase '0B...', you would have to
> > manually write 0B%b instead. However, since glibc DOES support %B as
> > the uppercase counterpart to %b, should we add that in gnulib (but
> > this time under the auspices of *printf-gnu, rather than
> > *printf-posix)?
>
> Nice idea. I was pondering what to do with the wording in ISO C23
> "Implementations that did not use an uppercase B as their own
> extension before are encouraged to implement it similar to
> conversion specifier b as standardized above, with the
> alternative form (#B) generating 0B as prefix for nonzero values."
>
> "encouraged" - should we add it to the *printf-posix modules or not?
>
Ah, the fun of chasing a spec still in progress
> Your suggestion to put it under *printf-gnu, that being an extension
> of *printf-posix, makes perfect sense, since glibc implements %B
> since version 2.35. Implemented as follows.
The latest draft comments on C go a step further (warning, big document):
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3091.doc
Searching that for %B finds:
FR-217
Make %B optional
Accepted with comment: Wording from N 3072 section 15 with editorial corrections
so now go check N3072:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3072.htm#make-printf-format-specifier-b-optional
which states that the PRIBPTR in <inttype.h> is now a reliable witness
of whether %B has C23 semantics rather than other
implementation-defined semantics.
and glibc has updated their %B implementation accordingly:
https://sourceware.org/git/?p=glibc.git;a=commit;h=2d4728e60621
| Update printf %b/%B C2x support
|
| WG14 recently accepted two additions to the printf/scanf %b/%B
| support: there are now PRIb* and SCNb* macros in <inttypes.h>, and
| printf %B is now an optional feature defined in normative text,
| instead of recommended practice, with corresponding PRIB* macros that
| can also be used to test whether that optional feature is supported.
| See N3072 items 14 and 15 for details (those changes were accepted,
| some other changes in that paper weren't).
|
| Add the corresponding PRI* macros to glibc and update one place in the
| manual referring to %B as recommended. (SCNb* should naturally be
| added at the same time as the corresponding scanf %b support.)
Since %B is optional (but now MUST have a reliable PRIBPTR witness
macro), I could see still keeping it in only the gnu-*printf variants.
Or we can just state that we are going to blindly define PRIBPTR in
inttypes.h if the posix-*printf variants are in use. Either way, you
probably want to work on followup patches that take PRIBPTR into
account.
Thanks for all your work on this, by the way!
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: new modules *printf-gnu
2023-03-24 16:11 ` Eric Blake
@ 2023-03-25 0:29 ` Bruno Haible
2023-03-25 0:34 ` Paul Eggert
0 siblings, 1 reply; 9+ messages in thread
From: Bruno Haible @ 2023-03-25 0:29 UTC (permalink / raw)
To: Eric Blake; +Cc: Pádraig Brady, bug-gnulib
Hi Eric,
Thanks for the pointers.
> The latest draft comments on C go a step further (warning, big document):
> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3091.doc
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3108.doc
seems to be the latest one, now.
> Searching that for %B finds:
> FR-217
> Make %B optional
> Accepted with comment: Wording from N 3072 section 15 with editorial corrections
>
> so now go check N3072:
> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3072.htm#make-printf-format-specifier-b-optional
>
> which states that the PRIBPTR in <inttypes.h> is now a reliable witness
> of whether %B has C23 semantics rather than other
> implementation-defined semantics.
>
> and glibc has updated their %B implementation accordingly:
> https://sourceware.org/git/?p=glibc.git;a=commit;h=2d4728e60621
The implementation could be to define a C macro or AC_SUBSTed variable in
gl_PREREQ_VASNPRINTF_DIRECTIVE_UPPERCASE_B
and test it in inttypes.in.h.
But still, I don't wish to make this change to Gnulib's <inttypes.h> for the
moment, because:
* Logically, there should also be definitions of
PRIbN PRIbLEASTN PRIbFASTN PRIbMAX PRIbPTR
in <inttypes.h>, but I do not see them in the latest complete PDF
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3088.pdf
section 7.8.1.(3).
* These macros are redundant anyway:
PRIb8 "w8b"
PRIb16 "w16b"
PRIb32 "w32b"
PRIb64 "w64b"
PRIbLEAST8 "w8b"
PRIbLEAST16 "w16b"
PRIbLEAST32 "w32b"
PRIbLEAST64 "w64b"
PRIbFAST8 "wf8b"
PRIbFAST16 "wf16b"
PRIbFAST32 "wf32b"
PRIbFAST64 "wf64b"
PRIbMAX "jb"
and likewise for uppercase B.
Bruno
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: new modules *printf-gnu
2023-03-25 0:29 ` Bruno Haible
@ 2023-03-25 0:34 ` Paul Eggert
2023-03-25 0:40 ` Bruno Haible
0 siblings, 1 reply; 9+ messages in thread
From: Paul Eggert @ 2023-03-25 0:34 UTC (permalink / raw)
To: Bruno Haible; +Cc: Pádraig Brady, bug-gnulib, Eric Blake
On 2023-03-24 17:29, Bruno Haible wrote:
> * Logically, there should also be definitions of
> PRIbN PRIbLEASTN PRIbFASTN PRIbMAX PRIbPTR
> in <inttypes.h>, but I do not see them in the latest complete PDF
> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3088.pdf
> section 7.8.1.(3).
> * These macros are redundant anyway:
Aren't they omitted because they would indeed be redundant?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: new modules *printf-gnu
2023-03-25 0:34 ` Paul Eggert
@ 2023-03-25 0:40 ` Bruno Haible
0 siblings, 0 replies; 9+ messages in thread
From: Bruno Haible @ 2023-03-25 0:40 UTC (permalink / raw)
To: Paul Eggert; +Cc: Pádraig Brady, bug-gnulib, Eric Blake
Paul Eggert wrote:
> > * Logically, there should also be definitions of
> > PRIbN PRIbLEASTN PRIbFASTN PRIbMAX PRIbPTR
> > in <inttypes.h>, but I do not see them in the latest complete PDF
> > https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3088.pdf
> > section 7.8.1.(3).
> > * These macros are redundant anyway:
>
> Aren't they omitted because they would indeed be redundant?
Well, glibc has PRIb* already in <inttypes.h>. [1] Would Joseph Myers
have added them if they were not in ISO C 23?
Really, I find it hard to follow the evolution of a standard, without
access to the latest complete document.
Bruno
[1] https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=2d4728e60621
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-03-25 0:40 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-17 21:51 *printf-posix: ISO C 23: Add %b directive for binary output of integers Bruno Haible
2023-03-18 11:50 ` Pádraig Brady
2023-03-18 12:47 ` Eric Blake
2023-03-24 11:37 ` new modules *printf-gnu Bruno Haible
2023-03-24 16:11 ` Eric Blake
2023-03-25 0:29 ` Bruno Haible
2023-03-25 0:34 ` Paul Eggert
2023-03-25 0:40 ` Bruno Haible
2023-03-22 21:13 ` *printf-posix: ISO C 23: Add %b directive for binary output of integers Bruno Haible
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).