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 | |
19 | TEST(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 | |
38 | TEST(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 | |
79 | TEST(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 | |
138 | TEST(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 | |
158 | TEST(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 | |
203 | TEST(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 | |
229 | TEST(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 | |
292 | TEST(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 | |
332 | TEST(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 | |
390 | TEST(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 | |
462 | TEST(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 | |
528 | TEST(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 | |
584 | TEST(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 | |
632 | TEST(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 | |
671 | TEST(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 | |