1 //===-- Unittests for the printf Converter --------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/stdio/printf_core/converter.h"
10 #include "src/stdio/printf_core/core_structs.h"
11 #include "src/stdio/printf_core/string_writer.h"
12 #include "src/stdio/printf_core/writer.h"
14 #include "test/UnitTest/Test.h"
16 class LlvmLibcPrintfConverterTest
: public __llvm_libc::testing::Test
{
18 // void SetUp() override {}
19 // void TearDown() override {}
22 __llvm_libc::printf_core::StringWriter str_writer
=
23 __llvm_libc::printf_core::StringWriter(str
);
24 __llvm_libc::printf_core::Writer writer
= __llvm_libc::printf_core::Writer(
25 reinterpret_cast<void *>(&str_writer
),
26 __llvm_libc::printf_core::StringWriter::write_str
,
27 __llvm_libc::printf_core::StringWriter::write_chars
,
28 __llvm_libc::printf_core::StringWriter::write_char
);
31 TEST_F(LlvmLibcPrintfConverterTest
, SimpleRawConversion
) {
32 __llvm_libc::printf_core::FormatSection raw_section
;
33 raw_section
.has_conv
= false;
34 raw_section
.raw_string
= "abc";
36 __llvm_libc::printf_core::convert(&writer
, raw_section
);
38 str_writer
.terminate();
40 ASSERT_STREQ(str
, "abc");
41 ASSERT_EQ(writer
.get_chars_written(), 3);
44 TEST_F(LlvmLibcPrintfConverterTest
, PercentConversion
) {
45 __llvm_libc::printf_core::FormatSection simple_conv
;
46 simple_conv
.has_conv
= true;
47 simple_conv
.raw_string
= "%%";
48 simple_conv
.conv_name
= '%';
50 __llvm_libc::printf_core::convert(&writer
, simple_conv
);
54 ASSERT_STREQ(str
, "%");
55 ASSERT_EQ(writer
.get_chars_written(), 1);
58 TEST_F(LlvmLibcPrintfConverterTest
, CharConversionSimple
) {
59 __llvm_libc::printf_core::FormatSection simple_conv
;
60 simple_conv
.has_conv
= true;
61 // If has_conv is true, the raw string is ignored. They are not being parsed
62 // and match the actual conversion taking place so that you can compare these
63 // tests with other implmentations. The raw strings are completely optional.
64 simple_conv
.raw_string
= "%c";
65 simple_conv
.conv_name
= 'c';
66 simple_conv
.conv_val_raw
= 'D';
68 __llvm_libc::printf_core::convert(&writer
, simple_conv
);
70 str_writer
.terminate();
72 ASSERT_STREQ(str
, "D");
73 ASSERT_EQ(writer
.get_chars_written(), 1);
76 TEST_F(LlvmLibcPrintfConverterTest
, CharConversionRightJustified
) {
77 __llvm_libc::printf_core::FormatSection right_justified_conv
;
78 right_justified_conv
.has_conv
= true;
79 right_justified_conv
.raw_string
= "%4c";
80 right_justified_conv
.conv_name
= 'c';
81 right_justified_conv
.min_width
= 4;
82 right_justified_conv
.conv_val_raw
= 'E';
83 __llvm_libc::printf_core::convert(&writer
, right_justified_conv
);
85 str_writer
.terminate();
87 ASSERT_STREQ(str
, " E");
88 ASSERT_EQ(writer
.get_chars_written(), 4);
91 TEST_F(LlvmLibcPrintfConverterTest
, CharConversionLeftJustified
) {
92 __llvm_libc::printf_core::FormatSection left_justified_conv
;
93 left_justified_conv
.has_conv
= true;
94 left_justified_conv
.raw_string
= "%-4c";
95 left_justified_conv
.conv_name
= 'c';
96 left_justified_conv
.flags
=
97 __llvm_libc::printf_core::FormatFlags::LEFT_JUSTIFIED
;
98 left_justified_conv
.min_width
= 4;
99 left_justified_conv
.conv_val_raw
= 'F';
100 __llvm_libc::printf_core::convert(&writer
, left_justified_conv
);
102 str_writer
.terminate();
104 ASSERT_STREQ(str
, "F ");
105 ASSERT_EQ(writer
.get_chars_written(), 4);
108 TEST_F(LlvmLibcPrintfConverterTest
, StringConversionSimple
) {
110 __llvm_libc::printf_core::FormatSection simple_conv
;
111 simple_conv
.has_conv
= true;
112 simple_conv
.raw_string
= "%s";
113 simple_conv
.conv_name
= 's';
114 simple_conv
.conv_val_ptr
= const_cast<char *>("DEF");
116 __llvm_libc::printf_core::convert(&writer
, simple_conv
);
118 str_writer
.terminate();
120 ASSERT_STREQ(str
, "DEF");
121 ASSERT_EQ(writer
.get_chars_written(), 3);
124 TEST_F(LlvmLibcPrintfConverterTest
, StringConversionPrecisionHigh
) {
125 __llvm_libc::printf_core::FormatSection high_precision_conv
;
126 high_precision_conv
.has_conv
= true;
127 high_precision_conv
.raw_string
= "%4s";
128 high_precision_conv
.conv_name
= 's';
129 high_precision_conv
.precision
= 4;
130 high_precision_conv
.conv_val_ptr
= const_cast<char *>("456");
131 __llvm_libc::printf_core::convert(&writer
, high_precision_conv
);
133 str_writer
.terminate();
135 ASSERT_STREQ(str
, "456");
136 ASSERT_EQ(writer
.get_chars_written(), 3);
139 TEST_F(LlvmLibcPrintfConverterTest
, StringConversionPrecisionLow
) {
140 __llvm_libc::printf_core::FormatSection low_precision_conv
;
141 low_precision_conv
.has_conv
= true;
142 low_precision_conv
.raw_string
= "%.2s";
143 low_precision_conv
.conv_name
= 's';
144 low_precision_conv
.precision
= 2;
145 low_precision_conv
.conv_val_ptr
= const_cast<char *>("xyz");
146 __llvm_libc::printf_core::convert(&writer
, low_precision_conv
);
148 str_writer
.terminate();
150 ASSERT_STREQ(str
, "xy");
151 ASSERT_EQ(writer
.get_chars_written(), 2);
154 TEST_F(LlvmLibcPrintfConverterTest
, StringConversionRightJustified
) {
155 __llvm_libc::printf_core::FormatSection right_justified_conv
;
156 right_justified_conv
.has_conv
= true;
157 right_justified_conv
.raw_string
= "%4s";
158 right_justified_conv
.conv_name
= 's';
159 right_justified_conv
.min_width
= 4;
160 right_justified_conv
.conv_val_ptr
= const_cast<char *>("789");
161 __llvm_libc::printf_core::convert(&writer
, right_justified_conv
);
163 str_writer
.terminate();
165 ASSERT_STREQ(str
, " 789");
166 ASSERT_EQ(writer
.get_chars_written(), 4);
169 TEST_F(LlvmLibcPrintfConverterTest
, StringConversionLeftJustified
) {
170 __llvm_libc::printf_core::FormatSection left_justified_conv
;
171 left_justified_conv
.has_conv
= true;
172 left_justified_conv
.raw_string
= "%-4s";
173 left_justified_conv
.conv_name
= 's';
174 left_justified_conv
.flags
=
175 __llvm_libc::printf_core::FormatFlags::LEFT_JUSTIFIED
;
176 left_justified_conv
.min_width
= 4;
177 left_justified_conv
.conv_val_ptr
= const_cast<char *>("ghi");
178 __llvm_libc::printf_core::convert(&writer
, left_justified_conv
);
180 str_writer
.terminate();
182 ASSERT_STREQ(str
, "ghi ");
183 ASSERT_EQ(writer
.get_chars_written(), 4);
186 TEST_F(LlvmLibcPrintfConverterTest
, IntConversionSimple
) {
187 __llvm_libc::printf_core::FormatSection section
;
188 section
.has_conv
= true;
189 section
.raw_string
= "%d";
190 section
.conv_name
= 'd';
191 section
.conv_val_raw
= 12345;
192 __llvm_libc::printf_core::convert(&writer
, section
);
194 str_writer
.terminate();
196 ASSERT_STREQ(str
, "12345");
197 ASSERT_EQ(writer
.get_chars_written(), 5);
200 TEST_F(LlvmLibcPrintfConverterTest
, HexConversion
) {
201 __llvm_libc::printf_core::FormatSection section
;
202 section
.has_conv
= true;
203 section
.raw_string
= "%#018x";
204 section
.conv_name
= 'x';
205 section
.flags
= static_cast<__llvm_libc::printf_core::FormatFlags
>(
206 __llvm_libc::printf_core::FormatFlags::ALTERNATE_FORM
|
207 __llvm_libc::printf_core::FormatFlags::LEADING_ZEROES
);
208 section
.min_width
= 18;
209 section
.conv_val_raw
= 0x123456ab;
210 __llvm_libc::printf_core::convert(&writer
, section
);
212 str_writer
.terminate();
213 ASSERT_STREQ(str
, "0x00000000123456ab");
214 ASSERT_EQ(writer
.get_chars_written(), 18);
217 TEST_F(LlvmLibcPrintfConverterTest
, PointerConversion
) {
219 __llvm_libc::printf_core::FormatSection section
;
220 section
.has_conv
= true;
221 section
.raw_string
= "%p";
222 section
.conv_name
= 'p';
223 section
.conv_val_ptr
= (void *)(0x123456ab);
224 __llvm_libc::printf_core::convert(&writer
, section
);
226 str_writer
.terminate();
227 ASSERT_STREQ(str
, "0x123456ab");
228 ASSERT_EQ(writer
.get_chars_written(), 10);
231 TEST_F(LlvmLibcPrintfConverterTest
, OctConversion
) {
233 __llvm_libc::printf_core::FormatSection section
;
234 section
.has_conv
= true;
235 section
.raw_string
= "%o";
236 section
.conv_name
= 'o';
237 section
.conv_val_raw
= 01234;
238 __llvm_libc::printf_core::convert(&writer
, section
);
240 str_writer
.terminate();
241 ASSERT_STREQ(str
, "1234");
242 ASSERT_EQ(writer
.get_chars_written(), 4);