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