1 | //===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream tests -----===// |
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 "llvm/ADT/SmallString.h" |
10 | #include "llvm/Support/Errc.h" |
11 | #include "llvm/Support/FileSystem.h" |
12 | #include "llvm/Support/FileUtilities.h" |
13 | #include "llvm/Support/Format.h" |
14 | #include "llvm/Support/MemoryBuffer.h" |
15 | #include "llvm/Support/raw_ostream.h" |
16 | #include "llvm/Testing/Support/Error.h" |
17 | #include "gtest/gtest.h" |
18 | #include <optional> |
19 | |
20 | using namespace llvm; |
21 | |
22 | namespace { |
23 | |
24 | template<typename T> std::string printToString(const T &Value) { |
25 | std::string res; |
26 | llvm::raw_string_ostream OS(res); |
27 | OS.SetBuffered(); |
28 | OS << Value; |
29 | OS.flush(); |
30 | return res; |
31 | } |
32 | |
33 | /// printToString - Print the given value to a stream which only has \arg |
34 | /// BytesLeftInBuffer bytes left in the buffer. This is useful for testing edge |
35 | /// cases in the buffer handling logic. |
36 | template<typename T> std::string printToString(const T &Value, |
37 | unsigned BytesLeftInBuffer) { |
38 | // FIXME: This is relying on internal knowledge of how raw_ostream works to |
39 | // get the buffer position right. |
40 | SmallString<256> SVec; |
41 | assert(BytesLeftInBuffer < 256 && "Invalid buffer count!" ); |
42 | llvm::raw_svector_ostream OS(SVec); |
43 | unsigned StartIndex = 256 - BytesLeftInBuffer; |
44 | for (unsigned i = 0; i != StartIndex; ++i) |
45 | OS << '?'; |
46 | OS << Value; |
47 | return std::string(OS.str().substr(Start: StartIndex)); |
48 | } |
49 | |
50 | template<typename T> std::string printToStringUnbuffered(const T &Value) { |
51 | std::string res; |
52 | llvm::raw_string_ostream OS(res); |
53 | OS.SetUnbuffered(); |
54 | OS << Value; |
55 | return res; |
56 | } |
57 | |
58 | struct X {}; |
59 | |
60 | raw_ostream &operator<<(raw_ostream &OS, const X &) { return OS << 'X'; } |
61 | |
62 | TEST(raw_ostreamTest, Types_Buffered) { |
63 | // Char |
64 | EXPECT_EQ("c" , printToString('c')); |
65 | |
66 | // String |
67 | EXPECT_EQ("hello" , printToString("hello" )); |
68 | EXPECT_EQ("hello" , printToString(std::string("hello" ))); |
69 | |
70 | // Int |
71 | EXPECT_EQ("0" , printToString(0)); |
72 | EXPECT_EQ("2425" , printToString(2425)); |
73 | EXPECT_EQ("-2425" , printToString(-2425)); |
74 | |
75 | // Long long |
76 | EXPECT_EQ("0" , printToString(0LL)); |
77 | EXPECT_EQ("257257257235709" , printToString(257257257235709LL)); |
78 | EXPECT_EQ("-257257257235709" , printToString(-257257257235709LL)); |
79 | |
80 | // Double |
81 | EXPECT_EQ("1.100000e+00" , printToString(1.1)); |
82 | |
83 | // void* |
84 | EXPECT_EQ("0x0" , printToString((void*) nullptr)); |
85 | EXPECT_EQ("0xbeef" , printToString((void*) 0xbeefLL)); |
86 | EXPECT_EQ("0xdeadbeef" , printToString((void*) 0xdeadbeefLL)); |
87 | |
88 | // Min and max. |
89 | EXPECT_EQ("18446744073709551615" , printToString(UINT64_MAX)); |
90 | EXPECT_EQ("-9223372036854775808" , printToString(INT64_MIN)); |
91 | |
92 | // X, checking free operator<<(). |
93 | EXPECT_EQ("X" , printToString(X{})); |
94 | } |
95 | |
96 | TEST(raw_ostreamTest, Types_Unbuffered) { |
97 | // Char |
98 | EXPECT_EQ("c" , printToStringUnbuffered('c')); |
99 | |
100 | // String |
101 | EXPECT_EQ("hello" , printToStringUnbuffered("hello" )); |
102 | EXPECT_EQ("hello" , printToStringUnbuffered(std::string("hello" ))); |
103 | |
104 | // Int |
105 | EXPECT_EQ("0" , printToStringUnbuffered(0)); |
106 | EXPECT_EQ("2425" , printToStringUnbuffered(2425)); |
107 | EXPECT_EQ("-2425" , printToStringUnbuffered(-2425)); |
108 | |
109 | // Long long |
110 | EXPECT_EQ("0" , printToStringUnbuffered(0LL)); |
111 | EXPECT_EQ("257257257235709" , printToStringUnbuffered(257257257235709LL)); |
112 | EXPECT_EQ("-257257257235709" , printToStringUnbuffered(-257257257235709LL)); |
113 | |
114 | // Double |
115 | EXPECT_EQ("1.100000e+00" , printToStringUnbuffered(1.1)); |
116 | |
117 | // void* |
118 | EXPECT_EQ("0x0" , printToStringUnbuffered((void*) nullptr)); |
119 | EXPECT_EQ("0xbeef" , printToStringUnbuffered((void*) 0xbeefLL)); |
120 | EXPECT_EQ("0xdeadbeef" , printToStringUnbuffered((void*) 0xdeadbeefLL)); |
121 | |
122 | // Min and max. |
123 | EXPECT_EQ("18446744073709551615" , printToStringUnbuffered(UINT64_MAX)); |
124 | EXPECT_EQ("-9223372036854775808" , printToStringUnbuffered(INT64_MIN)); |
125 | |
126 | // X, checking free operator<<(). |
127 | EXPECT_EQ("X" , printToString(X{})); |
128 | } |
129 | |
130 | TEST(raw_ostreamTest, BufferEdge) { |
131 | EXPECT_EQ("1.20" , printToString(format("%.2f" , 1.2), 1)); |
132 | EXPECT_EQ("1.20" , printToString(format("%.2f" , 1.2), 2)); |
133 | EXPECT_EQ("1.20" , printToString(format("%.2f" , 1.2), 3)); |
134 | EXPECT_EQ("1.20" , printToString(format("%.2f" , 1.2), 4)); |
135 | EXPECT_EQ("1.20" , printToString(format("%.2f" , 1.2), 10)); |
136 | } |
137 | |
138 | TEST(raw_ostreamTest, TinyBuffer) { |
139 | std::string Str; |
140 | raw_string_ostream OS(Str); |
141 | OS.SetBufferSize(1); |
142 | OS << "hello" ; |
143 | OS << 1; |
144 | OS << 'w' << 'o' << 'r' << 'l' << 'd'; |
145 | OS.flush(); |
146 | EXPECT_EQ("hello1world" , Str); |
147 | } |
148 | |
149 | TEST(raw_ostreamTest, WriteEscaped) { |
150 | std::string Str; |
151 | |
152 | Str = "" ; |
153 | raw_string_ostream(Str).write_escaped(Str: "hi" ); |
154 | EXPECT_EQ("hi" , Str); |
155 | |
156 | Str = "" ; |
157 | raw_string_ostream(Str).write_escaped(Str: "\\\t\n\"" ); |
158 | EXPECT_EQ("\\\\\\t\\n\\\"" , Str); |
159 | |
160 | Str = "" ; |
161 | raw_string_ostream(Str).write_escaped(Str: "\1\10\200" ); |
162 | EXPECT_EQ("\\001\\010\\200" , Str); |
163 | } |
164 | |
165 | TEST(raw_ostreamTest, Justify) { |
166 | EXPECT_EQ("xyz " , printToString(left_justify("xyz" , 6), 6)); |
167 | EXPECT_EQ("abc" , printToString(left_justify("abc" , 3), 3)); |
168 | EXPECT_EQ("big" , printToString(left_justify("big" , 1), 3)); |
169 | EXPECT_EQ(" xyz" , printToString(right_justify("xyz" , 6), 6)); |
170 | EXPECT_EQ("abc" , printToString(right_justify("abc" , 3), 3)); |
171 | EXPECT_EQ("big" , printToString(right_justify("big" , 1), 3)); |
172 | EXPECT_EQ(" on " , printToString(center_justify("on" , 9), 9)); |
173 | EXPECT_EQ(" off " , printToString(center_justify("off" , 10), 10)); |
174 | EXPECT_EQ("single " , printToString(center_justify("single" , 7), 7)); |
175 | EXPECT_EQ("none" , printToString(center_justify("none" , 1), 4)); |
176 | EXPECT_EQ("none" , printToString(center_justify("none" , 1), 1)); |
177 | } |
178 | |
179 | TEST(raw_ostreamTest, FormatHex) { |
180 | EXPECT_EQ("0x1234" , printToString(format_hex(0x1234, 6), 6)); |
181 | EXPECT_EQ("0x001234" , printToString(format_hex(0x1234, 8), 8)); |
182 | EXPECT_EQ("0x00001234" , printToString(format_hex(0x1234, 10), 10)); |
183 | EXPECT_EQ("0x1234" , printToString(format_hex(0x1234, 4), 6)); |
184 | EXPECT_EQ("0xff" , printToString(format_hex(255, 4), 4)); |
185 | EXPECT_EQ("0xFF" , printToString(format_hex(255, 4, true), 4)); |
186 | EXPECT_EQ("0x1" , printToString(format_hex(1, 3), 3)); |
187 | EXPECT_EQ("0x12" , printToString(format_hex(0x12, 3), 4)); |
188 | EXPECT_EQ("0x123" , printToString(format_hex(0x123, 3), 5)); |
189 | EXPECT_EQ("FF" , printToString(format_hex_no_prefix(0xFF, 2, true), 4)); |
190 | EXPECT_EQ("ABCD" , printToString(format_hex_no_prefix(0xABCD, 2, true), 4)); |
191 | EXPECT_EQ("0xffffffffffffffff" , |
192 | printToString(format_hex(UINT64_MAX, 18), 18)); |
193 | EXPECT_EQ("0x8000000000000000" , |
194 | printToString(format_hex((INT64_MIN), 18), 18)); |
195 | } |
196 | |
197 | TEST(raw_ostreamTest, FormatDecimal) { |
198 | EXPECT_EQ(" 0" , printToString(format_decimal(0, 4), 4)); |
199 | EXPECT_EQ(" -1" , printToString(format_decimal(-1, 4), 4)); |
200 | EXPECT_EQ(" -1" , printToString(format_decimal(-1, 6), 6)); |
201 | EXPECT_EQ("1234567890" , printToString(format_decimal(1234567890, 10), 10)); |
202 | EXPECT_EQ(" 9223372036854775807" , |
203 | printToString(format_decimal(INT64_MAX, 21), 21)); |
204 | EXPECT_EQ(" -9223372036854775808" , |
205 | printToString(format_decimal(INT64_MIN, 21), 21)); |
206 | } |
207 | |
208 | static std::string |
209 | formatted_bytes_str(ArrayRef<uint8_t> Bytes, |
210 | std::optional<uint64_t> Offset = std::nullopt, |
211 | uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4) { |
212 | std::string S; |
213 | raw_string_ostream Str(S); |
214 | Str << format_bytes(Bytes, FirstByteOffset: Offset, NumPerLine, ByteGroupSize); |
215 | Str.flush(); |
216 | return S; |
217 | } |
218 | |
219 | static std::string format_bytes_with_ascii_str( |
220 | ArrayRef<uint8_t> Bytes, std::optional<uint64_t> Offset = std::nullopt, |
221 | uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4) { |
222 | std::string S; |
223 | raw_string_ostream Str(S); |
224 | Str << format_bytes_with_ascii(Bytes, FirstByteOffset: Offset, NumPerLine, ByteGroupSize); |
225 | Str.flush(); |
226 | return S; |
227 | } |
228 | |
229 | TEST(raw_ostreamTest, FormattedHexBytes) { |
230 | std::vector<uint8_t> Buf = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', |
231 | 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', |
232 | 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', |
233 | '1', '2', '3', '4', '5', '6', '7', '8', '9'}; |
234 | ArrayRef<uint8_t> B(Buf); |
235 | |
236 | // Test invalid input. |
237 | EXPECT_EQ("" , formatted_bytes_str(ArrayRef<uint8_t>())); |
238 | EXPECT_EQ("" , format_bytes_with_ascii_str(ArrayRef<uint8_t>())); |
239 | //---------------------------------------------------------------------- |
240 | // Test hex byte output with the default 4 byte groups |
241 | //---------------------------------------------------------------------- |
242 | EXPECT_EQ("61" , formatted_bytes_str(B.take_front())); |
243 | EXPECT_EQ("61626364 65" , formatted_bytes_str(B.take_front(5))); |
244 | // Test that 16 bytes get written to a line correctly. |
245 | EXPECT_EQ("61626364 65666768 696a6b6c 6d6e6f70" , |
246 | formatted_bytes_str(B.take_front(16))); |
247 | // Test raw bytes with default 16 bytes per line wrapping. |
248 | EXPECT_EQ("61626364 65666768 696a6b6c 6d6e6f70\n71" , |
249 | formatted_bytes_str(B.take_front(17))); |
250 | // Test raw bytes with 1 bytes per line wrapping. |
251 | EXPECT_EQ("61\n62\n63\n64\n65\n66" , |
252 | formatted_bytes_str(B.take_front(6), std::nullopt, 1)); |
253 | // Test raw bytes with 7 bytes per line wrapping. |
254 | EXPECT_EQ("61626364 656667\n68696a6b 6c6d6e\n6f7071" , |
255 | formatted_bytes_str(B.take_front(17), std::nullopt, 7)); |
256 | // Test raw bytes with 8 bytes per line wrapping. |
257 | EXPECT_EQ("61626364 65666768\n696a6b6c 6d6e6f70\n71" , |
258 | formatted_bytes_str(B.take_front(17), std::nullopt, 8)); |
259 | //---------------------------------------------------------------------- |
260 | // Test hex byte output with the 1 byte groups |
261 | //---------------------------------------------------------------------- |
262 | EXPECT_EQ("61 62 63 64 65" , |
263 | formatted_bytes_str(B.take_front(5), std::nullopt, 16, 1)); |
264 | // Test that 16 bytes get written to a line correctly. |
265 | EXPECT_EQ("61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70" , |
266 | formatted_bytes_str(B.take_front(16), std::nullopt, 16, 1)); |
267 | // Test raw bytes with default 16 bytes per line wrapping. |
268 | EXPECT_EQ("61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70\n71" , |
269 | formatted_bytes_str(B.take_front(17), std::nullopt, 16, 1)); |
270 | // Test raw bytes with 7 bytes per line wrapping. |
271 | EXPECT_EQ("61 62 63 64 65 66 67\n68 69 6a 6b 6c 6d 6e\n6f 70 71" , |
272 | formatted_bytes_str(B.take_front(17), std::nullopt, 7, 1)); |
273 | // Test raw bytes with 8 bytes per line wrapping. |
274 | EXPECT_EQ("61 62 63 64 65 66 67 68\n69 6a 6b 6c 6d 6e 6f 70\n71" , |
275 | formatted_bytes_str(B.take_front(17), std::nullopt, 8, 1)); |
276 | |
277 | //---------------------------------------------------------------------- |
278 | // Test hex byte output with the 2 byte groups |
279 | //---------------------------------------------------------------------- |
280 | EXPECT_EQ("6162 6364 65" , |
281 | formatted_bytes_str(B.take_front(5), std::nullopt, 16, 2)); |
282 | // Test that 16 bytes get written to a line correctly. |
283 | EXPECT_EQ("6162 6364 6566 6768 696a 6b6c 6d6e 6f70" , |
284 | formatted_bytes_str(B.take_front(16), std::nullopt, 16, 2)); |
285 | // Test raw bytes with default 16 bytes per line wrapping. |
286 | EXPECT_EQ("6162 6364 6566 6768 696a 6b6c 6d6e 6f70\n71" , |
287 | formatted_bytes_str(B.take_front(17), std::nullopt, 16, 2)); |
288 | // Test raw bytes with 7 bytes per line wrapping. |
289 | EXPECT_EQ("6162 6364 6566 67\n6869 6a6b 6c6d 6e\n6f70 71" , |
290 | formatted_bytes_str(B.take_front(17), std::nullopt, 7, 2)); |
291 | // Test raw bytes with 8 bytes per line wrapping. |
292 | EXPECT_EQ("6162 6364 6566 6768\n696a 6b6c 6d6e 6f70\n71" , |
293 | formatted_bytes_str(B.take_front(17), std::nullopt, 8, 2)); |
294 | |
295 | //---------------------------------------------------------------------- |
296 | // Test hex bytes with offset with the default 4 byte groups. |
297 | //---------------------------------------------------------------------- |
298 | EXPECT_EQ("0000: 61" , formatted_bytes_str(B.take_front(), 0x0)); |
299 | EXPECT_EQ("1000: 61" , formatted_bytes_str(B.take_front(), 0x1000)); |
300 | EXPECT_EQ("1000: 61\n1001: 62" , |
301 | formatted_bytes_str(B.take_front(2), 0x1000, 1)); |
302 | //---------------------------------------------------------------------- |
303 | // Test hex bytes with ASCII with the default 4 byte groups. |
304 | //---------------------------------------------------------------------- |
305 | EXPECT_EQ("61626364 65666768 696a6b6c 6d6e6f70 |abcdefghijklmnop|" , |
306 | format_bytes_with_ascii_str(B.take_front(16))); |
307 | EXPECT_EQ("61626364 65666768 |abcdefgh|\n" |
308 | "696a6b6c 6d6e6f70 |ijklmnop|" , |
309 | format_bytes_with_ascii_str(B.take_front(16), std::nullopt, 8)); |
310 | EXPECT_EQ("61626364 65666768 |abcdefgh|\n696a6b6c |ijkl|" , |
311 | format_bytes_with_ascii_str(B.take_front(12), std::nullopt, 8)); |
312 | std::vector<uint8_t> Unprintable = {'a', '\x1e', 'b', '\x1f'}; |
313 | // Make sure the ASCII is still lined up correctly when fewer bytes than 16 |
314 | // bytes per line are available. The ASCII should still be aligned as if 16 |
315 | // bytes of hex might be displayed. |
316 | EXPECT_EQ("611e621f |a.b.|" , |
317 | format_bytes_with_ascii_str(Unprintable)); |
318 | //---------------------------------------------------------------------- |
319 | // Test hex bytes with ASCII with offsets with the default 4 byte groups. |
320 | //---------------------------------------------------------------------- |
321 | EXPECT_EQ("0000: 61626364 65666768 " |
322 | "696a6b6c 6d6e6f70 |abcdefghijklmnop|" , |
323 | format_bytes_with_ascii_str(B.take_front(16), 0)); |
324 | EXPECT_EQ("0000: 61626364 65666768 |abcdefgh|\n" |
325 | "0008: 696a6b6c 6d6e6f70 |ijklmnop|" , |
326 | format_bytes_with_ascii_str(B.take_front(16), 0, 8)); |
327 | EXPECT_EQ("0000: 61626364 656667 |abcdefg|\n" |
328 | "0007: 68696a6b 6c |hijkl|" , |
329 | format_bytes_with_ascii_str(B.take_front(12), 0, 7)); |
330 | |
331 | //---------------------------------------------------------------------- |
332 | // Test hex bytes with ASCII with offsets with the default 2 byte groups. |
333 | //---------------------------------------------------------------------- |
334 | EXPECT_EQ("0000: 6162 6364 6566 6768 " |
335 | "696a 6b6c 6d6e 6f70 |abcdefghijklmnop|" , |
336 | format_bytes_with_ascii_str(B.take_front(16), 0, 16, 2)); |
337 | EXPECT_EQ("0000: 6162 6364 6566 6768 |abcdefgh|\n" |
338 | "0008: 696a 6b6c 6d6e 6f70 |ijklmnop|" , |
339 | format_bytes_with_ascii_str(B.take_front(16), 0, 8, 2)); |
340 | EXPECT_EQ("0000: 6162 6364 6566 67 |abcdefg|\n" |
341 | "0007: 6869 6a6b 6c |hijkl|" , |
342 | format_bytes_with_ascii_str(B.take_front(12), 0, 7, 2)); |
343 | |
344 | //---------------------------------------------------------------------- |
345 | // Test hex bytes with ASCII with offsets with the default 1 byte groups. |
346 | //---------------------------------------------------------------------- |
347 | EXPECT_EQ("0000: 61 62 63 64 65 66 67 68 " |
348 | "69 6a 6b 6c 6d 6e 6f 70 |abcdefghijklmnop|" , |
349 | format_bytes_with_ascii_str(B.take_front(16), 0, 16, 1)); |
350 | EXPECT_EQ("0000: 61 62 63 64 65 66 67 68 |abcdefgh|\n" |
351 | "0008: 69 6a 6b 6c 6d 6e 6f 70 |ijklmnop|" , |
352 | format_bytes_with_ascii_str(B.take_front(16), 0, 8, 1)); |
353 | EXPECT_EQ("0000: 61 62 63 64 65 66 67 |abcdefg|\n" |
354 | "0007: 68 69 6a 6b 6c |hijkl|" , |
355 | format_bytes_with_ascii_str(B.take_front(12), 0, 7, 1)); |
356 | } |
357 | |
358 | #ifdef LLVM_ON_UNIX |
359 | TEST(raw_ostreamTest, Colors) { |
360 | { |
361 | std::string S; |
362 | raw_string_ostream Sos(S); |
363 | Sos.enable_colors(enable: false); |
364 | Sos.changeColor(Color: raw_ostream::YELLOW); |
365 | EXPECT_EQ("" , Sos.str()); |
366 | } |
367 | |
368 | { |
369 | std::string S; |
370 | raw_string_ostream Sos(S); |
371 | Sos.enable_colors(enable: true); |
372 | Sos.changeColor(Color: raw_ostream::YELLOW); |
373 | EXPECT_EQ("\x1B[0;33m" , Sos.str()); |
374 | } |
375 | } |
376 | #endif |
377 | |
378 | TEST(raw_fd_ostreamTest, multiple_raw_fd_ostream_to_stdout) { |
379 | std::error_code EC; |
380 | |
381 | { raw_fd_ostream("-" , EC, sys::fs::OpenFlags::OF_None); } |
382 | { raw_fd_ostream("-" , EC, sys::fs::OpenFlags::OF_None); } |
383 | } |
384 | |
385 | TEST(raw_ostreamTest, flush_tied_to_stream_on_write) { |
386 | std::string TiedToBuffer; |
387 | raw_string_ostream TiedTo(TiedToBuffer); |
388 | TiedTo.SetBuffered(); |
389 | TiedTo << "a" ; |
390 | |
391 | std::string Buffer; |
392 | raw_string_ostream TiedStream(Buffer); |
393 | TiedStream.tie(TieTo: &TiedTo); |
394 | // Sanity check that the stream hasn't already been flushed. |
395 | EXPECT_EQ("" , TiedToBuffer); |
396 | |
397 | // Empty string doesn't cause a flush of TiedTo. |
398 | TiedStream << "" ; |
399 | EXPECT_EQ("" , TiedToBuffer); |
400 | |
401 | // Non-empty strings trigger flush of TiedTo. |
402 | TiedStream << "abc" ; |
403 | EXPECT_EQ("a" , TiedToBuffer); |
404 | |
405 | // Single char write flushes TiedTo. |
406 | TiedTo << "c" ; |
407 | TiedStream << 'd'; |
408 | EXPECT_EQ("ac" , TiedToBuffer); |
409 | |
410 | // Write to buffered stream without flush does not flush TiedTo. |
411 | TiedStream.SetBuffered(); |
412 | TiedStream.SetBufferSize(2); |
413 | TiedTo << "e" ; |
414 | TiedStream << "f" ; |
415 | EXPECT_EQ("ac" , TiedToBuffer); |
416 | |
417 | // Explicit flush of buffered stream flushes TiedTo. |
418 | TiedStream.flush(); |
419 | EXPECT_EQ("ace" , TiedToBuffer); |
420 | |
421 | // Explicit flush of buffered stream with empty buffer does not flush TiedTo. |
422 | TiedTo << "g" ; |
423 | TiedStream.flush(); |
424 | EXPECT_EQ("ace" , TiedToBuffer); |
425 | |
426 | // Write of data to empty buffer that is greater than buffer size flushes |
427 | // TiedTo. |
428 | TiedStream << "hijklm" ; |
429 | EXPECT_EQ("aceg" , TiedToBuffer); |
430 | |
431 | // Write of data that overflows buffer size also flushes TiedTo. |
432 | TiedStream.flush(); |
433 | TiedStream << "n" ; |
434 | TiedTo << "o" ; |
435 | TiedStream << "pq" ; |
436 | EXPECT_EQ("acego" , TiedToBuffer); |
437 | |
438 | // Streams can be tied to each other safely. |
439 | TiedStream.flush(); |
440 | Buffer = "" ; |
441 | TiedTo.tie(TieTo: &TiedStream); |
442 | TiedTo.SetBufferSize(2); |
443 | TiedStream << "r" ; |
444 | TiedTo << "s" ; |
445 | EXPECT_EQ("" , Buffer); |
446 | EXPECT_EQ("acego" , TiedToBuffer); |
447 | TiedTo << "tuv" ; |
448 | EXPECT_EQ("r" , Buffer); |
449 | TiedStream << "wxy" ; |
450 | EXPECT_EQ("acegostuv" , TiedToBuffer); |
451 | // The x remains in the buffer, since it was written after the flush of |
452 | // TiedTo. |
453 | EXPECT_EQ("rwx" , Buffer); |
454 | TiedTo.tie(TieTo: nullptr); |
455 | |
456 | // Calling tie with nullptr unties stream. |
457 | TiedStream.SetUnbuffered(); |
458 | TiedStream.tie(TieTo: nullptr); |
459 | TiedTo << "y" ; |
460 | TiedStream << "0" ; |
461 | EXPECT_EQ("acegostuv" , TiedToBuffer); |
462 | |
463 | TiedTo.flush(); |
464 | TiedStream.flush(); |
465 | } |
466 | |
467 | TEST(raw_ostreamTest, reserve_stream) { |
468 | std::string Str; |
469 | raw_string_ostream OS(Str); |
470 | OS << "11111111111111111111" ; |
471 | uint64_t CurrentPos = OS.tell(); |
472 | OS.reserveExtraSpace(ExtraSize: 1000); |
473 | EXPECT_GE(Str.capacity(), CurrentPos + 1000); |
474 | OS << "hello" ; |
475 | OS << 1; |
476 | OS << 'w' << 'o' << 'r' << 'l' << 'd'; |
477 | OS.flush(); |
478 | EXPECT_EQ("11111111111111111111hello1world" , Str); |
479 | } |
480 | |
481 | static void checkFileData(StringRef FileName, StringRef GoldenData) { |
482 | ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = |
483 | MemoryBuffer::getFileOrSTDIN(Filename: FileName); |
484 | EXPECT_FALSE(BufOrErr.getError()); |
485 | |
486 | EXPECT_EQ((*BufOrErr)->getBufferSize(), GoldenData.size()); |
487 | EXPECT_EQ(memcmp((*BufOrErr)->getBufferStart(), GoldenData.data(), |
488 | GoldenData.size()), |
489 | 0); |
490 | } |
491 | |
492 | TEST(raw_ostreamTest, writeToOutputFile) { |
493 | SmallString<64> Path; |
494 | int FD; |
495 | ASSERT_FALSE(sys::fs::createTemporaryFile("foo" , "bar" , FD, Path)); |
496 | FileRemover Cleanup(Path); |
497 | |
498 | ASSERT_THAT_ERROR(writeToOutput(Path, |
499 | [](raw_ostream &Out) -> Error { |
500 | Out << "HelloWorld" ; |
501 | return Error::success(); |
502 | }), |
503 | Succeeded()); |
504 | checkFileData(FileName: Path, GoldenData: "HelloWorld" ); |
505 | } |
506 | |
507 | #ifndef _WIN32 |
508 | TEST(raw_ostreamTest, filePermissions) { |
509 | // Set umask to be permissive of all permissions. |
510 | unsigned OldMask = ::umask(mask: 0); |
511 | |
512 | llvm::unittest::TempDir RootTestDirectory("writToOutput" , /*Unique*/ true); |
513 | SmallString<128> Path(RootTestDirectory.path()); |
514 | sys::path::append(path&: Path, a: "test.txt" ); |
515 | |
516 | ASSERT_THAT_ERROR(writeToOutput(Path, |
517 | [](raw_ostream &Out) -> Error { |
518 | Out << "HelloWorld" ; |
519 | return Error::success(); |
520 | }), |
521 | Succeeded()); |
522 | |
523 | ErrorOr<llvm::sys::fs::perms> Perms = llvm::sys::fs::getPermissions(Path); |
524 | ASSERT_TRUE(Perms) << "should be able to get permissions" ; |
525 | // Verify the permission bits set by writeToOutput are read and write only. |
526 | EXPECT_EQ(Perms.get(), llvm::sys::fs::all_read | llvm::sys::fs::all_write); |
527 | |
528 | ::umask(mask: OldMask); |
529 | } |
530 | #endif |
531 | |
532 | TEST(raw_ostreamTest, writeToNonexistingPath) { |
533 | StringRef FileName = "/_bad/_path" ; |
534 | std::string ErrorMessage = toString(E: createFileError( |
535 | F: FileName, EC: make_error_code(E: errc::no_such_file_or_directory))); |
536 | |
537 | EXPECT_THAT_ERROR(writeToOutput(FileName, |
538 | [](raw_ostream &Out) -> Error { |
539 | Out << "HelloWorld" ; |
540 | return Error::success(); |
541 | }), |
542 | FailedWithMessage(ErrorMessage)); |
543 | } |
544 | |
545 | TEST(raw_ostreamTest, writeToDevNull) { |
546 | bool DevNullIsUsed = false; |
547 | |
548 | EXPECT_THAT_ERROR( |
549 | writeToOutput("/dev/null" , |
550 | [&](raw_ostream &Out) -> Error { |
551 | DevNullIsUsed = |
552 | testing::internal::CheckedDowncastToActualType< |
553 | raw_null_ostream, raw_ostream>(&Out); |
554 | return Error::success(); |
555 | }), |
556 | Succeeded()); |
557 | |
558 | EXPECT_TRUE(DevNullIsUsed); |
559 | } |
560 | |
561 | TEST(raw_ostreamTest, writeToStdOut) { |
562 | outs().flush(); |
563 | testing::internal::CaptureStdout(); |
564 | |
565 | EXPECT_THAT_ERROR(writeToOutput("-" , |
566 | [](raw_ostream &Out) -> Error { |
567 | Out << "HelloWorld" ; |
568 | return Error::success(); |
569 | }), |
570 | Succeeded()); |
571 | outs().flush(); |
572 | |
573 | std::string CapturedStdOut = testing::internal::GetCapturedStdout(); |
574 | EXPECT_EQ(CapturedStdOut, "HelloWorld" ); |
575 | } |
576 | |
577 | } // namespace |
578 | |