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