diff mbox series

Update printf %b/%B C2x support

Message ID 75c3c46d-d35c-89ff-df4-dbd274375e1b@codesourcery.com
State New
Headers show
Series Update printf %b/%B C2x support | expand

Commit Message

Joseph Myers Feb. 24, 2023, 11:56 p.m. UTC
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.)

Tested for x86_64 and x86.

Comments

Joseph Myers March 13, 2023, 9:32 p.m. UTC | #1
Ping.  This patch 
<https://sourceware.org/pipermail/libc-alpha/2023-February/145882.html> is 
pending review.
Andreas Schwab March 14, 2023, 4:07 p.m. UTC | #2
On Feb 24 2023, Joseph Myers wrote:

> 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.)

Ok.
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index 080a2060d4..80e92f41ac 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,8 @@  Major new features:
   wcstoll, wcstoul, wcstoull, wcstol_l, wcstoll_l, wcstoul_l,
   wcstoull_l, wcstoimax, wcstoumax, wcstoq, wcstouq.
 
+* PRIb* and PRIB* macros from C2X have been added to <inttypes.h>.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/manual/stdio.texi b/manual/stdio.texi
index d7eab1843a..d89b6b2040 100644
--- a/manual/stdio.texi
+++ b/manual/stdio.texi
@@ -1829,7 +1829,7 @@  output, but are different when used with @code{scanf} for input
 Print an integer as an unsigned binary number.  @samp{%b} uses
 lower-case @samp{b} with the @samp{#} flag and @samp{%B} uses
 upper-case.  @samp{%b} is an ISO C2X feature; @samp{%B} is an
-extension recommended by ISO C2X.  @xref{Integer Conversions}, for
+optional ISO C2X feature.  @xref{Integer Conversions}, for
 details.
 
 @item @samp{%o}
diff --git a/stdio-common/tst-printf-binary-main.c b/stdio-common/tst-printf-binary-main.c
index e94b8b5959..0784368d85 100644
--- a/stdio-common/tst-printf-binary-main.c
+++ b/stdio-common/tst-printf-binary-main.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <inttypes.h>
 #include <limits.h>
 #include <stdio.h>
 #include <string.h>
@@ -77,6 +78,58 @@  do_test (void)
 		"10000111011001010100001100100001", "%lB",
 		0xfedcba9987654321ul);
 #endif
