brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.9 KiB · 8f9ed41 Raw
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