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