+  CHECK_PRINTF ("0b11", "%#" PRIb8, (uint8_t) 3);
+  CHECK_PRINTF ("0b11", "%#" PRIb16, (uint16_t) 3);
+  CHECK_PRINTF ("0b10000111011001010100001100100001", "%#" PRIb32,
+		(uint32_t) 0x87654321);
+  CHECK_PRINTF ("0b11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIb64,
+		(uint64_t) 0xfedcba9987654321ull);
+  CHECK_PRINTF ("0b11", "%#" PRIbLEAST8, (uint_least8_t) 3);
+  CHECK_PRINTF ("0b11", "%#" PRIbLEAST16, (uint_least16_t) 3);
+  CHECK_PRINTF ("0b10000111011001010100001100100001", "%#" PRIbLEAST32,
+		(uint_least32_t) 0x87654321);
+  CHECK_PRINTF ("0b11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIbLEAST64,
+		(uint_least64_t) 0xfedcba9987654321ull);
+  CHECK_PRINTF ("0b11", "%#" PRIbFAST8, (uint_fast8_t) 3);
+  CHECK_PRINTF ("0b11", "%#" PRIbFAST16, (uint_fast16_t) 3);
+  CHECK_PRINTF ("0b10000111011001010100001100100001", "%#" PRIbFAST32,
+		(uint_fast32_t) 0x87654321);
+  CHECK_PRINTF ("0b11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIbFAST64,
+		(uint_fast64_t) 0xfedcba9987654321ull);
+  CHECK_PRINTF ("0b10000111011001010100001100100001", "%#" PRIbPTR,
+		(uintptr_t) 0x87654321);
+  CHECK_PRINTF ("0b11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIbMAX,
+		(uintmax_t) 0xfedcba9987654321ull);
+  CHECK_PRINTF ("0B11", "%#" PRIB8, (uint8_t) 3);
+  CHECK_PRINTF ("0B11", "%#" PRIB16, (uint16_t) 3);
+  CHECK_PRINTF ("0B10000111011001010100001100100001", "%#" PRIB32,
+		(uint32_t) 0x87654321);
+  CHECK_PRINTF ("0B11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIB64,
+		(uint64_t) 0xfedcba9987654321ull);
+  CHECK_PRINTF ("0B11", "%#" PRIBLEAST8, (uint_least8_t) 3);
+  CHECK_PRINTF ("0B11", "%#" PRIBLEAST16, (uint_least16_t) 3);
+  CHECK_PRINTF ("0B10000111011001010100001100100001", "%#" PRIBLEAST32,
+		(uint_least32_t) 0x87654321);
+  CHECK_PRINTF ("0B11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIBLEAST64,
+		(uint_least64_t) 0xfedcba9987654321ull);
+  CHECK_PRINTF ("0B11", "%#" PRIBFAST8, (uint_fast8_t) 3);
+  CHECK_PRINTF ("0B11", "%#" PRIBFAST16, (uint_fast16_t) 3);
+  CHECK_PRINTF ("0B10000111011001010100001100100001", "%#" PRIBFAST32,
+		(uint_fast32_t) 0x87654321);
+  CHECK_PRINTF ("0B11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIBFAST64,
+		(uint_fast64_t) 0xfedcba9987654321ull);
+  CHECK_PRINTF ("0B10000111011001010100001100100001", "%#" PRIBPTR,
+		(uintptr_t) 0x87654321);
+  CHECK_PRINTF ("0B11111110110111001011101010011001"
+		"10000111011001010100001100100001", "%#" PRIBMAX,
+		(uintmax_t) 0xfedcba9987654321ull);
   CHECK_PRINTF (" 1010", "%5b", 10u);
   CHECK_PRINTF (" 1010", "%5B", 10u);
   CHECK_PRINTF ("01010", "%05b", 10u);
diff --git a/stdlib/inttypes.h b/stdlib/inttypes.h
index a5fa97b7c8..0ace21f54d 100644
--- a/stdlib/inttypes.h
+++ b/stdlib/inttypes.h
@@ -164,6 +164,45 @@  typedef wchar_t __gwchar_t;
 # define PRIxPTR	__PRIPTR_PREFIX "x"
 # define PRIXPTR	__PRIPTR_PREFIX "X"
 
+/* Binary notation.  */
+# if __GLIBC_USE (ISOC2X)
+#  define PRIb8		"b"
+#  define PRIb16	"b"
+#  define PRIb32	"b"
+#  define PRIb64	__PRI64_PREFIX "b"
+
+#  define PRIbLEAST8	"b"
+#  define PRIbLEAST16	"b"
+#  define PRIbLEAST32	"b"
+#  define PRIbLEAST64	__PRI64_PREFIX "b"
+
+#  define PRIbFAST8	"b"
+#  define PRIbFAST16	__PRIPTR_PREFIX "b"
+#  define PRIbFAST32	__PRIPTR_PREFIX "b"
+#  define PRIbFAST64	__PRI64_PREFIX "b"
+
+#  define PRIbMAX	__PRI64_PREFIX "b"
+#  define PRIbPTR	__PRIPTR_PREFIX "b"
+
+#  define PRIB8		"B"
+#  define PRIB16	"B"
+#  define PRIB32	"B"
+#  define PRIB64	__PRI64_PREFIX "B"
+
+#  define PRIBLEAST8	"B"
+#  define PRIBLEAST16	"B"
+#  define PRIBLEAST32	"B"
+#  define PRIBLEAST64	__PRI64_PREFIX "B"
+
+#  define PRIBFAST8	"B"
+#  define PRIBFAST16	__PRIPTR_PREFIX "B"
+#  define PRIBFAST32	__PRIPTR_PREFIX "B"
+#  define PRIBFAST64	__PRI64_PREFIX "B"
+
+#  define PRIBMAX	__PRI64_PREFIX "B"
+#  define PRIBPTR	__PRIPTR_PREFIX "B"
+# endif
+
 
 /* Macros for scanning format specifiers.  */