xref: /aosp_15_r20/external/llvm-libc/test/src/stdio/vsscanf_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Unittests for sscanf ----------------------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker 
9*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/vsscanf.h"
10*71db0c75SAndroid Build Coastguard Worker 
11*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
12*71db0c75SAndroid Build Coastguard Worker 
call_vsscanf(const char * __restrict buffer,const char * __restrict format,...)13*71db0c75SAndroid Build Coastguard Worker int call_vsscanf(const char *__restrict buffer, const char *__restrict format,
14*71db0c75SAndroid Build Coastguard Worker                  ...) {
15*71db0c75SAndroid Build Coastguard Worker   va_list vlist;
16*71db0c75SAndroid Build Coastguard Worker   va_start(vlist, format);
17*71db0c75SAndroid Build Coastguard Worker   int ret = LIBC_NAMESPACE::vsscanf(buffer, format, vlist);
18*71db0c75SAndroid Build Coastguard Worker   va_end(vlist);
19*71db0c75SAndroid Build Coastguard Worker   return ret;
20*71db0c75SAndroid Build Coastguard Worker }
21*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcVSScanfTest,SimpleStringConv)22*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcVSScanfTest, SimpleStringConv) {
23*71db0c75SAndroid Build Coastguard Worker   int ret_val;
24*71db0c75SAndroid Build Coastguard Worker   char buffer[10];
25*71db0c75SAndroid Build Coastguard Worker   char buffer2[10];
26*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("abc123", "abc %s", buffer);
27*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(ret_val, 1);
28*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(buffer, "123");
29*71db0c75SAndroid Build Coastguard Worker 
30*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("abc123", "%3s %3s", buffer, buffer2);
31*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(ret_val, 2);
32*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(buffer, "abc");
33*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(buffer2, "123");
34*71db0c75SAndroid Build Coastguard Worker 
35*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("abc 123", "%3s%3s", buffer, buffer2);
36*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(ret_val, 2);
37*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(buffer, "abc");
38*71db0c75SAndroid Build Coastguard Worker   ASSERT_STREQ(buffer2, "123");
39*71db0c75SAndroid Build Coastguard Worker }
40*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcVSScanfTest,IntConvSimple)41*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcVSScanfTest, IntConvSimple) {
42*71db0c75SAndroid Build Coastguard Worker   int ret_val;
43*71db0c75SAndroid Build Coastguard Worker   int result = 0;
44*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("123", "%d", &result);
45*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
46*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 123);
47*71db0c75SAndroid Build Coastguard Worker 
48*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("456", "%i", &result);
49*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
50*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 456);
51*71db0c75SAndroid Build Coastguard Worker 
52*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("789", "%x", &result);
53*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
54*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 0x789);
55*71db0c75SAndroid Build Coastguard Worker 
56*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("012", "%o", &result);
57*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
58*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 012);
59*71db0c75SAndroid Build Coastguard Worker 
60*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("345", "%u", &result);
61*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
62*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 345);
63*71db0c75SAndroid Build Coastguard Worker 
64*71db0c75SAndroid Build Coastguard Worker   // 288 characters
65*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("10000000000000000000000000000000"
66*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000"
67*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000"
68*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000"
69*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000"
70*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000"
71*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000"
72*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000"
73*71db0c75SAndroid Build Coastguard Worker                          "00000000000000000000000000000000",
74*71db0c75SAndroid Build Coastguard Worker                          "%d", &result);
75*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
76*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, int(LIBC_NAMESPACE::cpp::numeric_limits<intmax_t>::max()));
77*71db0c75SAndroid Build Coastguard Worker 
78*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("Not an integer", "%d", &result);
79*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 0);
80*71db0c75SAndroid Build Coastguard Worker }
81*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcVSScanfTest,IntConvLengthModifier)82*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcVSScanfTest, IntConvLengthModifier) {
83*71db0c75SAndroid Build Coastguard Worker   int ret_val;
84*71db0c75SAndroid Build Coastguard Worker   uintmax_t max_result = 0;
85*71db0c75SAndroid Build Coastguard Worker   int int_result = 0;
86*71db0c75SAndroid Build Coastguard Worker   char char_result = 0;
87*71db0c75SAndroid Build Coastguard Worker 
88*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("123", "%ju", &max_result);
89*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
90*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(max_result, uintmax_t(123));
91*71db0c75SAndroid Build Coastguard Worker 
92*71db0c75SAndroid Build Coastguard Worker   // Check overflow handling
93*71db0c75SAndroid Build Coastguard Worker   ret_val =
94*71db0c75SAndroid Build Coastguard Worker       call_vsscanf("999999999999999999999999999999999999", "%ju", &max_result);
95*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
96*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
97*71db0c75SAndroid Build Coastguard Worker 
98*71db0c75SAndroid Build Coastguard Worker   // Because this is unsigned, any out of range value should return the maximum,
99*71db0c75SAndroid Build Coastguard Worker   // even with a negative sign.
100*71db0c75SAndroid Build Coastguard Worker   ret_val =
101*71db0c75SAndroid Build Coastguard Worker       call_vsscanf("-999999999999999999999999999999999999", "%ju", &max_result);
102*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
103*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
104*71db0c75SAndroid Build Coastguard Worker 
105*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("-18446744073709551616", "%ju", &max_result);
106*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
107*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(max_result, LIBC_NAMESPACE::cpp::numeric_limits<uintmax_t>::max());
108*71db0c75SAndroid Build Coastguard Worker 
109*71db0c75SAndroid Build Coastguard Worker   // But any number below the maximum should have the - sign applied.
110*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("-1", "%ju", &max_result);
111*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
112*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(max_result, uintmax_t(-1));
113*71db0c75SAndroid Build Coastguard Worker 
114*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("-1", "%u", &int_result);
115*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
116*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(int_result, -1);
117*71db0c75SAndroid Build Coastguard Worker 
118*71db0c75SAndroid Build Coastguard Worker   max_result = 0xff00ff00ff00ff00;
119*71db0c75SAndroid Build Coastguard Worker   char_result = 0x6f;
120*71db0c75SAndroid Build Coastguard Worker 
121*71db0c75SAndroid Build Coastguard Worker   // Overflows for sizes larger than the maximum are handled by casting.
122*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("8589967360", "%d", &int_result);
123*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
124*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(int_result, int(8589967360)); // 2^33 + 2^15
125*71db0c75SAndroid Build Coastguard Worker 
126*71db0c75SAndroid Build Coastguard Worker   // Check that the adjacent values weren't touched by the overflow.
127*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
128*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(char_result, char(0x6f));
129*71db0c75SAndroid Build Coastguard Worker 
130*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("-8589967360", "%d", &int_result);
131*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
132*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(int_result, int(-8589967360));
133*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(max_result, uintmax_t(0xff00ff00ff00ff00));
134*71db0c75SAndroid Build Coastguard Worker   ASSERT_EQ(char_result, char(0x6f));
135*71db0c75SAndroid Build Coastguard Worker 
136*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("25", "%hhd", &char_result);
137*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
138*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(char_result, char(25));
139*71db0c75SAndroid Build Coastguard Worker }
140*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcVSScanfTest,IntConvBaseSelection)141*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcVSScanfTest, IntConvBaseSelection) {
142*71db0c75SAndroid Build Coastguard Worker   int ret_val;
143*71db0c75SAndroid Build Coastguard Worker   int result = 0;
144*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("0xabc123", "%i", &result);
145*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
146*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 0xabc123);
147*71db0c75SAndroid Build Coastguard Worker 
148*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("0456", "%i", &result);
149*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
150*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 0456);
151*71db0c75SAndroid Build Coastguard Worker 
152*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("0999", "%i", &result);
153*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
154*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 0);
155*71db0c75SAndroid Build Coastguard Worker 
156*71db0c75SAndroid Build Coastguard Worker   ret_val = call_vsscanf("123abc456", "%i", &result);
157*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(ret_val, 1);
158*71db0c75SAndroid Build Coastguard Worker   EXPECT_EQ(result, 123);
159*71db0c75SAndroid Build Coastguard Worker }
160