xref: /llvm-project/libc/test/src/stdio/sscanf_test.cpp (revision 0afe6e42fbab25b3b0d35921774bf2584bcd0d74)
136991d83SMichael Jones //===-- Unittests for sscanf ----------------------------------------------===//
236991d83SMichael Jones //
336991d83SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
436991d83SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
536991d83SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
636991d83SMichael Jones //
736991d83SMichael Jones //===----------------------------------------------------------------------===//
836991d83SMichael Jones 
936991d83SMichael Jones #include "src/stdio/sscanf.h"
1036991d83SMichael Jones 
11c63112a9Slntue #include "hdr/stdio_macros.h" // For EOF
12c63112a9Slntue #include "src/__support/CPP/limits.h"
13c63112a9Slntue #include "src/__support/FPUtil/FPBits.h"
14af1315c2SSiva Chandra Reddy #include "test/UnitTest/FPMatcher.h"
15af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h"
1636991d83SMichael Jones 
1736991d83SMichael Jones TEST(LlvmLibcSScanfTest, SimpleStringConv) {
1836991d83SMichael Jones   int ret_val;
1936991d83SMichael Jones   char buffer[10];
2036991d83SMichael Jones   char buffer2[10];
21b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("abc123", "abc %s", buffer);
2236991d83SMichael Jones   ASSERT_EQ(ret_val, 1);
2336991d83SMichael Jones   ASSERT_STREQ(buffer, "123");
2436991d83SMichael Jones 
25b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("abc123", "%3s %3s", buffer, buffer2);
2636991d83SMichael Jones   ASSERT_EQ(ret_val, 2);
2736991d83SMichael Jones   ASSERT_STREQ(buffer, "abc");
2836991d83SMichael Jones   ASSERT_STREQ(buffer2, "123");
2936991d83SMichael Jones 
30b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("abc 123", "%3s%3s", buffer, buffer2);
3136991d83SMichael Jones   ASSERT_EQ(ret_val, 2);
3236991d83SMichael Jones   ASSERT_STREQ(buffer, "abc");
3336991d83SMichael Jones   ASSERT_STREQ(buffer2, "123");
3436991d83SMichael Jones }
3565f4cc63SMichael Jones 
3665f4cc63SMichael Jones TEST(LlvmLibcSScanfTest, IntConvSimple) {
3765f4cc63SMichael Jones   int ret_val;
3865f4cc63SMichael Jones   int result = 0;
39b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%d", &result);
4065f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
4165f4cc63SMichael Jones   EXPECT_EQ(result, 123);
4265f4cc63SMichael Jones 
43b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("456", "%i", &result);
4465f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
4565f4cc63SMichael Jones   EXPECT_EQ(result, 456);
4665f4cc63SMichael Jones 
47b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("789", "%x", &result);
4865f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
4965f4cc63SMichael Jones   EXPECT_EQ(result, 0x789);
5065f4cc63SMichael Jones 
51b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("012", "%o", &result);
5265f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
5365f4cc63SMichael Jones   EXPECT_EQ(result, 012);
5465f4cc63SMichael Jones 
55b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("345", "%u", &result);
5665f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
5765f4cc63SMichael Jones   EXPECT_EQ(result, 345);
5865f4cc63SMichael Jones 
59afa764c9SMichael Jones   // 288 characters
60b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
61afa764c9SMichael Jones                                    "00000000000000000000000000000000"
62afa764c9SMichael Jones                                    "00000000000000000000000000000000"
63afa764c9SMichael Jones                                    "00000000000000000000000000000000"
64afa764c9SMichael Jones                                    "00000000000000000000000000000000"
65afa764c9SMichael Jones                                    "00000000000000000000000000000000"
66afa764c9SMichael Jones                                    "00000000000000000000000000000000"
67afa764c9SMichael Jones                                    "00000000000000000000000000000000"
68afa764c9SMichael Jones                                    "00000000000000000000000000000000",
69afa764c9SMichael Jones                                    "%d", &result);
70afa764c9SMichael Jones   EXPECT_EQ(ret_val, 1);
71b6bc9d72SGuillaume Chatelet   EXPECT_EQ(result, int(LIBC_NAMESPACE::cpp::numeric_limits<intmax_t>::max()));
72afa764c9SMichael Jones 
73b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("Not an integer", "%d", &result);
7465f4cc63SMichael Jones   EXPECT_EQ(ret_val, 0);
7565f4cc63SMichael Jones }
7665f4cc63SMichael Jones 
7765f4cc63SMichael Jones TEST(LlvmLibcSScanfTest, IntConvLengthModifier) {
7865f4cc63SMichael Jones   int ret_val;
7965f4cc63SMichael Jones   uintmax_t max_result = 0;
8065f4cc63SMichael Jones   int int_result = 0;
8165f4cc63SMichael Jones   char char_result = 0;
8265f4cc63SMichael Jones 
83b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%ju", &max_result);
8465f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
8565f4cc63SMichael Jones   EXPECT_EQ(max_result, uintmax_t(123));
8665f4cc63SMichael Jones 
8765f4cc63SMichael Jones   // Check overflow handling
88b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("999999999999999999999999999999999999",
89b6bc9d72SGuillaume Chatelet                                    "%ju", &max_result);
9065f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
91b6bc9d72SGuillaume Chatelet   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
9265f4cc63SMichael Jones 
9365f4cc63SMichael Jones   // Because this is unsigned, any out of range value should return the maximum,
9465f4cc63SMichael Jones   // even with a negative sign.
95b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-999999999999999999999999999999999999",
96b6bc9d72SGuillaume Chatelet                                    "%ju", &max_result);
9765f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
98b6bc9d72SGuillaume Chatelet   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
9965f4cc63SMichael Jones 
100b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-18446744073709551616", "%ju", &max_result);
10165f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
102b6bc9d72SGuillaume Chatelet   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
10365f4cc63SMichael Jones 
10465f4cc63SMichael Jones   // But any number below the maximum should have the - sign applied.
105b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-1", "%ju", &max_result);
10665f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
10765f4cc63SMichael Jones   EXPECT_EQ(max_result, uintmax_t(-1));
10865f4cc63SMichael Jones 
109b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-1", "%u", &int_result);
11065f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
11165f4cc63SMichael Jones   EXPECT_EQ(int_result, -1);
11265f4cc63SMichael Jones 
11365f4cc63SMichael Jones   max_result = 0xff00ff00ff00ff00;
11465f4cc63SMichael Jones   char_result = 0x6f;
11565f4cc63SMichael Jones 
11665f4cc63SMichael Jones   // Overflows for sizes larger than the maximum are handled by casting.
117b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("8589967360", "%d", &int_result);
11865f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
11965f4cc63SMichael Jones   EXPECT_EQ(int_result, int(8589967360)); // 2^33 + 2^15
12065f4cc63SMichael Jones 
12165f4cc63SMichael Jones   // Check that the adjacent values weren't touched by the overflow.
12265f4cc63SMichael Jones   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
12365f4cc63SMichael Jones   ASSERT_EQ(char_result, char(0x6f));
12465f4cc63SMichael Jones 
125b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-8589967360", "%d", &int_result);
12665f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
12765f4cc63SMichael Jones   EXPECT_EQ(int_result, int(-8589967360));
12865f4cc63SMichael Jones   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
12965f4cc63SMichael Jones   ASSERT_EQ(char_result, char(0x6f));
13065f4cc63SMichael Jones 
131b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("25", "%hhd", &char_result);
13265f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
13365f4cc63SMichael Jones   EXPECT_EQ(char_result, char(25));
13465f4cc63SMichael Jones }
13565f4cc63SMichael Jones 
13665f4cc63SMichael Jones TEST(LlvmLibcSScanfTest, IntConvBaseSelection) {
13765f4cc63SMichael Jones   int ret_val;
13865f4cc63SMichael Jones   int result = 0;
139b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0xabc123", "%i", &result);
14065f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
14165f4cc63SMichael Jones   EXPECT_EQ(result, 0xabc123);
14265f4cc63SMichael Jones 
143b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0456", "%i", &result);
14465f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
14565f4cc63SMichael Jones   EXPECT_EQ(result, 0456);
14665f4cc63SMichael Jones 
147b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0999", "%i", &result);
14865f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
14965f4cc63SMichael Jones   EXPECT_EQ(result, 0);
15065f4cc63SMichael Jones 
151b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123abc456", "%i", &result);
15265f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
15365f4cc63SMichael Jones   EXPECT_EQ(result, 123);
15465f4cc63SMichael Jones }
15565f4cc63SMichael Jones 
15665f4cc63SMichael Jones TEST(LlvmLibcSScanfTest, IntConvMaxLengthTests) {
15765f4cc63SMichael Jones   int ret_val;
15865f4cc63SMichael Jones   int result = 0;
15965f4cc63SMichael Jones 
160b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("12", "%1d", &result);
16165f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
16265f4cc63SMichael Jones   EXPECT_EQ(result, 1);
16365f4cc63SMichael Jones 
164b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-1", "%1d", &result);
16565f4cc63SMichael Jones   EXPECT_EQ(ret_val, 0);
16665f4cc63SMichael Jones   EXPECT_EQ(result, 0);
16765f4cc63SMichael Jones 
168b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("+1", "%1d", &result);
16965f4cc63SMichael Jones   EXPECT_EQ(ret_val, 0);
17065f4cc63SMichael Jones   EXPECT_EQ(result, 0);
17165f4cc63SMichael Jones 
172b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("01", "%1d", &result);
17365f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
17465f4cc63SMichael Jones   EXPECT_EQ(result, 0);
17565f4cc63SMichael Jones 
176b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("01", "%1i", &result);
17765f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
17865f4cc63SMichael Jones   EXPECT_EQ(result, 0);
17965f4cc63SMichael Jones 
180*0afe6e42SMichael Jones   result = -999;
181*0afe6e42SMichael Jones 
182*0afe6e42SMichael Jones   // 0x is a valid prefix, but not a valid number. This should be a matching
183*0afe6e42SMichael Jones   // failure and should not modify the values.
184b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%2i", &result);
185*0afe6e42SMichael Jones   EXPECT_EQ(ret_val, 0);
186*0afe6e42SMichael Jones   EXPECT_EQ(result, -999);
18765f4cc63SMichael Jones 
188b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-0x1", "%3i", &result);
189*0afe6e42SMichael Jones   EXPECT_EQ(ret_val, 0);
190*0afe6e42SMichael Jones   EXPECT_EQ(result, -999);
191*0afe6e42SMichael Jones 
192*0afe6e42SMichael Jones   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%3i", &result);
19365f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
194*0afe6e42SMichael Jones   EXPECT_EQ(result, 1);
195*0afe6e42SMichael Jones 
196*0afe6e42SMichael Jones   ret_val = LIBC_NAMESPACE::sscanf("-0x1", "%4i", &result);
197*0afe6e42SMichael Jones   EXPECT_EQ(ret_val, 1);
198*0afe6e42SMichael Jones   EXPECT_EQ(result, -1);
19965f4cc63SMichael Jones 
200b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-0x123", "%4i", &result);
20165f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
20265f4cc63SMichael Jones   EXPECT_EQ(result, -1);
20365f4cc63SMichael Jones 
204b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123456789", "%5i", &result);
20565f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
20665f4cc63SMichael Jones   EXPECT_EQ(result, 12345);
20765f4cc63SMichael Jones 
208b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123456789", "%10i", &result);
20965f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
21065f4cc63SMichael Jones   EXPECT_EQ(result, 123456789);
21165f4cc63SMichael Jones }
21265f4cc63SMichael Jones 
21365f4cc63SMichael Jones TEST(LlvmLibcSScanfTest, IntConvNoWriteTests) {
21465f4cc63SMichael Jones   int ret_val;
21565f4cc63SMichael Jones   // Result shouldn't be used by these tests, but it's safer to have it and
21665f4cc63SMichael Jones   // check it.
21765f4cc63SMichael Jones   int result = 0;
218b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-1", "%*1d", &result);
21965f4cc63SMichael Jones   EXPECT_EQ(ret_val, 0);
22065f4cc63SMichael Jones   EXPECT_EQ(result, 0);
22165f4cc63SMichael Jones 
222b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("01", "%*1i", &result);
22365f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
22465f4cc63SMichael Jones   EXPECT_EQ(result, 0);
22565f4cc63SMichael Jones 
226b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%*2i", &result);
227*0afe6e42SMichael Jones   EXPECT_EQ(ret_val, 0);
22865f4cc63SMichael Jones   EXPECT_EQ(result, 0);
22965f4cc63SMichael Jones 
230b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("a", "%*i", &result);
23165f4cc63SMichael Jones   EXPECT_EQ(ret_val, 0);
23265f4cc63SMichael Jones   EXPECT_EQ(result, 0);
23365f4cc63SMichael Jones 
234b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%*i", &result);
23565f4cc63SMichael Jones   EXPECT_EQ(ret_val, 1);
23665f4cc63SMichael Jones   EXPECT_EQ(result, 0);
23765f4cc63SMichael Jones }
23865f4cc63SMichael Jones 
2392e3ee31dSJoseph Huber #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT
2409a32e539SMichael Jones TEST(LlvmLibcSScanfTest, FloatConvSimple) {
2419a32e539SMichael Jones   int ret_val;
2429a32e539SMichael Jones   float result = 0;
2439a32e539SMichael Jones 
2446b02d2f8SGuillaume Chatelet   float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
245ace383dfSGuillaume Chatelet   float nan = LIBC_NAMESPACE::fputil::FPBits<float>::quiet_nan().get_val();
2469a32e539SMichael Jones 
247b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%f", &result);
2489a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2499a32e539SMichael Jones   EXPECT_FP_EQ(result, 123.0);
2509a32e539SMichael Jones 
251b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("456.1", "%a", &result);
2529a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2539a32e539SMichael Jones   EXPECT_FP_EQ(result, 456.1);
2549a32e539SMichael Jones 
255b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x789.ap0", "%e", &result);
2569a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2579a32e539SMichael Jones   EXPECT_FP_EQ(result, 0x789.ap0);
2589a32e539SMichael Jones 
259b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x.8", "%e", &result);
2609a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2619a32e539SMichael Jones   EXPECT_FP_EQ(result, 0x0.8p0);
2629a32e539SMichael Jones 
263b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x8.", "%e", &result);
2649a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2659a32e539SMichael Jones   EXPECT_FP_EQ(result, 0x8.0p0);
2669a32e539SMichael Jones 
267b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("+12.0e1", "%g", &result);
2689a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2699a32e539SMichael Jones   EXPECT_FP_EQ(result, 12.0e1);
2709a32e539SMichael Jones 
271b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("inf", "%F", &result);
2729a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2739a32e539SMichael Jones   EXPECT_FP_EQ(result, inf);
2749a32e539SMichael Jones 
275b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("NaN", "%A", &result);
2769a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2779a32e539SMichael Jones   EXPECT_FP_EQ(result, nan);
2789a32e539SMichael Jones 
279b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-InFiNiTy", "%E", &result);
2809a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2819a32e539SMichael Jones   EXPECT_FP_EQ(result, -inf);
2829a32e539SMichael Jones 
283b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1e10", "%G", &result);
2849a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2859a32e539SMichael Jones   EXPECT_FP_EQ(result, 1e10);
2869a32e539SMichael Jones 
287b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf(".1", "%G", &result);
2889a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2899a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.1);
2909a32e539SMichael Jones 
291b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1.", "%G", &result);
2929a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2939a32e539SMichael Jones   EXPECT_FP_EQ(result, 1.0);
2949a32e539SMichael Jones 
295b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0", "%f", &result);
2969a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
2979a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
2989a32e539SMichael Jones 
299b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("Not a float", "%f", &result);
3009a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
3019a32e539SMichael Jones }
3029a32e539SMichael Jones 
3039a32e539SMichael Jones TEST(LlvmLibcSScanfTest, FloatConvLengthModifier) {
3049a32e539SMichael Jones   int ret_val;
3059a32e539SMichael Jones   double d_result = 0;
3069a32e539SMichael Jones   long double ld_result = 0;
3079a32e539SMichael Jones 
3086b02d2f8SGuillaume Chatelet   double d_inf = LIBC_NAMESPACE::fputil::FPBits<double>::inf().get_val();
309eb56bc2bSGuillaume Chatelet   long double ld_nan =
310ace383dfSGuillaume Chatelet       LIBC_NAMESPACE::fputil::FPBits<long double>::quiet_nan().get_val();
3119a32e539SMichael Jones 
312b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%lf", &d_result);
3139a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3149a32e539SMichael Jones   EXPECT_FP_EQ(d_result, 123.0);
3159a32e539SMichael Jones 
316b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("456.1", "%La", &ld_result);
3179a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3189a32e539SMichael Jones   EXPECT_FP_EQ(ld_result, 456.1L);
3199a32e539SMichael Jones 
320b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("inf", "%le", &d_result);
3219a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3229a32e539SMichael Jones   EXPECT_FP_EQ(d_result, d_inf);
3239a32e539SMichael Jones 
324b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("nan", "%Lg", &ld_result);
3259a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3269a32e539SMichael Jones   EXPECT_FP_EQ(ld_result, ld_nan);
3279a32e539SMichael Jones 
328b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1e-300", "%lF", &d_result);
3299a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3309a32e539SMichael Jones   EXPECT_FP_EQ(d_result, 1e-300);
3319a32e539SMichael Jones 
332b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1.0e600", "%LA", &ld_result);
3339a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3349a32e539SMichael Jones // 1e600 may be larger than the maximum long double (if long double is double).
3359a32e539SMichael Jones // In that case both of these should be evaluated as inf.
336f7d4236aSGuillaume Chatelet #ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
3379a32e539SMichael Jones   EXPECT_FP_EQ(ld_result, d_inf);
3389a32e539SMichael Jones #else
3399a32e539SMichael Jones   EXPECT_FP_EQ(ld_result, 1.0e600L);
3409a32e539SMichael Jones #endif
3419a32e539SMichael Jones }
3429a32e539SMichael Jones 
3439a32e539SMichael Jones TEST(LlvmLibcSScanfTest, FloatConvLongNumber) {
3449a32e539SMichael Jones   int ret_val;
3459a32e539SMichael Jones   float result = 0;
3469a32e539SMichael Jones   double d_result = 0;
3479a32e539SMichael Jones 
3489a32e539SMichael Jones   // 32 characters
3499a32e539SMichael Jones   ret_val =
350b6bc9d72SGuillaume Chatelet       LIBC_NAMESPACE::sscanf("123456789012345678901234567890.0", "%f", &result);
3519a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3529a32e539SMichael Jones   EXPECT_FP_EQ(result, 123456789012345678901234567890.0f);
3539a32e539SMichael Jones 
3549a32e539SMichael Jones   // 64 characters
355b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf(
3569a32e539SMichael Jones       "123456789012345678901234567890123456789012345678901234567890.000", "%la",
3579a32e539SMichael Jones       &d_result);
3589a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3599a32e539SMichael Jones   EXPECT_FP_EQ(
3609a32e539SMichael Jones       d_result,
3619a32e539SMichael Jones       123456789012345678901234567890123456789012345678901234567890.000);
3629a32e539SMichael Jones 
3639a32e539SMichael Jones   // 128 characters
364b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf(
3659a32e539SMichael Jones       "123456789012345678901234567890123456789012345678901234567890"
3669a32e539SMichael Jones       "123456789012345678901234567890123456789012345678901234567890.0000000",
3679a32e539SMichael Jones       "%le", &d_result);
3689a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3699a32e539SMichael Jones   EXPECT_FP_EQ(
3709a32e539SMichael Jones       d_result,
3719a32e539SMichael Jones       123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.0000000);
3729a32e539SMichael Jones 
3739a32e539SMichael Jones   // 256 characters
374b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
3759a32e539SMichael Jones                                    "00000000000000000000000000000000"
3769a32e539SMichael Jones                                    "00000000000000000000000000000000"
3779a32e539SMichael Jones                                    "00000000000000000000000000000000"
3789a32e539SMichael Jones                                    "00000000000000000000000000000000"
3799a32e539SMichael Jones                                    "00000000000000000000000000000000"
3809a32e539SMichael Jones                                    "00000000000000000000000000000000"
3819a32e539SMichael Jones                                    "00000000000000000000000000000000",
3829a32e539SMichael Jones                                    "%lf", &d_result);
3839a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3849a32e539SMichael Jones   EXPECT_FP_EQ(d_result, 1e255);
3859a32e539SMichael Jones 
3869a32e539SMichael Jones   // 288 characters
387b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
3889a32e539SMichael Jones                                    "00000000000000000000000000000000"
3899a32e539SMichael Jones                                    "00000000000000000000000000000000"
3909a32e539SMichael Jones                                    "00000000000000000000000000000000"
3919a32e539SMichael Jones                                    "00000000000000000000000000000000"
3929a32e539SMichael Jones                                    "00000000000000000000000000000000"
3939a32e539SMichael Jones                                    "00000000000000000000000000000000"
3949a32e539SMichael Jones                                    "00000000000000000000000000000000"
3959a32e539SMichael Jones                                    "00000000000000000000000000000000",
3969a32e539SMichael Jones                                    "%lf", &d_result);
3979a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
3989a32e539SMichael Jones   EXPECT_FP_EQ(d_result, 1e287);
3999a32e539SMichael Jones }
4009a32e539SMichael Jones 
4019a32e539SMichael Jones TEST(LlvmLibcSScanfTest, FloatConvComplexParsing) {
4029a32e539SMichael Jones   int ret_val;
4039a32e539SMichael Jones   float result = 0;
4049a32e539SMichael Jones 
4056b02d2f8SGuillaume Chatelet   float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
406ace383dfSGuillaume Chatelet   float nan = LIBC_NAMESPACE::fputil::FPBits<float>::quiet_nan().get_val();
4079a32e539SMichael Jones 
408b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x1.0e3", "%f", &result);
4099a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4109a32e539SMichael Jones   EXPECT_FP_EQ(result, 0x1.0e3p0);
4119a32e539SMichael Jones 
412b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("", "%a", &result);
4139a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4149a32e539SMichael Jones 
415b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("+", "%a", &result);
4169a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4179a32e539SMichael Jones 
418b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-", "%a", &result);
4199a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4209a32e539SMichael Jones 
421b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("+.", "%a", &result);
4229a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4239a32e539SMichael Jones 
424b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-.e+10", "%a", &result);
4259a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4269a32e539SMichael Jones 
4279a32e539SMichael Jones   // This is a specific example from the standard. Its behavior diverges from
4289a32e539SMichael Jones   // other implementations that accept "100e" as being the same as "100e0"
429b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("100er", "%a", &result);
4309a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4319a32e539SMichael Jones 
432b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("nah", "%a", &result);
4339a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4349a32e539SMichael Jones 
435b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("indirection", "%a", &result);
4369a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4379a32e539SMichael Jones 
438b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("infnan", "%a", &result);
4399a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4409a32e539SMichael Jones   EXPECT_FP_EQ(result, inf);
4419a32e539SMichael Jones 
442b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("naninf", "%a", &result);
4439a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4449a32e539SMichael Jones   EXPECT_FP_EQ(result, nan);
4459a32e539SMichael Jones 
446b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("infinityinfinity", "%a", &result);
4479a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4489a32e539SMichael Jones   EXPECT_FP_EQ(result, inf);
4499a32e539SMichael Jones 
4509a32e539SMichael Jones   // For %f to accept a string as representing it has to be either "inf" or
4519a32e539SMichael Jones   // "infinity" when it stops. It only stops when it encounters a character that
4529a32e539SMichael Jones   // isn't the next one in the string, so it accepts "infi" as the the longest
4539a32e539SMichael Jones   // prefix of a possibly valid floating-point number, but determines that it is
4549a32e539SMichael Jones   // not valid and returns a matching failure. This is because it can only unget
4559a32e539SMichael Jones   // one character so when it finds that the character after the second 'i' is
4569a32e539SMichael Jones   // not the next character in "infinity" it can't rewind to the point where it
4579a32e539SMichael Jones   // had just "inf".
458b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("infi", "%a", &result);
4599a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4609a32e539SMichael Jones 
461b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("infinite", "%a", &result);
4629a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4639a32e539SMichael Jones 
464b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-.1e1", "%f", &result);
4659a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4669a32e539SMichael Jones   EXPECT_FP_EQ(result, -.1e1);
4679a32e539SMichael Jones 
468b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1.2.e1", "%f", &result);
4699a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4709a32e539SMichael Jones   EXPECT_FP_EQ(result, 1.2);
4719a32e539SMichael Jones }
4729a32e539SMichael Jones 
4739a32e539SMichael Jones TEST(LlvmLibcSScanfTest, FloatConvMaxWidth) {
4749a32e539SMichael Jones   int ret_val;
4759a32e539SMichael Jones   float result = 0;
4769a32e539SMichael Jones 
4776b02d2f8SGuillaume Chatelet   float inf = LIBC_NAMESPACE::fputil::FPBits<float>::inf().get_val();
4789a32e539SMichael Jones 
479b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%3f", &result);
4809a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4819a32e539SMichael Jones   EXPECT_FP_EQ(result, 123.0);
4829a32e539SMichael Jones 
483b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%5f", &result);
4849a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4859a32e539SMichael Jones   EXPECT_FP_EQ(result, 123.0);
4869a32e539SMichael Jones 
487b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("456", "%1f", &result);
4889a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4899a32e539SMichael Jones   EXPECT_FP_EQ(result, 4.0);
4909a32e539SMichael Jones 
491b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-789", "%1f", &result);
4929a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
4939a32e539SMichael Jones 
494b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-123", "%2f", &result);
4959a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
4969a32e539SMichael Jones   EXPECT_FP_EQ(result, -1.0);
4979a32e539SMichael Jones 
498b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("inf", "%2f", &result);
4999a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
5009a32e539SMichael Jones 
501b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("nan", "%1f", &result);
5029a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
5039a32e539SMichael Jones 
504b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-inf", "%3f", &result);
5059a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
5069a32e539SMichael Jones 
507b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-nan", "%3f", &result);
5089a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
5099a32e539SMichael Jones 
5109a32e539SMichael Jones   // If the max length were not here this would fail as discussed above, but
5119a32e539SMichael Jones   // since the max length limits it to the 3 it succeeds.
512b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("infinite", "%3f", &result);
5139a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5149a32e539SMichael Jones   EXPECT_FP_EQ(result, inf);
5159a32e539SMichael Jones 
516b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-infinite", "%4f", &result);
5179a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5189a32e539SMichael Jones   EXPECT_FP_EQ(result, -inf);
5199a32e539SMichael Jones 
520b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("01", "%1f", &result);
5219a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5229a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5239a32e539SMichael Jones 
524b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x1", "%2f", &result);
5259a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5269a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5279a32e539SMichael Jones 
528b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("100e", "%4f", &result);
5299a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
5309a32e539SMichael Jones 
531b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("100e+10", "%5f", &result);
5329a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
5339a32e539SMichael Jones 
534b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("100e10", "%5f", &result);
5359a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5369a32e539SMichael Jones   EXPECT_FP_EQ(result, 100e1);
5379a32e539SMichael Jones }
5389a32e539SMichael Jones 
5399a32e539SMichael Jones TEST(LlvmLibcSScanfTest, FloatConvNoWrite) {
5409a32e539SMichael Jones   int ret_val;
5419a32e539SMichael Jones   float result = 0;
5429a32e539SMichael Jones 
543b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%*f", &result);
5449a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5459a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5469a32e539SMichael Jones 
547b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("456.1", "%*a", &result);
5489a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5499a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5509a32e539SMichael Jones 
551b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0x789.ap0", "%*e", &result);
5529a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5539a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5549a32e539SMichael Jones 
555b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("+12.0e1", "%*g", &result);
5569a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5579a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5589a32e539SMichael Jones 
559b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("inf", "%*F", &result);
5609a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5619a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5629a32e539SMichael Jones 
563b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("NaN", "%*A", &result);
5649a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5659a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5669a32e539SMichael Jones 
567b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-InFiNiTy", "%*E", &result);
5689a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5699a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5709a32e539SMichael Jones 
571b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1e10", "%*G", &result);
5729a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5739a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5749a32e539SMichael Jones 
575b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf(".1", "%*G", &result);
5769a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5779a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5789a32e539SMichael Jones 
579b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%*3f", &result);
5809a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5819a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5829a32e539SMichael Jones 
583b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123", "%*5f", &result);
5849a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5859a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5869a32e539SMichael Jones 
587b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("456", "%*1f", &result);
5889a32e539SMichael Jones   EXPECT_EQ(ret_val, 1);
5899a32e539SMichael Jones   EXPECT_FP_EQ(result, 0.0);
5909a32e539SMichael Jones 
591b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("Not a float", "%*f", &result);
5929a32e539SMichael Jones   EXPECT_EQ(ret_val, 0);
5939a32e539SMichael Jones }
5942e3ee31dSJoseph Huber #endif
5959a32e539SMichael Jones 
5962e3ee31dSJoseph Huber #ifndef LIBC_COPT_SCANF_DISABLE_INDEX_MODE
597afa764c9SMichael Jones TEST(LlvmLibcSScanfTest, CurPosCombined) {
598afa764c9SMichael Jones   int ret_val;
599afa764c9SMichael Jones   int result = -1;
600afa764c9SMichael Jones   char c_result = 0;
601afa764c9SMichael Jones 
602b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("some text", "%n", &result);
603afa764c9SMichael Jones   // %n doesn't count as a conversion for the return value.
604afa764c9SMichael Jones   EXPECT_EQ(ret_val, 0);
605afa764c9SMichael Jones   EXPECT_EQ(result, 0);
606afa764c9SMichael Jones 
607b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1234567890", "12345%n", &result);
608afa764c9SMichael Jones   EXPECT_EQ(ret_val, 0);
609afa764c9SMichael Jones   EXPECT_EQ(result, 5);
610afa764c9SMichael Jones 
611b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("1234567890", "12345%n", &result);
612afa764c9SMichael Jones   EXPECT_EQ(ret_val, 0);
613afa764c9SMichael Jones   EXPECT_EQ(result, 5);
614afa764c9SMichael Jones 
615afa764c9SMichael Jones   // 288 characters
616b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
617afa764c9SMichael Jones                                    "00000000000000000000000000000000"
618afa764c9SMichael Jones                                    "00000000000000000000000000000000"
619afa764c9SMichael Jones                                    "00000000000000000000000000000000"
620afa764c9SMichael Jones                                    "00000000000000000000000000000000"
621afa764c9SMichael Jones                                    "00000000000000000000000000000000"
622afa764c9SMichael Jones                                    "00000000000000000000000000000000"
623afa764c9SMichael Jones                                    "00000000000000000000000000000000"
624afa764c9SMichael Jones                                    "00000000000000000000000000000000",
625afa764c9SMichael Jones                                    "%*d%hhn", &c_result);
626afa764c9SMichael Jones   EXPECT_EQ(ret_val, 1);
627afa764c9SMichael Jones   EXPECT_EQ(c_result, char(288)); // Overflow is handled by casting.
628afa764c9SMichael Jones 
629afa764c9SMichael Jones   // 320 characters
630b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("10000000000000000000000000000000"
631afa764c9SMichael Jones                                    "00000000000000000000000000000000"
632afa764c9SMichael Jones                                    "00000000000000000000000000000000"
633afa764c9SMichael Jones                                    "00000000000000000000000000000000"
634afa764c9SMichael Jones                                    "00000000000000000000000000000000"
635afa764c9SMichael Jones                                    "00000000000000000000000000000000"
636afa764c9SMichael Jones                                    "00000000000000000000000000000000"
637afa764c9SMichael Jones                                    "00000000000000000000000000000000"
638afa764c9SMichael Jones                                    "00000000000000000000000000000000"
639afa764c9SMichael Jones                                    "00000000000000000000000000000000",
640afa764c9SMichael Jones                                    "%*d%n", &result);
641afa764c9SMichael Jones   EXPECT_EQ(ret_val, 1);
642afa764c9SMichael Jones   EXPECT_EQ(result, 320);
643afa764c9SMichael Jones }
6442e3ee31dSJoseph Huber #endif
645afa764c9SMichael Jones 
646edf964e0SMichael Jones TEST(LlvmLibcSScanfTest, PointerConvCombined) {
647edf964e0SMichael Jones   int ret_val;
648edf964e0SMichael Jones   void *result;
649edf964e0SMichael Jones 
650b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("(nullptr)", "%p", &result);
651edf964e0SMichael Jones   EXPECT_EQ(ret_val, 1);
652edf964e0SMichael Jones   EXPECT_EQ(result, static_cast<void *>(nullptr));
653edf964e0SMichael Jones 
654b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("(NuLlPtR)", "%p", &result);
655edf964e0SMichael Jones   EXPECT_EQ(ret_val, 1);
656edf964e0SMichael Jones   EXPECT_EQ(result, static_cast<void *>(nullptr));
657edf964e0SMichael Jones 
658b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("(NULLPTR)", "%p", &result);
659edf964e0SMichael Jones   EXPECT_EQ(ret_val, 1);
660edf964e0SMichael Jones   EXPECT_EQ(result, static_cast<void *>(nullptr));
661edf964e0SMichael Jones 
662b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("(null)", "%p", &result);
663edf964e0SMichael Jones   EXPECT_EQ(ret_val, 0);
664edf964e0SMichael Jones 
665b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("(nullptr2", "%p", &result);
666edf964e0SMichael Jones   EXPECT_EQ(ret_val, 0);
667edf964e0SMichael Jones 
668b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0", "%p", &result);
669edf964e0SMichael Jones   EXPECT_EQ(ret_val, 1);
670edf964e0SMichael Jones   EXPECT_EQ(result, reinterpret_cast<void *>(0));
671edf964e0SMichael Jones 
672b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("100", "%p", &result);
673edf964e0SMichael Jones   EXPECT_EQ(ret_val, 1);
674edf964e0SMichael Jones   EXPECT_EQ(result, reinterpret_cast<void *>(0x100));
675edf964e0SMichael Jones 
676b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("-1", "%p", &result);
677edf964e0SMichael Jones   EXPECT_EQ(ret_val, 1);
678edf964e0SMichael Jones   EXPECT_EQ(result, reinterpret_cast<void *>(-1));
679edf964e0SMichael Jones 
680b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0xabcDEFG", "%p", &result);
681edf964e0SMichael Jones   EXPECT_EQ(ret_val, 1);
682edf964e0SMichael Jones   EXPECT_EQ(result, reinterpret_cast<void *>(0xabcdef));
683edf964e0SMichael Jones }
684edf964e0SMichael Jones 
68565f4cc63SMichael Jones TEST(LlvmLibcSScanfTest, CombinedConv) {
68665f4cc63SMichael Jones   int ret_val;
68765f4cc63SMichael Jones   int result = 0;
68865f4cc63SMichael Jones   char buffer[10];
689b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("123abc", "%i%s", &result, buffer);
69065f4cc63SMichael Jones   EXPECT_EQ(ret_val, 2);
69165f4cc63SMichael Jones   EXPECT_EQ(result, 123);
69265f4cc63SMichael Jones   ASSERT_STREQ(buffer, "abc");
69365f4cc63SMichael Jones 
694*0afe6e42SMichael Jones   result = -1;
695*0afe6e42SMichael Jones 
696*0afe6e42SMichael Jones   // 0x is a valid prefix, but not a valid number. This should be a matching
697*0afe6e42SMichael Jones   // failure and should not modify the values.
698b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0xZZZ", "%i%s", &result, buffer);
699*0afe6e42SMichael Jones   EXPECT_EQ(ret_val, 0);
700*0afe6e42SMichael Jones   EXPECT_EQ(result, -1);
701*0afe6e42SMichael Jones   ASSERT_STREQ(buffer, "abc");
70265f4cc63SMichael Jones 
703b6bc9d72SGuillaume Chatelet   ret_val = LIBC_NAMESPACE::sscanf("0xZZZ", "%X%s", &result, buffer);
704*0afe6e42SMichael Jones   EXPECT_EQ(ret_val, 0);
705*0afe6e42SMichael Jones   EXPECT_EQ(result, -1);
706*0afe6e42SMichael Jones   ASSERT_STREQ(buffer, "abc");
70765f4cc63SMichael Jones }
708