[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / libc / test / src / stdio / scanf_core / converter_test.cpp
blob97cb77e91c9b2c6cd1e36c7ba93912c2950faa43
1 //===-- Unittests for the basic scanf converters --------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "src/__support/CPP/string_view.h"
10 #include "src/stdio/scanf_core/converter.h"
11 #include "src/stdio/scanf_core/core_structs.h"
12 #include "src/stdio/scanf_core/reader.h"
13 #include "src/stdio/scanf_core/string_reader.h"
15 #include "test/UnitTest/Test.h"
17 TEST(LlvmLibcScanfConverterTest, RawMatchBasic) {
18 const char *str = "abcdef";
19 __llvm_libc::scanf_core::StringReader str_reader(str);
20 __llvm_libc::scanf_core::Reader reader(&str_reader);
22 // Reading "abc" should succeed.
23 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "abc"),
24 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
25 ASSERT_EQ(reader.chars_read(), size_t(3));
27 // Reading nothing should succeed and not advance.
28 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, ""),
29 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
30 ASSERT_EQ(reader.chars_read(), size_t(3));
32 // Reading a space where there is none should succeed and not advance.
33 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, " "),
34 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
35 ASSERT_EQ(reader.chars_read(), size_t(3));
37 // Reading "d" should succeed and advance by 1.
38 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "d"),
39 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
40 ASSERT_EQ(reader.chars_read(), size_t(4));
42 // Reading "z" should fail and not advance.
43 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "z"),
44 static_cast<int>(__llvm_libc::scanf_core::MATCHING_FAILURE));
45 ASSERT_EQ(reader.chars_read(), size_t(4));
47 // Reading "efgh" should fail but advance to the end.
48 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "efgh"),
49 static_cast<int>(__llvm_libc::scanf_core::MATCHING_FAILURE));
50 ASSERT_EQ(reader.chars_read(), size_t(6));
53 TEST(LlvmLibcScanfConverterTest, RawMatchSpaces) {
54 const char *str = " a \t\n b cd";
55 __llvm_libc::scanf_core::StringReader str_reader(str);
56 __llvm_libc::scanf_core::Reader reader(&str_reader);
58 // Reading "a" should fail and not advance.
59 // Since there's nothing in the format string (the second argument to
60 // raw_match) to match the space in the buffer it isn't consumed.
61 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "a"),
62 static_cast<int>(__llvm_libc::scanf_core::MATCHING_FAILURE));
63 ASSERT_EQ(reader.chars_read(), size_t(0));
65 // Reading " \t\n " should succeed and advance past the space.
66 // Any number of space characters in the format string match 0 or more space
67 // characters in the buffer.
68 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, " \t\n "),
69 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
70 ASSERT_EQ(reader.chars_read(), size_t(1));
72 // Reading "ab" should fail and only advance past the a
73 // The a characters match, but the format string doesn't have anything to
74 // consume the spaces in the buffer, so it fails.
75 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "ab"),
76 static_cast<int>(__llvm_libc::scanf_core::MATCHING_FAILURE));
77 ASSERT_EQ(reader.chars_read(), size_t(2));
79 // Reading " b" should succeed and advance past the b
80 // Any number of space characters in the format string matches 0 or more space
81 // characters in the buffer.
82 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, " b"),
83 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
84 ASSERT_EQ(reader.chars_read(), size_t(7));
86 // Reading "\t" should succeed and advance past the spaces to the c
87 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "\t"),
88 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
89 ASSERT_EQ(reader.chars_read(), size_t(10));
91 // Reading "c d" should succeed and advance past the d.
92 // Here the space character in the format string is matching 0 space
93 // characters in the buffer.
94 ASSERT_EQ(__llvm_libc::scanf_core::raw_match(&reader, "c d"),
95 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
96 ASSERT_EQ(reader.chars_read(), size_t(12));
99 TEST(LlvmLibcScanfConverterTest, StringConvSimple) {
100 const char *str = "abcDEF123 654LKJihg";
101 char result[20];
102 __llvm_libc::scanf_core::StringReader str_reader(str);
103 __llvm_libc::scanf_core::Reader reader(&str_reader);
105 __llvm_libc::scanf_core::FormatSection conv;
106 conv.has_conv = true;
107 conv.conv_name = 's';
108 conv.output_ptr = result;
110 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
111 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
112 ASSERT_EQ(reader.chars_read(), size_t(9));
113 ASSERT_STREQ(result, "abcDEF123");
115 //%s skips all spaces before beginning to read.
116 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
117 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
118 ASSERT_EQ(reader.chars_read(), size_t(19));
119 ASSERT_STREQ(result, "654LKJihg");
122 TEST(LlvmLibcScanfConverterTest, StringConvNoWrite) {
123 const char *str = "abcDEF123 654LKJihg";
124 __llvm_libc::scanf_core::StringReader str_reader(str);
125 __llvm_libc::scanf_core::Reader reader(&str_reader);
127 __llvm_libc::scanf_core::FormatSection conv;
128 conv.has_conv = true;
129 conv.conv_name = 's';
130 conv.flags = __llvm_libc::scanf_core::NO_WRITE;
132 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
133 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
134 ASSERT_EQ(reader.chars_read(), size_t(9));
136 //%s skips all spaces before beginning to read.
137 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
138 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
139 ASSERT_EQ(reader.chars_read(), size_t(19));
142 TEST(LlvmLibcScanfConverterTest, StringConvWidth) {
143 const char *str = "abcDEF123 654LKJihg";
144 char result[6];
145 __llvm_libc::scanf_core::StringReader str_reader(str);
146 __llvm_libc::scanf_core::Reader reader(&str_reader);
148 __llvm_libc::scanf_core::FormatSection conv;
149 conv.has_conv = true;
150 conv.conv_name = 's';
151 conv.max_width = 5; // this means the result takes up 6 characters (with \0).
152 conv.output_ptr = result;
154 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
155 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
156 ASSERT_EQ(reader.chars_read(), size_t(5));
157 ASSERT_STREQ(result, "abcDE");
159 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
160 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
161 ASSERT_EQ(reader.chars_read(), size_t(9));
162 ASSERT_STREQ(result, "F123");
164 //%s skips all spaces before beginning to read.
165 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
166 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
167 ASSERT_EQ(reader.chars_read(), size_t(15));
168 ASSERT_STREQ(result, "654LK");
170 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
171 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
172 ASSERT_EQ(reader.chars_read(), size_t(19));
173 ASSERT_STREQ(result, "Jihg");
176 TEST(LlvmLibcScanfConverterTest, CharsConv) {
177 const char *str = "abcDEF123 654LKJihg MNOpqr&*(";
178 char result[20];
179 __llvm_libc::scanf_core::StringReader str_reader(str);
180 __llvm_libc::scanf_core::Reader reader(&str_reader);
182 __llvm_libc::scanf_core::FormatSection conv;
183 conv.has_conv = true;
184 conv.conv_name = 'c';
185 conv.output_ptr = result;
187 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
188 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
189 ASSERT_EQ(reader.chars_read(), size_t(1));
190 ASSERT_EQ(result[0], 'a');
192 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
193 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
194 ASSERT_EQ(reader.chars_read(), size_t(2));
195 ASSERT_EQ(result[0], 'b');
197 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
198 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
199 ASSERT_EQ(reader.chars_read(), size_t(3));
200 ASSERT_EQ(result[0], 'c');
202 // Switch from character by character to 8 at a time.
203 conv.max_width = 8;
204 __llvm_libc::cpp::string_view result_view(result, 8);
206 //%c doesn't stop on spaces.
207 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
208 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
209 ASSERT_EQ(reader.chars_read(), size_t(11));
210 ASSERT_EQ(result_view, __llvm_libc::cpp::string_view("DEF123 6", 8));
212 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
213 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
214 ASSERT_EQ(reader.chars_read(), size_t(19));
215 ASSERT_EQ(result_view, __llvm_libc::cpp::string_view("54LKJihg", 8));
217 //%c also doesn't skip spaces at the start.
218 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
219 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
220 ASSERT_EQ(reader.chars_read(), size_t(27));
221 ASSERT_EQ(result_view, __llvm_libc::cpp::string_view(" MNOpqr&", 8));
223 //%c will stop on a null byte though.
224 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
225 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
226 ASSERT_EQ(reader.chars_read(), size_t(29));
227 ASSERT_EQ(__llvm_libc::cpp::string_view(result, 2),
228 __llvm_libc::cpp::string_view("*(", 2));
231 TEST(LlvmLibcScanfConverterTest, ScansetConv) {
232 const char *str = "abcDEF[123] 654LKJihg";
233 char result[20];
234 __llvm_libc::scanf_core::StringReader str_reader(str);
235 __llvm_libc::scanf_core::Reader reader(&str_reader);
237 __llvm_libc::scanf_core::FormatSection conv;
238 conv.has_conv = true;
239 conv.conv_name = '[';
240 conv.output_ptr = result;
242 __llvm_libc::cpp::bitset<256> bitset1;
243 bitset1.set_range('a', 'c');
244 bitset1.set_range('D', 'F');
245 bitset1.set_range('1', '6');
246 bitset1.set('[');
247 bitset1.set(']');
249 conv.scan_set = bitset1;
251 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
252 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
253 ASSERT_EQ(reader.chars_read(), size_t(11));
254 ASSERT_EQ(__llvm_libc::cpp::string_view(result, 11),
255 __llvm_libc::cpp::string_view("abcDEF[123]", 11));
257 // The scanset conversion doesn't consume leading spaces. If it did it would
258 // return "654" here.
259 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
260 static_cast<int>(__llvm_libc::scanf_core::MATCHING_FAILURE));
261 ASSERT_EQ(reader.chars_read(), size_t(11));
263 // This set is everything except for a-g.
264 __llvm_libc::cpp::bitset<256> bitset2;
265 bitset2.set_range('a', 'g');
266 bitset2.flip();
267 conv.scan_set = bitset2;
269 conv.max_width = 5;
271 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
272 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
273 ASSERT_EQ(reader.chars_read(), size_t(16));
274 ASSERT_EQ(__llvm_libc::cpp::string_view(result, 5),
275 __llvm_libc::cpp::string_view(" 654L", 5));
277 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
278 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
279 ASSERT_EQ(reader.chars_read(), size_t(20));
280 ASSERT_EQ(__llvm_libc::cpp::string_view(result, 4),
281 __llvm_libc::cpp::string_view("KJih", 4));
283 // This set is g and '\0'.
284 __llvm_libc::cpp::bitset<256> bitset3;
285 bitset3.set('g');
286 bitset3.set('\0');
287 conv.scan_set = bitset3;
289 // Even though '\0' is in the scanset, it should still stop on it.
290 ASSERT_EQ(__llvm_libc::scanf_core::convert(&reader, conv),
291 static_cast<int>(__llvm_libc::scanf_core::READ_OK));
292 ASSERT_EQ(reader.chars_read(), size_t(21));
293 ASSERT_EQ(__llvm_libc::cpp::string_view(result, 1),
294 __llvm_libc::cpp::string_view("g", 1));