1 //===-- Unittests for the printf String Writer ----------------------------===//
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 //===----------------------------------------------------------------------===//
8
9 #include "src/stdio/printf_core/string_writer.h"
10 #include "src/stdio/printf_core/writer.h"
11
12 #include "utils/UnitTest/Test.h"
13
TEST(LlvmLibcPrintfStringWriterTest,Constructor)14 TEST(LlvmLibcPrintfStringWriterTest, Constructor) {
15 char str[10];
16 __llvm_libc::printf_core::StringWriter str_writer(str);
17 __llvm_libc::printf_core::Writer writer(
18 reinterpret_cast<void *>(&str_writer),
19 __llvm_libc::printf_core::write_to_string);
20 }
21
TEST(LlvmLibcPrintfStringWriterTest,Write)22 TEST(LlvmLibcPrintfStringWriterTest, Write) {
23 char str[4] = {'D', 'E', 'F', 'G'};
24 __llvm_libc::printf_core::StringWriter str_writer(str);
25 __llvm_libc::printf_core::Writer writer(
26 reinterpret_cast<void *>(&str_writer),
27 __llvm_libc::printf_core::write_to_string);
28 writer.write("abc", 3);
29
30 EXPECT_EQ(str[3], 'G');
31 // This null terminates the string. The writer has no indication when the
32 // string is done, so it relies on the user to tell it when to null terminate
33 // the string. Importantly, it can't tell the difference between an intended
34 // max length of 0 (write nothing) or 1 (write just a null byte), and so it
35 // relies on the caller to do that bounds check.
36 str_writer.terminate();
37
38 ASSERT_STREQ("abc", str);
39 ASSERT_EQ(writer.get_chars_written(), 3);
40 }
41
TEST(LlvmLibcPrintfStringWriterTest,WriteMultipleTimes)42 TEST(LlvmLibcPrintfStringWriterTest, WriteMultipleTimes) {
43 char str[10];
44 __llvm_libc::printf_core::StringWriter str_writer(str);
45 __llvm_libc::printf_core::Writer writer(
46 reinterpret_cast<void *>(&str_writer),
47 __llvm_libc::printf_core::write_to_string);
48 writer.write("abc", 3);
49 writer.write("DEF", 3);
50 writer.write("1234", 3);
51
52 str_writer.terminate();
53
54 ASSERT_STREQ("abcDEF123", str);
55 ASSERT_EQ(writer.get_chars_written(), 9);
56 }
57
TEST(LlvmLibcPrintfStringWriterTest,WriteChars)58 TEST(LlvmLibcPrintfStringWriterTest, WriteChars) {
59 char str[4] = {'D', 'E', 'F', 'G'};
60 __llvm_libc::printf_core::StringWriter str_writer(str);
61 __llvm_libc::printf_core::Writer writer(
62 reinterpret_cast<void *>(&str_writer),
63 __llvm_libc::printf_core::write_to_string);
64 writer.write_chars('a', 3);
65
66 EXPECT_EQ(str[3], 'G');
67 str_writer.terminate();
68
69 ASSERT_STREQ("aaa", str);
70 ASSERT_EQ(writer.get_chars_written(), 3);
71 }
72
TEST(LlvmLibcPrintfStringWriterTest,WriteCharsMultipleTimes)73 TEST(LlvmLibcPrintfStringWriterTest, WriteCharsMultipleTimes) {
74 char str[10];
75 __llvm_libc::printf_core::StringWriter str_writer(str);
76 __llvm_libc::printf_core::Writer writer(
77 reinterpret_cast<void *>(&str_writer),
78 __llvm_libc::printf_core::write_to_string);
79 writer.write_chars('a', 3);
80 writer.write_chars('D', 3);
81 writer.write_chars('1', 3);
82
83 str_writer.terminate();
84
85 ASSERT_STREQ("aaaDDD111", str);
86 ASSERT_EQ(writer.get_chars_written(), 9);
87 }
88
TEST(LlvmLibcPrintfStringWriterTest,WriteManyChars)89 TEST(LlvmLibcPrintfStringWriterTest, WriteManyChars) {
90 char str[100];
91 __llvm_libc::printf_core::StringWriter str_writer(str);
92 __llvm_libc::printf_core::Writer writer(
93 reinterpret_cast<void *>(&str_writer),
94 __llvm_libc::printf_core::write_to_string);
95 writer.write_chars('Z', 99);
96
97 str_writer.terminate();
98
99 ASSERT_STREQ("ZZZZZZZZZZ"
100 "ZZZZZZZZZZ"
101 "ZZZZZZZZZZ"
102 "ZZZZZZZZZZ"
103 "ZZZZZZZZZZ"
104 "ZZZZZZZZZZ"
105 "ZZZZZZZZZZ"
106 "ZZZZZZZZZZ"
107 "ZZZZZZZZZZ"
108 "ZZZZZZZZZ",
109 str);
110 ASSERT_EQ(writer.get_chars_written(), 99);
111 }
112
TEST(LlvmLibcPrintfStringWriterTest,MixedWrites)113 TEST(LlvmLibcPrintfStringWriterTest, MixedWrites) {
114 char str[13];
115 __llvm_libc::printf_core::StringWriter str_writer(str);
116 __llvm_libc::printf_core::Writer writer(
117 reinterpret_cast<void *>(&str_writer),
118 __llvm_libc::printf_core::write_to_string);
119 writer.write_chars('a', 3);
120 writer.write("DEF", 3);
121 writer.write_chars('1', 3);
122 writer.write("456", 3);
123
124 str_writer.terminate();
125
126 ASSERT_STREQ("aaaDEF111456", str);
127 ASSERT_EQ(writer.get_chars_written(), 12);
128 }
129
TEST(LlvmLibcPrintfStringWriterTest,WriteWithMaxLength)130 TEST(LlvmLibcPrintfStringWriterTest, WriteWithMaxLength) {
131 char str[11];
132 __llvm_libc::printf_core::StringWriter str_writer(str, 10);
133 __llvm_libc::printf_core::Writer writer(
134 reinterpret_cast<void *>(&str_writer),
135 __llvm_libc::printf_core::write_to_string);
136 writer.write("abcDEF123456", 12);
137
138 str_writer.terminate();
139
140 ASSERT_STREQ("abcDEF1234", str);
141 ASSERT_EQ(writer.get_chars_written(), 12);
142 }
143
TEST(LlvmLibcPrintfStringWriterTest,WriteCharsWithMaxLength)144 TEST(LlvmLibcPrintfStringWriterTest, WriteCharsWithMaxLength) {
145 char str[11];
146 __llvm_libc::printf_core::StringWriter str_writer(str, 10);
147 __llvm_libc::printf_core::Writer writer(
148 reinterpret_cast<void *>(&str_writer),
149 __llvm_libc::printf_core::write_to_string);
150
151 writer.write_chars('1', 15);
152
153 str_writer.terminate();
154
155 ASSERT_STREQ("1111111111", str);
156 ASSERT_EQ(writer.get_chars_written(), 15);
157 }
158
TEST(LlvmLibcPrintfStringWriterTest,MixedWriteWithMaxLength)159 TEST(LlvmLibcPrintfStringWriterTest, MixedWriteWithMaxLength) {
160 char str[11];
161 __llvm_libc::printf_core::StringWriter str_writer(str, 10);
162 __llvm_libc::printf_core::Writer writer(
163 reinterpret_cast<void *>(&str_writer),
164 __llvm_libc::printf_core::write_to_string);
165 writer.write_chars('a', 3);
166 writer.write("DEF", 3);
167 writer.write_chars('1', 3);
168 writer.write("456", 3);
169
170 str_writer.terminate();
171
172 ASSERT_STREQ("aaaDEF1114", str);
173 ASSERT_EQ(writer.get_chars_written(), 12);
174 }
175
TEST(LlvmLibcPrintfStringWriterTest,StringWithMaxLengthOne)176 TEST(LlvmLibcPrintfStringWriterTest, StringWithMaxLengthOne) {
177 char str[1];
178 __llvm_libc::printf_core::StringWriter str_writer(str, 0);
179 __llvm_libc::printf_core::Writer writer(
180 reinterpret_cast<void *>(&str_writer),
181 __llvm_libc::printf_core::write_to_string);
182 // This is because the max length should be at most 1 less than the size of
183 // the buffer it's writing to.
184 writer.write_chars('a', 3);
185 writer.write("DEF", 3);
186 writer.write_chars('1', 3);
187 writer.write("456", 3);
188
189 str_writer.terminate();
190
191 ASSERT_STREQ("", str);
192 ASSERT_EQ(writer.get_chars_written(), 12);
193 }
194
TEST(LlvmLibcPrintfStringWriterTest,NullStringWithZeroMaxLength)195 TEST(LlvmLibcPrintfStringWriterTest, NullStringWithZeroMaxLength) {
196 __llvm_libc::printf_core::StringWriter str_writer(nullptr, 0);
197 __llvm_libc::printf_core::Writer writer(
198 reinterpret_cast<void *>(&str_writer),
199 __llvm_libc::printf_core::write_to_string);
200 writer.write_chars('a', 3);
201 writer.write("DEF", 3);
202 writer.write_chars('1', 3);
203 writer.write("456", 3);
204
205 ASSERT_EQ(writer.get_chars_written(), 12);
206 }
207