1 /* Test scanf functions with C23 binary integers.
2 Copyright (C) 2022-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
24 #include <libc-diag.h>
25 #include <support/check.h>
26 #include <support/xstdio.h>
28 #define CONCAT_(X, Y, Z) X ## Y ## Z
29 #define CONCAT(X, Y, Z) CONCAT_ (X, Y, Z)
30 #define FNX(FN1, FN2) CONCAT (FN1, FNW, FN2)
35 #define INFILE OBJPFX "/tst-" STDX "scanf-binary-" STD "-in"
38 wrap_vfscanf (FILE *fp
, const CHAR
*format
, ...)
41 va_start (ap
, format
);
42 int ret
= FNX (vf
, scanf
) (fp
, format
, ap
);
48 wrap_vscanf (const CHAR
*format
, ...)
51 va_start (ap
, format
);
52 int ret
= FNX (v
, scanf
) (format
, ap
);
58 wrap_vsscanf (const CHAR
*s
, const CHAR
*format
, ...)
61 va_start (ap
, format
);
62 int ret
= FNX (vs
, scanf
) (s
, format
, ap
);
68 one_check (const CHAR
*s
, int expected
, char expected_c
)
76 fp
= xfopen (INFILE
, "w");
77 ret
= FNX (fput
, s
) (s
, fp
);
78 TEST_VERIFY_EXIT (0 <= ret
);
84 expected_c
= s
[0] == L_('-') ? s
[2] : s
[1];
87 ret
= FNX (s
, scanf
) (s
, L_("%i %c"), &ret_i
, &ret_c
);
88 TEST_COMPARE (ret
, 2);
89 TEST_COMPARE (ret_i
, expected
);
90 TEST_COMPARE (ret_c
, expected_c
);
91 fp
= xfopen (INFILE
, "r");
92 ret
= FNX (f
, scanf
) (fp
, L_("%i %c"), &ret_i
, &ret_c
);
93 TEST_COMPARE (ret
, 2);
94 TEST_COMPARE (ret_i
, expected
);
95 TEST_COMPARE (ret_c
, expected_c
);
97 fp
= xfreopen (INFILE
, "r", stdin
);
98 ret
= FNX (, scanf
) (L_("%i %c"), &ret_i
, &ret_c
);
99 TEST_COMPARE (ret
, 2);
100 TEST_COMPARE (ret_i
, expected
);
101 TEST_COMPARE (ret_c
, expected_c
);
102 ret
= wrap_vsscanf (s
, L_("%i %c"), &ret_i
, &ret_c
);
103 TEST_COMPARE (ret
, 2);
104 TEST_COMPARE (ret_i
, expected
);
105 TEST_COMPARE (ret_c
, expected_c
);
106 fp
= xfopen (INFILE
, "r");
107 ret
= wrap_vfscanf (fp
, L_("%i %c"), &ret_i
, &ret_c
);
108 TEST_COMPARE (ret
, 2);
109 TEST_COMPARE (ret_i
, expected
);
110 TEST_COMPARE (ret_c
, expected_c
);
112 fp
= xfreopen (INFILE
, "r", stdin
);
113 ret
= wrap_vscanf (L_("%i %c"), &ret_i
, &ret_c
);
114 TEST_COMPARE (ret
, 2);
115 TEST_COMPARE (ret_i
, expected
);
116 TEST_COMPARE (ret_c
, expected_c
);
118 ret
= FNX (s
, scanf
) (s
, L_("%li %c"), &ret_l
, &ret_c
);
119 TEST_COMPARE (ret
, 2);
120 TEST_COMPARE (ret_l
, expected
);
121 TEST_COMPARE (ret_c
, expected_c
);
122 fp
= xfopen (INFILE
, "r");
123 ret
= FNX (f
, scanf
) (fp
, L_("%li %c"), &ret_l
, &ret_c
);
124 TEST_COMPARE (ret
, 2);
125 TEST_COMPARE (ret_l
, expected
);
126 TEST_COMPARE (ret_c
, expected_c
);
128 fp
= xfreopen (INFILE
, "r", stdin
);
129 ret
= FNX (, scanf
) (L_("%li %c"), &ret_l
, &ret_c
);
130 TEST_COMPARE (ret
, 2);
131 TEST_COMPARE (ret_l
, expected
);
132 TEST_COMPARE (ret_c
, expected_c
);
133 ret
= wrap_vsscanf (s
, L_("%li %c"), &ret_l
, &ret_c
);
134 TEST_COMPARE (ret
, 2);
135 TEST_COMPARE (ret_l
, expected
);
136 TEST_COMPARE (ret_c
, expected_c
);
137 fp
= xfopen (INFILE
, "r");
138 ret
= wrap_vfscanf (fp
, L_("%li %c"), &ret_l
, &ret_c
);
139 TEST_COMPARE (ret
, 2);
140 TEST_COMPARE (ret_l
, expected
);
141 TEST_COMPARE (ret_c
, expected_c
);
143 fp
= xfreopen (INFILE
, "r", stdin
);
144 ret
= wrap_vscanf (L_("%li %c"), &ret_l
, &ret_c
);
145 TEST_COMPARE (ret
, 2);
146 TEST_COMPARE (ret_l
, expected
);
147 TEST_COMPARE (ret_c
, expected_c
);
149 ret
= FNX (s
, scanf
) (s
, L_("%lli %c"), &ret_ll
, &ret_c
);
150 TEST_COMPARE (ret
, 2);
151 TEST_COMPARE (ret_ll
, expected
);
152 TEST_COMPARE (ret_c
, expected_c
);
153 fp
= xfopen (INFILE
, "r");
154 ret
= FNX (f
, scanf
) (fp
, L_("%lli %c"), &ret_ll
, &ret_c
);
155 TEST_COMPARE (ret
, 2);
156 TEST_COMPARE (ret_ll
, expected
);
157 TEST_COMPARE (ret_c
, expected_c
);
159 fp
= xfreopen (INFILE
, "r", stdin
);
160 ret
= FNX (, scanf
) (L_("%lli %c"), &ret_ll
, &ret_c
);
161 TEST_COMPARE (ret
, 2);
162 TEST_COMPARE (ret_ll
, expected
);
163 TEST_COMPARE (ret_c
, expected_c
);
164 ret
= wrap_vsscanf (s
, L_("%lli %c"), &ret_ll
, &ret_c
);
165 TEST_COMPARE (ret
, 2);
166 TEST_COMPARE (ret_ll
, expected
);
167 TEST_COMPARE (ret_c
, expected_c
);
168 fp
= xfopen (INFILE
, "r");
169 ret
= wrap_vfscanf (fp
, L_("%lli %c"), &ret_ll
, &ret_c
);
170 TEST_COMPARE (ret
, 2);
171 TEST_COMPARE (ret_ll
, expected
);
172 TEST_COMPARE (ret_c
, expected_c
);
174 fp
= xfreopen (INFILE
, "r", stdin
);
175 ret
= wrap_vscanf (L_("%lli %c"), &ret_ll
, &ret_c
);
176 TEST_COMPARE (ret
, 2);
177 TEST_COMPARE (ret_ll
, expected
);
178 TEST_COMPARE (ret_c
, expected_c
);
181 /* GCC does not know the %b format before GCC 12. */
182 DIAG_PUSH_NEEDS_COMMENT
;
183 #if !__GNUC_PREREQ (12, 0)
184 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wformat");
185 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wformat-extra-args");
189 one_check_b (const CHAR
*s
, int expected
, char expected_c
)
194 unsigned long int ret_l
;
195 unsigned long long int ret_ll
;
197 fp
= xfopen (INFILE
, "w");
198 ret
= FNX (fput
, s
) (s
, fp
);
199 TEST_VERIFY_EXIT (0 <= ret
);
202 ret
= FNX (s
, scanf
) (s
, L_("%b %c"), &ret_i
, &ret_c
);
203 TEST_COMPARE (ret
, 2);
204 TEST_COMPARE (ret_i
, (unsigned int) expected
);
205 TEST_COMPARE (ret_c
, expected_c
);
206 fp
= xfopen (INFILE
, "r");
207 ret
= FNX (f
, scanf
) (fp
, L_("%b %c"), &ret_i
, &ret_c
);
208 TEST_COMPARE (ret
, 2);
209 TEST_COMPARE (ret_i
, (unsigned int) expected
);
210 TEST_COMPARE (ret_c
, expected_c
);
212 fp
= xfreopen (INFILE
, "r", stdin
);
213 ret
= FNX (, scanf
) (L_("%b %c"), &ret_i
, &ret_c
);
214 TEST_COMPARE (ret
, 2);
215 TEST_COMPARE (ret_i
, (unsigned int) expected
);
216 TEST_COMPARE (ret_c
, expected_c
);
217 ret
= wrap_vsscanf (s
, L_("%b %c"), &ret_i
, &ret_c
);
218 TEST_COMPARE (ret
, 2);
219 TEST_COMPARE (ret_i
, (unsigned int) expected
);
220 TEST_COMPARE (ret_c
, expected_c
);
221 fp
= xfopen (INFILE
, "r");
222 ret
= wrap_vfscanf (fp
, L_("%b %c"), &ret_i
, &ret_c
);
223 TEST_COMPARE (ret
, 2);
224 TEST_COMPARE (ret_i
, (unsigned int) expected
);
225 TEST_COMPARE (ret_c
, expected_c
);
227 fp
= xfreopen (INFILE
, "r", stdin
);
228 ret
= wrap_vscanf (L_("%b %c"), &ret_i
, &ret_c
);
229 TEST_COMPARE (ret
, 2);
230 TEST_COMPARE (ret_i
, (unsigned int) expected
);
231 TEST_COMPARE (ret_c
, expected_c
);
233 ret
= FNX (s
, scanf
) (s
, L_("%lb %c"), &ret_l
, &ret_c
);
234 TEST_COMPARE (ret
, 2);
235 TEST_COMPARE (ret_l
, (unsigned long int) expected
);
236 TEST_COMPARE (ret_c
, expected_c
);
237 fp
= xfopen (INFILE
, "r");
238 ret
= FNX (f
, scanf
) (fp
, L_("%lb %c"), &ret_l
, &ret_c
);
239 TEST_COMPARE (ret
, 2);
240 TEST_COMPARE (ret_l
, (unsigned long int) expected
);
241 TEST_COMPARE (ret_c
, expected_c
);
243 fp
= xfreopen (INFILE
, "r", stdin
);
244 ret
= FNX (, scanf
) (L_("%lb %c"), &ret_l
, &ret_c
);
245 TEST_COMPARE (ret
, 2);
246 TEST_COMPARE (ret_l
, (unsigned long int) expected
);
247 TEST_COMPARE (ret_c
, expected_c
);
248 ret
= wrap_vsscanf (s
, L_("%lb %c"), &ret_l
, &ret_c
);
249 TEST_COMPARE (ret
, 2);
250 TEST_COMPARE (ret_l
, (unsigned long int) expected
);
251 TEST_COMPARE (ret_c
, expected_c
);
252 fp
= xfopen (INFILE
, "r");
253 ret
= wrap_vfscanf (fp
, L_("%lb %c"), &ret_l
, &ret_c
);
254 TEST_COMPARE (ret
, 2);
255 TEST_COMPARE (ret_l
, (unsigned long int) expected
);
256 TEST_COMPARE (ret_c
, expected_c
);
258 fp
= xfreopen (INFILE
, "r", stdin
);
259 ret
= wrap_vscanf (L_("%lb %c"), &ret_l
, &ret_c
);
260 TEST_COMPARE (ret
, 2);
261 TEST_COMPARE (ret_l
, (unsigned long int) expected
);
262 TEST_COMPARE (ret_c
, expected_c
);
264 ret
= FNX (s
, scanf
) (s
, L_("%llb %c"), &ret_ll
, &ret_c
);
265 TEST_COMPARE (ret
, 2);
266 TEST_COMPARE (ret_ll
, (unsigned long long int) expected
);
267 TEST_COMPARE (ret_c
, expected_c
);
268 fp
= xfopen (INFILE
, "r");
269 ret
= FNX (f
, scanf
) (fp
, L_("%llb %c"), &ret_ll
, &ret_c
);
270 TEST_COMPARE (ret
, 2);
271 TEST_COMPARE (ret_ll
, (unsigned long long int) expected
);
272 TEST_COMPARE (ret_c
, expected_c
);
274 fp
= xfreopen (INFILE
, "r", stdin
);
275 ret
= FNX (, scanf
) (L_("%llb %c"), &ret_ll
, &ret_c
);
276 TEST_COMPARE (ret
, 2);
277 TEST_COMPARE (ret_ll
, (unsigned long long int) expected
);
278 TEST_COMPARE (ret_c
, expected_c
);
279 ret
= wrap_vsscanf (s
, L_("%llb %c"), &ret_ll
, &ret_c
);
280 TEST_COMPARE (ret
, 2);
281 TEST_COMPARE (ret_ll
, (unsigned long long int) expected
);
282 TEST_COMPARE (ret_c
, expected_c
);
283 fp
= xfopen (INFILE
, "r");
284 ret
= wrap_vfscanf (fp
, L_("%llb %c"), &ret_ll
, &ret_c
);
285 TEST_COMPARE (ret
, 2);
286 TEST_COMPARE (ret_ll
, (unsigned long long int) expected
);
287 TEST_COMPARE (ret_c
, expected_c
);
289 fp
= xfreopen (INFILE
, "r", stdin
);
290 ret
= wrap_vscanf (L_("%llb %c"), &ret_ll
, &ret_c
);
291 TEST_COMPARE (ret
, 2);
292 TEST_COMPARE (ret_ll
, (unsigned long long int) expected
);
293 TEST_COMPARE (ret_c
, expected_c
);
296 #define CHECK_SCNB(TYPE, MACRO, S, EXPECTED, EXPECTED_C) \
303 fp = xfopen (INFILE, "w"); \
304 ret = FNX (fput, s) (S, fp); \
305 TEST_VERIFY_EXIT (0 <= ret); \
307 ret = FNX (s, scanf) (S, L_("%") MACRO " %c", &ret_t, &ret_c); \
308 TEST_COMPARE (ret, 2); \
309 TEST_COMPARE (ret_t, EXPECTED); \
310 TEST_COMPARE (ret_c, EXPECTED_C); \
311 fp = xfopen (INFILE, "r"); \
312 ret = FNX (f, scanf) (fp, L_("%") MACRO " %c", &ret_t, &ret_c); \
313 TEST_COMPARE (ret, 2); \
314 TEST_COMPARE (ret_t, EXPECTED); \
315 TEST_COMPARE (ret_c, EXPECTED_C); \
317 fp = xfreopen (INFILE, "r", stdin); \
318 ret = FNX (, scanf) (L_("%") MACRO " %c", &ret_t, &ret_c); \
319 TEST_COMPARE (ret, 2); \
320 TEST_COMPARE (ret_t, EXPECTED); \
321 TEST_COMPARE (ret_c, EXPECTED_C); \
322 ret = wrap_vsscanf (S, L_("%") MACRO " %c", &ret_t, &ret_c); \
323 TEST_COMPARE (ret, 2); \
324 TEST_COMPARE (ret_t, EXPECTED); \
325 TEST_COMPARE (ret_c, EXPECTED_C); \
326 fp = xfopen (INFILE, "r"); \
327 ret = wrap_vfscanf (fp, L_("%") MACRO " %c", &ret_t, &ret_c); \
328 TEST_COMPARE (ret, 2); \
329 TEST_COMPARE (ret_t, EXPECTED); \
330 TEST_COMPARE (ret_c, EXPECTED_C); \
332 fp = xfreopen (INFILE, "r", stdin); \
333 ret = wrap_vscanf (L_("%") MACRO " %c", &ret_t, &ret_c); \
334 TEST_COMPARE (ret, 2); \
335 TEST_COMPARE (ret_t, EXPECTED); \
336 TEST_COMPARE (ret_c, EXPECTED_C); \
341 one_check_scnb (const CHAR
*s
, int expected
, char expected_c
)
343 #if TEST_C23 || defined _GNU_SOURCE
344 CHECK_SCNB (uint8_t, SCNb8
, s
, (uint8_t) expected
, expected_c
);
345 CHECK_SCNB (uint16_t, SCNb16
, s
, (uint16_t) expected
, expected_c
);
346 CHECK_SCNB (uint32_t, SCNb32
, s
, (uint32_t) expected
, expected_c
);
347 CHECK_SCNB (uint64_t, SCNb64
, s
, (uint64_t) expected
, expected_c
);
348 CHECK_SCNB (uint_least8_t, SCNbLEAST8
, s
, (uint_least8_t) expected
,
350 CHECK_SCNB (uint_least16_t, SCNbLEAST16
, s
, (uint_least16_t) expected
,
352 CHECK_SCNB (uint_least32_t, SCNbLEAST32
, s
, (uint_least32_t) expected
,
354 CHECK_SCNB (uint_least64_t, SCNbLEAST64
, s
, (uint_least64_t) expected
,
356 CHECK_SCNB (uint_fast8_t, SCNbFAST8
, s
, (uint_fast8_t) expected
, expected_c
);
357 CHECK_SCNB (uint_fast16_t, SCNbFAST16
, s
, (uint_fast16_t) expected
,
359 CHECK_SCNB (uint_fast32_t, SCNbFAST32
, s
, (uint_fast32_t) expected
,
361 CHECK_SCNB (uint_fast64_t, SCNbFAST64
, s
, (uint_fast64_t) expected
,
363 CHECK_SCNB (uintmax_t, SCNbMAX
, s
, (uintmax_t) expected
, expected_c
);
364 CHECK_SCNB (uintptr_t, SCNbPTR
, s
, (uintptr_t) expected
, expected_c
);
368 DIAG_POP_NEEDS_COMMENT
;
373 one_check (L_("0b101 x"), 5, 'x');
374 one_check (L_("0B101 x"), 5, 'x');
375 one_check (L_("-0b11111 y"), -31, 'y');
376 one_check (L_("-0B11111 y"), -31, 'y');
377 one_check_b (L_("0b101 x"), 5, 'x');
378 one_check_b (L_("0B101 x"), 5, 'x');
379 one_check_b (L_("-0b11111 y"), -31, 'y');
380 one_check_b (L_("-0B11111 y"), -31, 'y');
381 one_check_b (L_("101 x"), 5, 'x');
382 one_check_b (L_("-11111 y"), -31, 'y');
383 one_check_scnb (L_("0b101 x"), 5, 'x');
384 one_check_scnb (L_("0B101 x"), 5, 'x');
385 one_check_scnb (L_("-0b11111 y"), -31, 'y');
386 one_check_scnb (L_("-0B11111 y"), -31, 'y');
387 one_check_scnb (L_("101 x"), 5, 'x');
388 one_check_scnb (L_("-11111 y"), -31, 'y');
392 #include <support/test-driver.c>