1//===-- Unittests for sscanf ----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "src/__support/CPP/limits.h"
10#include "src/__support/FPUtil/FPBits.h"
11
12#include "src/stdio/sscanf.h"
13
14#include <stdio.h> // For EOF
15
16#include "test/UnitTest/FPMatcher.h"
17#include "test/UnitTest/Test.h"
18
19TEST(LlvmLibcSScanfTest, SimpleStringConv) {
20 int ret_val;
21 char buffer[10];
22 char buffer2[10];
23 ret_val = LIBC_NAMESPACE::sscanf(buffer: "abc123", format: "abc %s", buffer);
24 ASSERT_EQ(ret_val, 1);
25 ASSERT_STREQ(buffer, "123");
26
27 ret_val = LIBC_NAMESPACE::sscanf(buffer: "abc123", format: "%3s %3s", buffer, buffer2);
28 ASSERT_EQ(ret_val, 2);
29 ASSERT_STREQ(buffer, "abc");
30 ASSERT_STREQ(buffer2, "123");
31
32 ret_val = LIBC_NAMESPACE::sscanf(buffer: "abc 123", format: "%3s%3s", buffer, buffer2);
33 ASSERT_EQ(ret_val, 2);
34 ASSERT_STREQ(buffer, "abc");
35 ASSERT_STREQ(buffer2, "123");
36}
37
38TEST(LlvmLibcSScanfTest, IntConvSimple) {
39 int ret_val;
40 int result = 0;
41 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%d", &result);
42 EXPECT_EQ(ret_val, 1);
43 EXPECT_EQ(result, 123);
44
45 ret_val = LIBC_NAMESPACE::sscanf(buffer: "456", format: "%i", &result);
46 EXPECT_EQ(ret_val, 1);
47 EXPECT_EQ(result, 456);
48
49 ret_val = LIBC_NAMESPACE::sscanf(buffer: "789", format: "%x", &result);
50 EXPECT_EQ(ret_val, 1);
51 EXPECT_EQ(result, 0x789);
52
53 ret_val = LIBC_NAMESPACE::sscanf(buffer: "012", format: "%o", &result);
54 EXPECT_EQ(ret_val, 1);
55 EXPECT_EQ(result, 012);
56
57 ret_val = LIBC_NAMESPACE::sscanf(buffer: "345", format: "%u", &result);
58 EXPECT_EQ(ret_val, 1);
59 EXPECT_EQ(result, 345);
60
61 // 288 characters
62 ret_val = LIBC_NAMESPACE::sscanf(buffer: "10000000000000000000000000000000"
63 "00000000000000000000000000000000"
64 "00000000000000000000000000000000"
65 "00000000000000000000000000000000"
66 "00000000000000000000000000000000"
67 "00000000000000000000000000000000"
68 "00000000000000000000000000000000"
69 "00000000000000000000000000000000"
70 "00000000000000000000000000000000",
71 format: "%d", &result);
72 EXPECT_EQ(ret_val, 1);
73 EXPECT_EQ(result, int(LIBC_NAMESPACE::cpp::numeric_limits<intmax_t>::max()));
74
75 ret_val = LIBC_NAMESPACE::sscanf(buffer: "Not an integer", format: "%d", &result);
76 EXPECT_EQ(ret_val, 0);
77}
78
79TEST(LlvmLibcSScanfTest, IntConvLengthModifier) {
80 int ret_val;
81 uintmax_t max_result = 0;
82 int int_result = 0;
83 char char_result = 0;
84
85 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%ju", &max_result);
86 EXPECT_EQ(ret_val, 1);
87 EXPECT_EQ(max_result, uintmax_t(123));
88
89 // Check overflow handling
90 ret_val = LIBC_NAMESPACE::sscanf(buffer: "999999999999999999999999999999999999",
91 format: "%ju", &max_result);
92 EXPECT_EQ(ret_val, 1);
93 EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
94
95 // Because this is unsigned, any out of range value should return the maximum,
96 // even with a negative sign.
97 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-999999999999999999999999999999999999",
98 format: "%ju", &max_result);
99 EXPECT_EQ(ret_val, 1);
100 EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
101
102 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-18446744073709551616", format: "%ju", &max_result);
103 EXPECT_EQ(ret_val, 1);
104 EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
105
106 // But any number below the maximum should have the - sign applied.
107 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-1", format: "%ju", &max_result);
108 EXPECT_EQ(ret_val, 1);
109 EXPECT_EQ(max_result, uintmax_t(-1));
110
111 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-1", format: "%u", &int_result);
112 EXPECT_EQ(ret_val, 1);
113 EXPECT_EQ(int_result, -1);
114
115 max_result = 0xff00ff00ff00ff00;
116 char_result = 0x6f;
117
118 // Overflows for sizes larger than the maximum are handled by casting.
119 ret_val = LIBC_NAMESPACE::sscanf(buffer: "8589967360", format: "%d", &int_result);
120 EXPECT_EQ(ret_val, 1);
121 EXPECT_EQ(int_result, int(8589967360)); // 2^33 + 2^15
122
123 // Check that the adjacent values weren't touched by the overflow.
124 ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
125 ASSERT_EQ(char_result, char(0x6f));
126
127 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-8589967360", format: "%d", &int_result);
128 EXPECT_EQ(ret_val, 1);
129 EXPECT_EQ(int_result, int(-8589967360));
130 ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
131 ASSERT_EQ(char_result, char(0x6f));
132
133 ret_val = LIBC_NAMESPACE::sscanf(buffer: "25", format: "%hhd", &char_result);
134 EXPECT_EQ(ret_val, 1);
135 EXPECT_EQ(char_result, char(25));
136}
137
138TEST(LlvmLibcSScanfTest, IntConvBaseSelection) {
139 int ret_val;
140 int result = 0;
141 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0xabc123", format: "%i", &result);
142 EXPECT_EQ(ret_val, 1);
143 EXPECT_EQ(result, 0xabc123);
144
145 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0456", format: "%i", &result);
146 EXPECT_EQ(ret_val, 1);
147 EXPECT_EQ(result, 0456);
148
149 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0999", format: "%i", &result);
150 EXPECT_EQ(ret_val, 1);
151 EXPECT_EQ(result, 0);
152
153 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123abc456", format: "%i", &result);
154 EXPECT_EQ(ret_val, 1);
155 EXPECT_EQ(result, 123);
156}
157
158TEST(LlvmLibcSScanfTest, IntConvMaxLengthTests) {
159 int ret_val;
160 int result = 0;
161
162 ret_val = LIBC_NAMESPACE::sscanf(buffer: "12", format: "%1d", &result);
163 EXPECT_EQ(ret_val, 1);
164 EXPECT_EQ(result, 1);
165
166 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-1", format: "%1d", &result);
167 EXPECT_EQ(ret_val, 0);
168 EXPECT_EQ(result, 0);
169
170 ret_val = LIBC_NAMESPACE::sscanf(buffer: "+1", format: "%1d", &result);
171 EXPECT_EQ(ret_val, 0);
172 EXPECT_EQ(result, 0);
173
174 ret_val = LIBC_NAMESPACE::sscanf(buffer: "01", format: "%1d", &result);
175 EXPECT_EQ(ret_val, 1);
176 EXPECT_EQ(result, 0);
177
178 ret_val = LIBC_NAMESPACE::sscanf(buffer: "01", format: "%1i", &result);
179 EXPECT_EQ(ret_val, 1);
180 EXPECT_EQ(result, 0);
181
182 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x1", format: "%2i", &result);
183 EXPECT_EQ(ret_val, 1);
184 EXPECT_EQ(result, 0);
185
186 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-0x1", format: "%3i", &result);
187 EXPECT_EQ(ret_val, 1);
188 EXPECT_EQ(result, 0);
189
190 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-0x123", format: "%4i", &result);
191 EXPECT_EQ(ret_val, 1);
192 EXPECT_EQ(result, -1);
193
194 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123456789", format: "%5i", &result);
195 EXPECT_EQ(ret_val, 1);
196 EXPECT_EQ(result, 12345);
197
198 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123456789", format: "%10i", &result);
199 EXPECT_EQ(ret_val, 1);
200 EXPECT_EQ(result, 123456789);
201}
202
203TEST(LlvmLibcSScanfTest, IntConvNoWriteTests) {
204 int ret_val;
205 // Result shouldn't be used by these tests, but it's safer to have it and
206 // check it.
207 int result = 0;
208 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-1", format: "%*1d", &result);
209 EXPECT_EQ(ret_val, 0);
210 EXPECT_EQ(result, 0);
211
212 ret_val = LIBC_NAMESPACE::sscanf(buffer: "01", format: "%*1i", &result);
213 EXPECT_EQ(ret_val, 1);
214 EXPECT_EQ(result, 0);
215
216 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x1", format: "%*2i", &result);
217 EXPECT_EQ(ret_val, 1);
218 EXPECT_EQ(result, 0);
219
220 ret_val = LIBC_NAMESPACE::sscanf(buffer: "a", format: "%*i", &result);
221 EXPECT_EQ(ret_val, 0);
222 EXPECT_EQ(result, 0);
223
224 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%*i", &result);
225 EXPECT_EQ(ret_val, 1);
226 EXPECT_EQ(result, 0);
227}
228
229TEST(LlvmLibcSScanfTest, FloatConvSimple) {
230 int ret_val;
231 float result = 0;
232
233 float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
234 float nan = LIBC_NAMESPACE::fputil::FPBits<float>::quiet_nan().get_val();
235
236 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%f", &result);
237 EXPECT_EQ(ret_val, 1);
238 EXPECT_FP_EQ(result, 123.0);
239
240 ret_val = LIBC_NAMESPACE::sscanf(buffer: "456.1", format: "%a", &result);
241 EXPECT_EQ(ret_val, 1);
242 EXPECT_FP_EQ(result, 456.1);
243
244 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x789.ap0", format: "%e", &result);
245 EXPECT_EQ(ret_val, 1);
246 EXPECT_FP_EQ(result, 0x789.ap0);
247
248 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x.8", format: "%e", &result);
249 EXPECT_EQ(ret_val, 1);
250 EXPECT_FP_EQ(result, 0x0.8p0);
251
252 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x8.", format: "%e", &result);
253 EXPECT_EQ(ret_val, 1);
254 EXPECT_FP_EQ(result, 0x8.0p0);
255
256 ret_val = LIBC_NAMESPACE::sscanf(buffer: "+12.0e1", format: "%g", &result);
257 EXPECT_EQ(ret_val, 1);
258 EXPECT_FP_EQ(result, 12.0e1);
259
260 ret_val = LIBC_NAMESPACE::sscanf(buffer: "inf", format: "%F", &result);
261 EXPECT_EQ(ret_val, 1);
262 EXPECT_FP_EQ(result, inf);
263
264 ret_val = LIBC_NAMESPACE::sscanf(buffer: "NaN", format: "%A", &result);
265 EXPECT_EQ(ret_val, 1);
266 EXPECT_FP_EQ(result, nan);
267
268 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-InFiNiTy", format: "%E", &result);
269 EXPECT_EQ(ret_val, 1);
270 EXPECT_FP_EQ(result, -inf);
271
272 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1e10", format: "%G", &result);
273 EXPECT_EQ(ret_val, 1);
274 EXPECT_FP_EQ(result, 1e10);
275
276 ret_val = LIBC_NAMESPACE::sscanf(buffer: ".1", format: "%G", &result);
277 EXPECT_EQ(ret_val, 1);
278 EXPECT_FP_EQ(result, 0.1);
279
280 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1.", format: "%G", &result);
281 EXPECT_EQ(ret_val, 1);
282 EXPECT_FP_EQ(result, 1.0);
283
284 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0", format: "%f", &result);
285 EXPECT_EQ(ret_val, 1);
286 EXPECT_FP_EQ(result, 0.0);
287
288 ret_val = LIBC_NAMESPACE::sscanf(buffer: "Not a float", format: "%f", &result);
289 EXPECT_EQ(ret_val, 0);
290}
291
292TEST(LlvmLibcSScanfTest, FloatConvLengthModifier) {
293 int ret_val;
294 double d_result = 0;
295 long double ld_result = 0;
296
297 double d_inf = LIBC_NAMESPACE::fputil::FPBits<double>::inf().get_val();
298 long double ld_nan =
299 LIBC_NAMESPACE::fputil::FPBits<long double>::quiet_nan().get_val();
300
301 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%lf", &d_result);
302 EXPECT_EQ(ret_val, 1);
303 EXPECT_FP_EQ(d_result, 123.0);
304
305 ret_val = LIBC_NAMESPACE::sscanf(buffer: "456.1", format: "%La", &ld_result);
306 EXPECT_EQ(ret_val, 1);
307 EXPECT_FP_EQ(ld_result, 456.1L);
308
309 ret_val = LIBC_NAMESPACE::sscanf(buffer: "inf", format: "%le", &d_result);
310 EXPECT_EQ(ret_val, 1);
311 EXPECT_FP_EQ(d_result, d_inf);
312
313 ret_val = LIBC_NAMESPACE::sscanf(buffer: "nan", format: "%Lg", &ld_result);
314 EXPECT_EQ(ret_val, 1);
315 EXPECT_FP_EQ(ld_result, ld_nan);
316
317 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1e-300", format: "%lF", &d_result);
318 EXPECT_EQ(ret_val, 1);
319 EXPECT_FP_EQ(d_result, 1e-300);
320
321 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1.0e600", format: "%LA", &ld_result);
322 EXPECT_EQ(ret_val, 1);
323// 1e600 may be larger than the maximum long double (if long double is double).
324// In that case both of these should be evaluated as inf.
325#ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
326 EXPECT_FP_EQ(ld_result, d_inf);
327#else
328 EXPECT_FP_EQ(ld_result, 1.0e600L);
329#endif
330}
331
332TEST(LlvmLibcSScanfTest, FloatConvLongNumber) {
333 int ret_val;
334 float result = 0;
335 double d_result = 0;
336
337 // 32 characters
338 ret_val =
339 LIBC_NAMESPACE::sscanf(buffer: "123456789012345678901234567890.0", format: "%f", &result);
340 EXPECT_EQ(ret_val, 1);
341 EXPECT_FP_EQ(result, 123456789012345678901234567890.0f);
342
343 // 64 characters
344 ret_val = LIBC_NAMESPACE::sscanf(
345 buffer: "123456789012345678901234567890123456789012345678901234567890.000", format: "%la",
346 &d_result);
347 EXPECT_EQ(ret_val, 1);
348 EXPECT_FP_EQ(
349 d_result,
350 123456789012345678901234567890123456789012345678901234567890.000);
351
352 // 128 characters
353 ret_val = LIBC_NAMESPACE::sscanf(
354 buffer: "123456789012345678901234567890123456789012345678901234567890"
355 "123456789012345678901234567890123456789012345678901234567890.0000000",
356 format: "%le", &d_result);
357 EXPECT_EQ(ret_val, 1);
358 EXPECT_FP_EQ(
359 d_result,
360 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.0000000);
361
362 // 256 characters
363 ret_val = LIBC_NAMESPACE::sscanf(buffer: "10000000000000000000000000000000"
364 "00000000000000000000000000000000"
365 "00000000000000000000000000000000"
366 "00000000000000000000000000000000"
367 "00000000000000000000000000000000"
368 "00000000000000000000000000000000"
369 "00000000000000000000000000000000"
370 "00000000000000000000000000000000",
371 format: "%lf", &d_result);
372 EXPECT_EQ(ret_val, 1);
373 EXPECT_FP_EQ(d_result, 1e255);
374
375 // 288 characters
376 ret_val = LIBC_NAMESPACE::sscanf(buffer: "10000000000000000000000000000000"
377 "00000000000000000000000000000000"
378 "00000000000000000000000000000000"
379 "00000000000000000000000000000000"
380 "00000000000000000000000000000000"
381 "00000000000000000000000000000000"
382 "00000000000000000000000000000000"
383 "00000000000000000000000000000000"
384 "00000000000000000000000000000000",
385 format: "%lf", &d_result);
386 EXPECT_EQ(ret_val, 1);
387 EXPECT_FP_EQ(d_result, 1e287);
388}
389
390TEST(LlvmLibcSScanfTest, FloatConvComplexParsing) {
391 int ret_val;
392 float result = 0;
393
394 float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
395 float nan = LIBC_NAMESPACE::fputil::FPBits<float>::quiet_nan().get_val();
396
397 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x1.0e3", format: "%f", &result);
398 EXPECT_EQ(ret_val, 1);
399 EXPECT_FP_EQ(result, 0x1.0e3p0);
400
401 ret_val = LIBC_NAMESPACE::sscanf(buffer: "", format: "%a", &result);
402 EXPECT_EQ(ret_val, 0);
403
404 ret_val = LIBC_NAMESPACE::sscanf(buffer: "+", format: "%a", &result);
405 EXPECT_EQ(ret_val, 0);
406
407 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-", format: "%a", &result);
408 EXPECT_EQ(ret_val, 0);
409
410 ret_val = LIBC_NAMESPACE::sscanf(buffer: "+.", format: "%a", &result);
411 EXPECT_EQ(ret_val, 0);
412
413 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-.e+10", format: "%a", &result);
414 EXPECT_EQ(ret_val, 0);
415
416 // This is a specific example from the standard. Its behavior diverges from
417 // other implementations that accept "100e" as being the same as "100e0"
418 ret_val = LIBC_NAMESPACE::sscanf(buffer: "100er", format: "%a", &result);
419 EXPECT_EQ(ret_val, 0);
420
421 ret_val = LIBC_NAMESPACE::sscanf(buffer: "nah", format: "%a", &result);
422 EXPECT_EQ(ret_val, 0);
423
424 ret_val = LIBC_NAMESPACE::sscanf(buffer: "indirection", format: "%a", &result);
425 EXPECT_EQ(ret_val, 0);
426
427 ret_val = LIBC_NAMESPACE::sscanf(buffer: "infnan", format: "%a", &result);
428 EXPECT_EQ(ret_val, 1);
429 EXPECT_FP_EQ(result, inf);
430
431 ret_val = LIBC_NAMESPACE::sscanf(buffer: "naninf", format: "%a", &result);
432 EXPECT_EQ(ret_val, 1);
433 EXPECT_FP_EQ(result, nan);
434
435 ret_val = LIBC_NAMESPACE::sscanf(buffer: "infinityinfinity", format: "%a", &result);
436 EXPECT_EQ(ret_val, 1);
437 EXPECT_FP_EQ(result, inf);
438
439 // For %f to accept a string as representing it has to be either "inf" or
440 // "infinity" when it stops. It only stops when it encounters a character that
441 // isn't the next one in the string, so it accepts "infi" as the the longest
442 // prefix of a possibly valid floating-point number, but determines that it is
443 // not valid and returns a matching failure. This is because it can only unget
444 // one character so when it finds that the character after the second 'i' is
445 // not the next character in "infinity" it can't rewind to the point where it
446 // had just "inf".
447 ret_val = LIBC_NAMESPACE::sscanf(buffer: "infi", format: "%a", &result);
448 EXPECT_EQ(ret_val, 0);
449
450 ret_val = LIBC_NAMESPACE::sscanf(buffer: "infinite", format: "%a", &result);
451 EXPECT_EQ(ret_val, 0);
452
453 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-.1e1", format: "%f", &result);
454 EXPECT_EQ(ret_val, 1);
455 EXPECT_FP_EQ(result, -.1e1);
456
457 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1.2.e1", format: "%f", &result);
458 EXPECT_EQ(ret_val, 1);
459 EXPECT_FP_EQ(result, 1.2);
460}
461
462TEST(LlvmLibcSScanfTest, FloatConvMaxWidth) {
463 int ret_val;
464 float result = 0;
465
466 float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
467
468 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%3f", &result);
469 EXPECT_EQ(ret_val, 1);
470 EXPECT_FP_EQ(result, 123.0);
471
472 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%5f", &result);
473 EXPECT_EQ(ret_val, 1);
474 EXPECT_FP_EQ(result, 123.0);
475
476 ret_val = LIBC_NAMESPACE::sscanf(buffer: "456", format: "%1f", &result);
477 EXPECT_EQ(ret_val, 1);
478 EXPECT_FP_EQ(result, 4.0);
479
480 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-789", format: "%1f", &result);
481 EXPECT_EQ(ret_val, 0);
482
483 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-123", format: "%2f", &result);
484 EXPECT_EQ(ret_val, 1);
485 EXPECT_FP_EQ(result, -1.0);
486
487 ret_val = LIBC_NAMESPACE::sscanf(buffer: "inf", format: "%2f", &result);
488 EXPECT_EQ(ret_val, 0);
489
490 ret_val = LIBC_NAMESPACE::sscanf(buffer: "nan", format: "%1f", &result);
491 EXPECT_EQ(ret_val, 0);
492
493 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-inf", format: "%3f", &result);
494 EXPECT_EQ(ret_val, 0);
495
496 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-nan", format: "%3f", &result);
497 EXPECT_EQ(ret_val, 0);
498
499 // If the max length were not here this would fail as discussed above, but
500 // since the max length limits it to the 3 it succeeds.
501 ret_val = LIBC_NAMESPACE::sscanf(buffer: "infinite", format: "%3f", &result);
502 EXPECT_EQ(ret_val, 1);
503 EXPECT_FP_EQ(result, inf);
504
505 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-infinite", format: "%4f", &result);
506 EXPECT_EQ(ret_val, 1);
507 EXPECT_FP_EQ(result, -inf);
508
509 ret_val = LIBC_NAMESPACE::sscanf(buffer: "01", format: "%1f", &result);
510 EXPECT_EQ(ret_val, 1);
511 EXPECT_FP_EQ(result, 0.0);
512
513 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x1", format: "%2f", &result);
514 EXPECT_EQ(ret_val, 1);
515 EXPECT_FP_EQ(result, 0.0);
516
517 ret_val = LIBC_NAMESPACE::sscanf(buffer: "100e", format: "%4f", &result);
518 EXPECT_EQ(ret_val, 0);
519
520 ret_val = LIBC_NAMESPACE::sscanf(buffer: "100e+10", format: "%5f", &result);
521 EXPECT_EQ(ret_val, 0);
522
523 ret_val = LIBC_NAMESPACE::sscanf(buffer: "100e10", format: "%5f", &result);
524 EXPECT_EQ(ret_val, 1);
525 EXPECT_FP_EQ(result, 100e1);
526}
527
528TEST(LlvmLibcSScanfTest, FloatConvNoWrite) {
529 int ret_val;
530 float result = 0;
531
532 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%*f", &result);
533 EXPECT_EQ(ret_val, 1);
534 EXPECT_FP_EQ(result, 0.0);
535
536 ret_val = LIBC_NAMESPACE::sscanf(buffer: "456.1", format: "%*a", &result);
537 EXPECT_EQ(ret_val, 1);
538 EXPECT_FP_EQ(result, 0.0);
539
540 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0x789.ap0", format: "%*e", &result);
541 EXPECT_EQ(ret_val, 1);
542 EXPECT_FP_EQ(result, 0.0);
543
544 ret_val = LIBC_NAMESPACE::sscanf(buffer: "+12.0e1", format: "%*g", &result);
545 EXPECT_EQ(ret_val, 1);
546 EXPECT_FP_EQ(result, 0.0);
547
548 ret_val = LIBC_NAMESPACE::sscanf(buffer: "inf", format: "%*F", &result);
549 EXPECT_EQ(ret_val, 1);
550 EXPECT_FP_EQ(result, 0.0);
551
552 ret_val = LIBC_NAMESPACE::sscanf(buffer: "NaN", format: "%*A", &result);
553 EXPECT_EQ(ret_val, 1);
554 EXPECT_FP_EQ(result, 0.0);
555
556 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-InFiNiTy", format: "%*E", &result);
557 EXPECT_EQ(ret_val, 1);
558 EXPECT_FP_EQ(result, 0.0);
559
560 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1e10", format: "%*G", &result);
561 EXPECT_EQ(ret_val, 1);
562 EXPECT_FP_EQ(result, 0.0);
563
564 ret_val = LIBC_NAMESPACE::sscanf(buffer: ".1", format: "%*G", &result);
565 EXPECT_EQ(ret_val, 1);
566 EXPECT_FP_EQ(result, 0.0);
567
568 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%*3f", &result);
569 EXPECT_EQ(ret_val, 1);
570 EXPECT_FP_EQ(result, 0.0);
571
572 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123", format: "%*5f", &result);
573 EXPECT_EQ(ret_val, 1);
574 EXPECT_FP_EQ(result, 0.0);
575
576 ret_val = LIBC_NAMESPACE::sscanf(buffer: "456", format: "%*1f", &result);
577 EXPECT_EQ(ret_val, 1);
578 EXPECT_FP_EQ(result, 0.0);
579
580 ret_val = LIBC_NAMESPACE::sscanf(buffer: "Not a float", format: "%*f", &result);
581 EXPECT_EQ(ret_val, 0);
582}
583
584TEST(LlvmLibcSScanfTest, CurPosCombined) {
585 int ret_val;
586 int result = -1;
587 char c_result = 0;
588
589 ret_val = LIBC_NAMESPACE::sscanf(buffer: "some text", format: "%n", &result);
590 // %n doesn't count as a conversion for the return value.
591 EXPECT_EQ(ret_val, 0);
592 EXPECT_EQ(result, 0);
593
594 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1234567890", format: "12345%n", &result);
595 EXPECT_EQ(ret_val, 0);
596 EXPECT_EQ(result, 5);
597
598 ret_val = LIBC_NAMESPACE::sscanf(buffer: "1234567890", format: "12345%n", &result);
599 EXPECT_EQ(ret_val, 0);
600 EXPECT_EQ(result, 5);
601
602 // 288 characters
603 ret_val = LIBC_NAMESPACE::sscanf(buffer: "10000000000000000000000000000000"
604 "00000000000000000000000000000000"
605 "00000000000000000000000000000000"
606 "00000000000000000000000000000000"
607 "00000000000000000000000000000000"
608 "00000000000000000000000000000000"
609 "00000000000000000000000000000000"
610 "00000000000000000000000000000000"
611 "00000000000000000000000000000000",
612 format: "%*d%hhn", &c_result);
613 EXPECT_EQ(ret_val, 1);
614 EXPECT_EQ(c_result, char(288)); // Overflow is handled by casting.
615
616 // 320 characters
617 ret_val = LIBC_NAMESPACE::sscanf(buffer: "10000000000000000000000000000000"
618 "00000000000000000000000000000000"
619 "00000000000000000000000000000000"
620 "00000000000000000000000000000000"
621 "00000000000000000000000000000000"
622 "00000000000000000000000000000000"
623 "00000000000000000000000000000000"
624 "00000000000000000000000000000000"
625 "00000000000000000000000000000000"
626 "00000000000000000000000000000000",
627 format: "%*d%n", &result);
628 EXPECT_EQ(ret_val, 1);
629 EXPECT_EQ(result, 320);
630}
631
632TEST(LlvmLibcSScanfTest, PointerConvCombined) {
633 int ret_val;
634 void *result;
635
636 ret_val = LIBC_NAMESPACE::sscanf(buffer: "(nullptr)", format: "%p", &result);
637 EXPECT_EQ(ret_val, 1);
638 EXPECT_EQ(result, static_cast<void *>(nullptr));
639
640 ret_val = LIBC_NAMESPACE::sscanf(buffer: "(NuLlPtR)", format: "%p", &result);
641 EXPECT_EQ(ret_val, 1);
642 EXPECT_EQ(result, static_cast<void *>(nullptr));
643
644 ret_val = LIBC_NAMESPACE::sscanf(buffer: "(NULLPTR)", format: "%p", &result);
645 EXPECT_EQ(ret_val, 1);
646 EXPECT_EQ(result, static_cast<void *>(nullptr));
647
648 ret_val = LIBC_NAMESPACE::sscanf(buffer: "(null)", format: "%p", &result);
649 EXPECT_EQ(ret_val, 0);
650
651 ret_val = LIBC_NAMESPACE::sscanf(buffer: "(nullptr2", format: "%p", &result);
652 EXPECT_EQ(ret_val, 0);
653
654 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0", format: "%p", &result);
655 EXPECT_EQ(ret_val, 1);
656 EXPECT_EQ(result, reinterpret_cast<void *>(0));
657
658 ret_val = LIBC_NAMESPACE::sscanf(buffer: "100", format: "%p", &result);
659 EXPECT_EQ(ret_val, 1);
660 EXPECT_EQ(result, reinterpret_cast<void *>(0x100));
661
662 ret_val = LIBC_NAMESPACE::sscanf(buffer: "-1", format: "%p", &result);
663 EXPECT_EQ(ret_val, 1);
664 EXPECT_EQ(result, reinterpret_cast<void *>(-1));
665
666 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0xabcDEFG", format: "%p", &result);
667 EXPECT_EQ(ret_val, 1);
668 EXPECT_EQ(result, reinterpret_cast<void *>(0xabcdef));
669}
670
671TEST(LlvmLibcSScanfTest, CombinedConv) {
672 int ret_val;
673 int result = 0;
674 char buffer[10];
675 ret_val = LIBC_NAMESPACE::sscanf(buffer: "123abc", format: "%i%s", &result, buffer);
676 EXPECT_EQ(ret_val, 2);
677 EXPECT_EQ(result, 123);
678 ASSERT_STREQ(buffer, "abc");
679
680 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0xZZZ", format: "%i%s", &result, buffer);
681 EXPECT_EQ(ret_val, 2);
682 EXPECT_EQ(result, 0);
683 ASSERT_STREQ(buffer, "ZZZ");
684
685 ret_val = LIBC_NAMESPACE::sscanf(buffer: "0xZZZ", format: "%X%s", &result, buffer);
686 EXPECT_EQ(ret_val, 2);
687 EXPECT_EQ(result, 0);
688 ASSERT_STREQ(buffer, "ZZZ");
689}
690

source code of libc/test/src/stdio/sscanf_test.cpp