1 /* Test binary printf formats.
2    Copyright (C) 2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <limits.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <wchar.h>
23 
24 #include <libc-diag.h>
25 #include <support/check.h>
26 
27 /* GCC does not know the %b or %B formats before GCC 12.  */
28 DIAG_PUSH_NEEDS_COMMENT;
29 #if !__GNUC_PREREQ (12, 0)
30 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wformat");
31 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wformat-extra-args");
32 #endif
33 
34 #define CHECK_PRINTF(EXPECTED, FMT, ...)				\
35   do									\
36     {									\
37       int ret = SNPRINTF (buf, sizeof buf / sizeof buf[0], L_(FMT),	\
38 			  __VA_ARGS__);					\
39       TEST_COMPARE_STRING_MACRO (buf, L_(EXPECTED));			\
40       TEST_COMPARE (ret, STRLEN (L_(EXPECTED)));			\
41     }									\
42   while (0)
43 
44 static int
do_test(void)45 do_test (void)
46 {
47   CHAR buf[1024];
48   CHECK_PRINTF ("0", "%b", 0u);
49   CHECK_PRINTF ("0", "%B", 0u);
50   CHECK_PRINTF ("0", "%#b", 0u);
51   CHECK_PRINTF ("0", "%#B", 0u);
52   CHECK_PRINTF ("1", "%b", 1u);
53   CHECK_PRINTF ("1", "%B", 1u);
54   CHECK_PRINTF ("10", "%b", 2u);
55   CHECK_PRINTF ("10", "%B", 2u);
56   CHECK_PRINTF ("11", "%b", 3u);
57   CHECK_PRINTF ("11", "%B", 3u);
58   CHECK_PRINTF ("10000111011001010100001100100001", "%b", 0x87654321);
59   CHECK_PRINTF ("10000111011001010100001100100001", "%B", 0x87654321);
60   CHECK_PRINTF ("100001100100001", "%hb", (int) 0x87654321);
61   CHECK_PRINTF ("100001100100001", "%hB", (int) 0x87654321);
62   CHECK_PRINTF ("100001", "%hhb", (int) 0x87654321);
63   CHECK_PRINTF ("100001", "%hhB", (int) 0x87654321);
64   CHECK_PRINTF ("10000111011001010100001100100001", "%lb", 0x87654321ul);
65   CHECK_PRINTF ("10000111011001010100001100100001", "%lB", 0x87654321ul);
66   CHECK_PRINTF ("11111110110111001011101010011001"
67 		"10000111011001010100001100100001", "%llb",
68 		0xfedcba9987654321ull);
69   CHECK_PRINTF ("11111110110111001011101010011001"
70 		"10000111011001010100001100100001", "%llB",
71 		0xfedcba9987654321ull);
72 #if LONG_WIDTH >= 64
73   CHECK_PRINTF ("11111110110111001011101010011001"
74 		"10000111011001010100001100100001", "%lb",
75 		0xfedcba9987654321ul);
76   CHECK_PRINTF ("11111110110111001011101010011001"
77 		"10000111011001010100001100100001", "%lB",
78 		0xfedcba9987654321ul);
79 #endif
80   CHECK_PRINTF (" 1010", "%5b", 10u);
81   CHECK_PRINTF (" 1010", "%5B", 10u);
82   CHECK_PRINTF ("01010", "%05b", 10u);
83   CHECK_PRINTF ("01010", "%05B", 10u);
84   CHECK_PRINTF ("1011 ", "%-5b", 11u);
85   CHECK_PRINTF ("1011 ", "%-5B", 11u);
86   CHECK_PRINTF ("0b10011", "%#b", 19u);
87   CHECK_PRINTF ("0B10011", "%#B", 19u);
88   CHECK_PRINTF ("   0b10011", "%#10b", 19u);
89   CHECK_PRINTF ("   0B10011", "%#10B", 19u);
90   CHECK_PRINTF ("0b00010011", "%0#10b", 19u);
91   CHECK_PRINTF ("0B00010011", "%0#10B", 19u);
92   CHECK_PRINTF ("0b00010011", "%#010b", 19u);
93   CHECK_PRINTF ("0B00010011", "%#010B", 19u);
94   CHECK_PRINTF ("0b10011   ", "%#-10b", 19u);
95   CHECK_PRINTF ("0B10011   ", "%#-10B", 19u);
96   CHECK_PRINTF ("00010011", "%.8b", 19u);
97   CHECK_PRINTF ("00010011", "%.8B", 19u);
98   CHECK_PRINTF ("0b00010011", "%#.8b", 19u);
99   CHECK_PRINTF ("0B00010011", "%#.8B", 19u);
100   CHECK_PRINTF ("       00010011", "%15.8b", 19u);
101   CHECK_PRINTF ("       00010011", "%15.8B", 19u);
102   CHECK_PRINTF ("00010011       ", "%-15.8b", 19u);
103   CHECK_PRINTF ("00010011       ", "%-15.8B", 19u);
104   CHECK_PRINTF ("     0b00010011", "%#15.8b", 19u);
105   CHECK_PRINTF ("     0B00010011", "%#15.8B", 19u);
106   CHECK_PRINTF ("0b00010011     ", "%-#15.8b", 19u);
107   CHECK_PRINTF ("0B00010011     ", "%-#15.8B", 19u);
108   /* GCC diagnoses ignored flags.  */
109   DIAG_PUSH_NEEDS_COMMENT;
110   DIAG_IGNORE_NEEDS_COMMENT (12, "-Wformat");
111   /* '0' flag ignored with '-'.  */
112   CHECK_PRINTF ("1011 ", "%0-5b", 11u);
113   CHECK_PRINTF ("1011 ", "%0-5B", 11u);
114   CHECK_PRINTF ("0b10011   ", "%#0-10b", 19u);
115   CHECK_PRINTF ("0B10011   ", "%#0-10B", 19u);
116   /* '0' flag ignored with precision.  */
117   CHECK_PRINTF ("       00010011", "%015.8b", 19u);
118   CHECK_PRINTF ("       00010011", "%015.8B", 19u);
119   CHECK_PRINTF ("     0b00010011", "%0#15.8b", 19u);
120   CHECK_PRINTF ("     0B00010011", "%0#15.8B", 19u);
121   DIAG_POP_NEEDS_COMMENT;
122   /* Test positional argument handling.  */
123   CHECK_PRINTF ("test 1011 test2 100010001000100010001000100010001",
124 		"%2$s %1$b %4$s %3$llb", 11u, "test", 0x111111111ull, "test2");
125   return 0;
126 }
127 
128 DIAG_POP_NEEDS_COMMENT;
129 
130 #include <support/test-driver.c>
131