109467b48Spatrick //===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This implements support for bulk buffered stream output.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick
1309467b48Spatrick #include "llvm/Support/raw_ostream.h"
1409467b48Spatrick #include "llvm/ADT/StringExtras.h"
1509467b48Spatrick #include "llvm/Config/config.h"
1609467b48Spatrick #include "llvm/Support/Compiler.h"
17*d415bd75Srobert #include "llvm/Support/Duration.h"
1809467b48Spatrick #include "llvm/Support/ErrorHandling.h"
1909467b48Spatrick #include "llvm/Support/FileSystem.h"
2009467b48Spatrick #include "llvm/Support/Format.h"
2109467b48Spatrick #include "llvm/Support/FormatVariadic.h"
2209467b48Spatrick #include "llvm/Support/MathExtras.h"
2309467b48Spatrick #include "llvm/Support/NativeFormatting.h"
2409467b48Spatrick #include "llvm/Support/Process.h"
2509467b48Spatrick #include "llvm/Support/Program.h"
2609467b48Spatrick #include <algorithm>
2709467b48Spatrick #include <cerrno>
2809467b48Spatrick #include <cstdio>
2909467b48Spatrick #include <sys/stat.h>
3009467b48Spatrick
3109467b48Spatrick // <fcntl.h> may provide O_BINARY.
3209467b48Spatrick #if defined(HAVE_FCNTL_H)
3309467b48Spatrick # include <fcntl.h>
3409467b48Spatrick #endif
3509467b48Spatrick
3609467b48Spatrick #if defined(HAVE_UNISTD_H)
3709467b48Spatrick # include <unistd.h>
3809467b48Spatrick #endif
3909467b48Spatrick
4009467b48Spatrick #if defined(__CYGWIN__)
4109467b48Spatrick #include <io.h>
4209467b48Spatrick #endif
4309467b48Spatrick
4409467b48Spatrick #if defined(_MSC_VER)
4509467b48Spatrick #include <io.h>
4609467b48Spatrick #ifndef STDIN_FILENO
4709467b48Spatrick # define STDIN_FILENO 0
4809467b48Spatrick #endif
4909467b48Spatrick #ifndef STDOUT_FILENO
5009467b48Spatrick # define STDOUT_FILENO 1
5109467b48Spatrick #endif
5209467b48Spatrick #ifndef STDERR_FILENO
5309467b48Spatrick # define STDERR_FILENO 2
5409467b48Spatrick #endif
5509467b48Spatrick #endif
5609467b48Spatrick
5709467b48Spatrick #ifdef _WIN32
5809467b48Spatrick #include "llvm/Support/ConvertUTF.h"
59*d415bd75Srobert #include "llvm/Support/Signals.h"
6009467b48Spatrick #include "llvm/Support/Windows/WindowsSupport.h"
6109467b48Spatrick #endif
6209467b48Spatrick
6309467b48Spatrick using namespace llvm;
6409467b48Spatrick
65097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::BLACK;
66097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::RED;
67097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::GREEN;
68097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::YELLOW;
69097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::BLUE;
70097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::MAGENTA;
71097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::CYAN;
72097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::WHITE;
73097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
74097a140dSpatrick constexpr raw_ostream::Colors raw_ostream::RESET;
7509467b48Spatrick
~raw_ostream()7609467b48Spatrick raw_ostream::~raw_ostream() {
7709467b48Spatrick // raw_ostream's subclasses should take care to flush the buffer
7809467b48Spatrick // in their destructors.
7909467b48Spatrick assert(OutBufCur == OutBufStart &&
8009467b48Spatrick "raw_ostream destructor called with non-empty buffer!");
8109467b48Spatrick
8209467b48Spatrick if (BufferMode == BufferKind::InternalBuffer)
8309467b48Spatrick delete [] OutBufStart;
8409467b48Spatrick }
8509467b48Spatrick
preferred_buffer_size() const8609467b48Spatrick size_t raw_ostream::preferred_buffer_size() const {
87*d415bd75Srobert #ifdef _WIN32
88*d415bd75Srobert // On Windows BUFSIZ is only 512 which results in more calls to write. This
89*d415bd75Srobert // overhead can cause significant performance degradation. Therefore use a
90*d415bd75Srobert // better default.
91*d415bd75Srobert return (16 * 1024);
92*d415bd75Srobert #else
9309467b48Spatrick // BUFSIZ is intended to be a reasonable default.
9409467b48Spatrick return BUFSIZ;
95*d415bd75Srobert #endif
9609467b48Spatrick }
9709467b48Spatrick
SetBuffered()9809467b48Spatrick void raw_ostream::SetBuffered() {
9909467b48Spatrick // Ask the subclass to determine an appropriate buffer size.
10009467b48Spatrick if (size_t Size = preferred_buffer_size())
10109467b48Spatrick SetBufferSize(Size);
10209467b48Spatrick else
10309467b48Spatrick // It may return 0, meaning this stream should be unbuffered.
10409467b48Spatrick SetUnbuffered();
10509467b48Spatrick }
10609467b48Spatrick
SetBufferAndMode(char * BufferStart,size_t Size,BufferKind Mode)10709467b48Spatrick void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
10809467b48Spatrick BufferKind Mode) {
10909467b48Spatrick assert(((Mode == BufferKind::Unbuffered && !BufferStart && Size == 0) ||
11009467b48Spatrick (Mode != BufferKind::Unbuffered && BufferStart && Size != 0)) &&
11109467b48Spatrick "stream must be unbuffered or have at least one byte");
11209467b48Spatrick // Make sure the current buffer is free of content (we can't flush here; the
11309467b48Spatrick // child buffer management logic will be in write_impl).
11409467b48Spatrick assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
11509467b48Spatrick
11609467b48Spatrick if (BufferMode == BufferKind::InternalBuffer)
11709467b48Spatrick delete [] OutBufStart;
11809467b48Spatrick OutBufStart = BufferStart;
11909467b48Spatrick OutBufEnd = OutBufStart+Size;
12009467b48Spatrick OutBufCur = OutBufStart;
12109467b48Spatrick BufferMode = Mode;
12209467b48Spatrick
12309467b48Spatrick assert(OutBufStart <= OutBufEnd && "Invalid size!");
12409467b48Spatrick }
12509467b48Spatrick
operator <<(unsigned long N)12609467b48Spatrick raw_ostream &raw_ostream::operator<<(unsigned long N) {
12709467b48Spatrick write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
12809467b48Spatrick return *this;
12909467b48Spatrick }
13009467b48Spatrick
operator <<(long N)13109467b48Spatrick raw_ostream &raw_ostream::operator<<(long N) {
13209467b48Spatrick write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
13309467b48Spatrick return *this;
13409467b48Spatrick }
13509467b48Spatrick
operator <<(unsigned long long N)13609467b48Spatrick raw_ostream &raw_ostream::operator<<(unsigned long long N) {
13709467b48Spatrick write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
13809467b48Spatrick return *this;
13909467b48Spatrick }
14009467b48Spatrick
operator <<(long long N)14109467b48Spatrick raw_ostream &raw_ostream::operator<<(long long N) {
14209467b48Spatrick write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
14309467b48Spatrick return *this;
14409467b48Spatrick }
14509467b48Spatrick
write_hex(unsigned long long N)14609467b48Spatrick raw_ostream &raw_ostream::write_hex(unsigned long long N) {
14709467b48Spatrick llvm::write_hex(*this, N, HexPrintStyle::Lower);
14809467b48Spatrick return *this;
14909467b48Spatrick }
15009467b48Spatrick
operator <<(Colors C)15109467b48Spatrick raw_ostream &raw_ostream::operator<<(Colors C) {
15209467b48Spatrick if (C == Colors::RESET)
15309467b48Spatrick resetColor();
15409467b48Spatrick else
15509467b48Spatrick changeColor(C);
15609467b48Spatrick return *this;
15709467b48Spatrick }
15809467b48Spatrick
write_uuid(const uuid_t UUID)15909467b48Spatrick raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
16009467b48Spatrick for (int Idx = 0; Idx < 16; ++Idx) {
16109467b48Spatrick *this << format("%02" PRIX32, UUID[Idx]);
16209467b48Spatrick if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9)
16309467b48Spatrick *this << "-";
16409467b48Spatrick }
16509467b48Spatrick return *this;
16609467b48Spatrick }
16709467b48Spatrick
16809467b48Spatrick
write_escaped(StringRef Str,bool UseHexEscapes)16909467b48Spatrick raw_ostream &raw_ostream::write_escaped(StringRef Str,
17009467b48Spatrick bool UseHexEscapes) {
17109467b48Spatrick for (unsigned char c : Str) {
17209467b48Spatrick switch (c) {
17309467b48Spatrick case '\\':
17409467b48Spatrick *this << '\\' << '\\';
17509467b48Spatrick break;
17609467b48Spatrick case '\t':
17709467b48Spatrick *this << '\\' << 't';
17809467b48Spatrick break;
17909467b48Spatrick case '\n':
18009467b48Spatrick *this << '\\' << 'n';
18109467b48Spatrick break;
18209467b48Spatrick case '"':
18309467b48Spatrick *this << '\\' << '"';
18409467b48Spatrick break;
18509467b48Spatrick default:
18609467b48Spatrick if (isPrint(c)) {
18709467b48Spatrick *this << c;
18809467b48Spatrick break;
18909467b48Spatrick }
19009467b48Spatrick
19109467b48Spatrick // Write out the escaped representation.
19209467b48Spatrick if (UseHexEscapes) {
19309467b48Spatrick *this << '\\' << 'x';
194*d415bd75Srobert *this << hexdigit((c >> 4) & 0xF);
19509467b48Spatrick *this << hexdigit((c >> 0) & 0xF);
19609467b48Spatrick } else {
19709467b48Spatrick // Always use a full 3-character octal escape.
19809467b48Spatrick *this << '\\';
19909467b48Spatrick *this << char('0' + ((c >> 6) & 7));
20009467b48Spatrick *this << char('0' + ((c >> 3) & 7));
20109467b48Spatrick *this << char('0' + ((c >> 0) & 7));
20209467b48Spatrick }
20309467b48Spatrick }
20409467b48Spatrick }
20509467b48Spatrick
20609467b48Spatrick return *this;
20709467b48Spatrick }
20809467b48Spatrick
operator <<(const void * P)20909467b48Spatrick raw_ostream &raw_ostream::operator<<(const void *P) {
21009467b48Spatrick llvm::write_hex(*this, (uintptr_t)P, HexPrintStyle::PrefixLower);
21109467b48Spatrick return *this;
21209467b48Spatrick }
21309467b48Spatrick
operator <<(double N)21409467b48Spatrick raw_ostream &raw_ostream::operator<<(double N) {
21509467b48Spatrick llvm::write_double(*this, N, FloatStyle::Exponent);
21609467b48Spatrick return *this;
21709467b48Spatrick }
21809467b48Spatrick
flush_nonempty()21909467b48Spatrick void raw_ostream::flush_nonempty() {
22009467b48Spatrick assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
22109467b48Spatrick size_t Length = OutBufCur - OutBufStart;
22209467b48Spatrick OutBufCur = OutBufStart;
223097a140dSpatrick flush_tied_then_write(OutBufStart, Length);
22409467b48Spatrick }
22509467b48Spatrick
write(unsigned char C)22609467b48Spatrick raw_ostream &raw_ostream::write(unsigned char C) {
22709467b48Spatrick // Group exceptional cases into a single branch.
22809467b48Spatrick if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
22909467b48Spatrick if (LLVM_UNLIKELY(!OutBufStart)) {
23009467b48Spatrick if (BufferMode == BufferKind::Unbuffered) {
231097a140dSpatrick flush_tied_then_write(reinterpret_cast<char *>(&C), 1);
23209467b48Spatrick return *this;
23309467b48Spatrick }
23409467b48Spatrick // Set up a buffer and start over.
23509467b48Spatrick SetBuffered();
23609467b48Spatrick return write(C);
23709467b48Spatrick }
23809467b48Spatrick
23909467b48Spatrick flush_nonempty();
24009467b48Spatrick }
24109467b48Spatrick
24209467b48Spatrick *OutBufCur++ = C;
24309467b48Spatrick return *this;
24409467b48Spatrick }
24509467b48Spatrick
write(const char * Ptr,size_t Size)24609467b48Spatrick raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
24709467b48Spatrick // Group exceptional cases into a single branch.
24809467b48Spatrick if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
24909467b48Spatrick if (LLVM_UNLIKELY(!OutBufStart)) {
25009467b48Spatrick if (BufferMode == BufferKind::Unbuffered) {
251097a140dSpatrick flush_tied_then_write(Ptr, Size);
25209467b48Spatrick return *this;
25309467b48Spatrick }
25409467b48Spatrick // Set up a buffer and start over.
25509467b48Spatrick SetBuffered();
25609467b48Spatrick return write(Ptr, Size);
25709467b48Spatrick }
25809467b48Spatrick
25909467b48Spatrick size_t NumBytes = OutBufEnd - OutBufCur;
26009467b48Spatrick
26109467b48Spatrick // If the buffer is empty at this point we have a string that is larger
26209467b48Spatrick // than the buffer. Directly write the chunk that is a multiple of the
26309467b48Spatrick // preferred buffer size and put the remainder in the buffer.
26409467b48Spatrick if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
26509467b48Spatrick assert(NumBytes != 0 && "undefined behavior");
26609467b48Spatrick size_t BytesToWrite = Size - (Size % NumBytes);
267097a140dSpatrick flush_tied_then_write(Ptr, BytesToWrite);
26809467b48Spatrick size_t BytesRemaining = Size - BytesToWrite;
26909467b48Spatrick if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
27009467b48Spatrick // Too much left over to copy into our buffer.
27109467b48Spatrick return write(Ptr + BytesToWrite, BytesRemaining);
27209467b48Spatrick }
27309467b48Spatrick copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
27409467b48Spatrick return *this;
27509467b48Spatrick }
27609467b48Spatrick
27709467b48Spatrick // We don't have enough space in the buffer to fit the string in. Insert as
27809467b48Spatrick // much as possible, flush and start over with the remainder.
27909467b48Spatrick copy_to_buffer(Ptr, NumBytes);
28009467b48Spatrick flush_nonempty();
28109467b48Spatrick return write(Ptr + NumBytes, Size - NumBytes);
28209467b48Spatrick }
28309467b48Spatrick
28409467b48Spatrick copy_to_buffer(Ptr, Size);
28509467b48Spatrick
28609467b48Spatrick return *this;
28709467b48Spatrick }
28809467b48Spatrick
copy_to_buffer(const char * Ptr,size_t Size)28909467b48Spatrick void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
29009467b48Spatrick assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!");
29109467b48Spatrick
29209467b48Spatrick // Handle short strings specially, memcpy isn't very good at very short
29309467b48Spatrick // strings.
29409467b48Spatrick switch (Size) {
295*d415bd75Srobert case 4: OutBufCur[3] = Ptr[3]; [[fallthrough]];
296*d415bd75Srobert case 3: OutBufCur[2] = Ptr[2]; [[fallthrough]];
297*d415bd75Srobert case 2: OutBufCur[1] = Ptr[1]; [[fallthrough]];
298*d415bd75Srobert case 1: OutBufCur[0] = Ptr[0]; [[fallthrough]];
29909467b48Spatrick case 0: break;
30009467b48Spatrick default:
30109467b48Spatrick memcpy(OutBufCur, Ptr, Size);
30209467b48Spatrick break;
30309467b48Spatrick }
30409467b48Spatrick
30509467b48Spatrick OutBufCur += Size;
30609467b48Spatrick }
30709467b48Spatrick
flush_tied_then_write(const char * Ptr,size_t Size)308097a140dSpatrick void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) {
309097a140dSpatrick if (TiedStream)
310097a140dSpatrick TiedStream->flush();
311097a140dSpatrick write_impl(Ptr, Size);
312097a140dSpatrick }
313097a140dSpatrick
31409467b48Spatrick // Formatted output.
operator <<(const format_object_base & Fmt)31509467b48Spatrick raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
31609467b48Spatrick // If we have more than a few bytes left in our output buffer, try
31709467b48Spatrick // formatting directly onto its end.
31809467b48Spatrick size_t NextBufferSize = 127;
31909467b48Spatrick size_t BufferBytesLeft = OutBufEnd - OutBufCur;
32009467b48Spatrick if (BufferBytesLeft > 3) {
32109467b48Spatrick size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
32209467b48Spatrick
32309467b48Spatrick // Common case is that we have plenty of space.
32409467b48Spatrick if (BytesUsed <= BufferBytesLeft) {
32509467b48Spatrick OutBufCur += BytesUsed;
32609467b48Spatrick return *this;
32709467b48Spatrick }
32809467b48Spatrick
32909467b48Spatrick // Otherwise, we overflowed and the return value tells us the size to try
33009467b48Spatrick // again with.
33109467b48Spatrick NextBufferSize = BytesUsed;
33209467b48Spatrick }
33309467b48Spatrick
33409467b48Spatrick // If we got here, we didn't have enough space in the output buffer for the
33509467b48Spatrick // string. Try printing into a SmallVector that is resized to have enough
33609467b48Spatrick // space. Iterate until we win.
33709467b48Spatrick SmallVector<char, 128> V;
33809467b48Spatrick
33909467b48Spatrick while (true) {
34009467b48Spatrick V.resize(NextBufferSize);
34109467b48Spatrick
34209467b48Spatrick // Try formatting into the SmallVector.
34309467b48Spatrick size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
34409467b48Spatrick
34509467b48Spatrick // If BytesUsed fit into the vector, we win.
34609467b48Spatrick if (BytesUsed <= NextBufferSize)
34709467b48Spatrick return write(V.data(), BytesUsed);
34809467b48Spatrick
34909467b48Spatrick // Otherwise, try again with a new size.
35009467b48Spatrick assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
35109467b48Spatrick NextBufferSize = BytesUsed;
35209467b48Spatrick }
35309467b48Spatrick }
35409467b48Spatrick
operator <<(const formatv_object_base & Obj)35509467b48Spatrick raw_ostream &raw_ostream::operator<<(const formatv_object_base &Obj) {
35609467b48Spatrick Obj.format(*this);
35709467b48Spatrick return *this;
35809467b48Spatrick }
35909467b48Spatrick
operator <<(const FormattedString & FS)36009467b48Spatrick raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
361097a140dSpatrick unsigned LeftIndent = 0;
362097a140dSpatrick unsigned RightIndent = 0;
363097a140dSpatrick const ssize_t Difference = FS.Width - FS.Str.size();
364097a140dSpatrick if (Difference > 0) {
36509467b48Spatrick switch (FS.Justify) {
366097a140dSpatrick case FormattedString::JustifyNone:
367097a140dSpatrick break;
36809467b48Spatrick case FormattedString::JustifyLeft:
369097a140dSpatrick RightIndent = Difference;
37009467b48Spatrick break;
37109467b48Spatrick case FormattedString::JustifyRight:
372097a140dSpatrick LeftIndent = Difference;
37309467b48Spatrick break;
374097a140dSpatrick case FormattedString::JustifyCenter:
375097a140dSpatrick LeftIndent = Difference / 2;
376097a140dSpatrick RightIndent = Difference - LeftIndent;
37709467b48Spatrick break;
37809467b48Spatrick }
37909467b48Spatrick }
380097a140dSpatrick indent(LeftIndent);
381097a140dSpatrick (*this) << FS.Str;
382097a140dSpatrick indent(RightIndent);
38309467b48Spatrick return *this;
38409467b48Spatrick }
38509467b48Spatrick
operator <<(const FormattedNumber & FN)38609467b48Spatrick raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
38709467b48Spatrick if (FN.Hex) {
38809467b48Spatrick HexPrintStyle Style;
38909467b48Spatrick if (FN.Upper && FN.HexPrefix)
39009467b48Spatrick Style = HexPrintStyle::PrefixUpper;
39109467b48Spatrick else if (FN.Upper && !FN.HexPrefix)
39209467b48Spatrick Style = HexPrintStyle::Upper;
39309467b48Spatrick else if (!FN.Upper && FN.HexPrefix)
39409467b48Spatrick Style = HexPrintStyle::PrefixLower;
39509467b48Spatrick else
39609467b48Spatrick Style = HexPrintStyle::Lower;
39709467b48Spatrick llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
39809467b48Spatrick } else {
39909467b48Spatrick llvm::SmallString<16> Buffer;
40009467b48Spatrick llvm::raw_svector_ostream Stream(Buffer);
40109467b48Spatrick llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
40209467b48Spatrick if (Buffer.size() < FN.Width)
40309467b48Spatrick indent(FN.Width - Buffer.size());
40409467b48Spatrick (*this) << Buffer;
40509467b48Spatrick }
40609467b48Spatrick return *this;
40709467b48Spatrick }
40809467b48Spatrick
operator <<(const FormattedBytes & FB)40909467b48Spatrick raw_ostream &raw_ostream::operator<<(const FormattedBytes &FB) {
41009467b48Spatrick if (FB.Bytes.empty())
41109467b48Spatrick return *this;
41209467b48Spatrick
41309467b48Spatrick size_t LineIndex = 0;
41409467b48Spatrick auto Bytes = FB.Bytes;
41509467b48Spatrick const size_t Size = Bytes.size();
41609467b48Spatrick HexPrintStyle HPS = FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower;
41709467b48Spatrick uint64_t OffsetWidth = 0;
418*d415bd75Srobert if (FB.FirstByteOffset) {
41909467b48Spatrick // Figure out how many nibbles are needed to print the largest offset
42009467b48Spatrick // represented by this data set, so that we can align the offset field
42109467b48Spatrick // to the right width.
42209467b48Spatrick size_t Lines = Size / FB.NumPerLine;
42309467b48Spatrick uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
42409467b48Spatrick unsigned Power = 0;
42509467b48Spatrick if (MaxOffset > 0)
42609467b48Spatrick Power = llvm::Log2_64_Ceil(MaxOffset);
42709467b48Spatrick OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
42809467b48Spatrick }
42909467b48Spatrick
43009467b48Spatrick // The width of a block of data including all spaces for group separators.
43109467b48Spatrick unsigned NumByteGroups =
43209467b48Spatrick alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
43309467b48Spatrick unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
43409467b48Spatrick
43509467b48Spatrick while (!Bytes.empty()) {
43609467b48Spatrick indent(FB.IndentLevel);
43709467b48Spatrick
438*d415bd75Srobert if (FB.FirstByteOffset) {
439*d415bd75Srobert uint64_t Offset = *FB.FirstByteOffset;
44009467b48Spatrick llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
44109467b48Spatrick *this << ": ";
44209467b48Spatrick }
44309467b48Spatrick
44409467b48Spatrick auto Line = Bytes.take_front(FB.NumPerLine);
44509467b48Spatrick
44609467b48Spatrick size_t CharsPrinted = 0;
44709467b48Spatrick // Print the hex bytes for this line in groups
44809467b48Spatrick for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
44909467b48Spatrick if (I && (I % FB.ByteGroupSize) == 0) {
45009467b48Spatrick ++CharsPrinted;
45109467b48Spatrick *this << " ";
45209467b48Spatrick }
45309467b48Spatrick llvm::write_hex(*this, Line[I], HPS, 2);
45409467b48Spatrick }
45509467b48Spatrick
45609467b48Spatrick if (FB.ASCII) {
45709467b48Spatrick // Print any spaces needed for any bytes that we didn't print on this
45809467b48Spatrick // line so that the ASCII bytes are correctly aligned.
45909467b48Spatrick assert(BlockCharWidth >= CharsPrinted);
46009467b48Spatrick indent(BlockCharWidth - CharsPrinted + 2);
46109467b48Spatrick *this << "|";
46209467b48Spatrick
46309467b48Spatrick // Print the ASCII char values for each byte on this line
46409467b48Spatrick for (uint8_t Byte : Line) {
46509467b48Spatrick if (isPrint(Byte))
46609467b48Spatrick *this << static_cast<char>(Byte);
46709467b48Spatrick else
46809467b48Spatrick *this << '.';
46909467b48Spatrick }
47009467b48Spatrick *this << '|';
47109467b48Spatrick }
47209467b48Spatrick
47309467b48Spatrick Bytes = Bytes.drop_front(Line.size());
47409467b48Spatrick LineIndex += Line.size();
47509467b48Spatrick if (LineIndex < Size)
47609467b48Spatrick *this << '\n';
47709467b48Spatrick }
47809467b48Spatrick return *this;
47909467b48Spatrick }
48009467b48Spatrick
48109467b48Spatrick template <char C>
write_padding(raw_ostream & OS,unsigned NumChars)48209467b48Spatrick static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
48309467b48Spatrick static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
48409467b48Spatrick C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
48509467b48Spatrick C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
48609467b48Spatrick C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
48709467b48Spatrick C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C};
48809467b48Spatrick
48909467b48Spatrick // Usually the indentation is small, handle it with a fastpath.
490*d415bd75Srobert if (NumChars < std::size(Chars))
49109467b48Spatrick return OS.write(Chars, NumChars);
49209467b48Spatrick
49309467b48Spatrick while (NumChars) {
494*d415bd75Srobert unsigned NumToWrite = std::min(NumChars, (unsigned)std::size(Chars) - 1);
49509467b48Spatrick OS.write(Chars, NumToWrite);
49609467b48Spatrick NumChars -= NumToWrite;
49709467b48Spatrick }
49809467b48Spatrick return OS;
49909467b48Spatrick }
50009467b48Spatrick
50109467b48Spatrick /// indent - Insert 'NumSpaces' spaces.
indent(unsigned NumSpaces)50209467b48Spatrick raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
50309467b48Spatrick return write_padding<' '>(*this, NumSpaces);
50409467b48Spatrick }
50509467b48Spatrick
50609467b48Spatrick /// write_zeros - Insert 'NumZeros' nulls.
write_zeros(unsigned NumZeros)50709467b48Spatrick raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
50809467b48Spatrick return write_padding<'\0'>(*this, NumZeros);
50909467b48Spatrick }
51009467b48Spatrick
prepare_colors()511097a140dSpatrick bool raw_ostream::prepare_colors() {
512097a140dSpatrick // Colors were explicitly disabled.
513097a140dSpatrick if (!ColorEnabled)
514097a140dSpatrick return false;
515097a140dSpatrick
516097a140dSpatrick // Colors require changing the terminal but this stream is not going to a
517097a140dSpatrick // terminal.
518097a140dSpatrick if (sys::Process::ColorNeedsFlush() && !is_displayed())
519097a140dSpatrick return false;
520097a140dSpatrick
521097a140dSpatrick if (sys::Process::ColorNeedsFlush())
522097a140dSpatrick flush();
523097a140dSpatrick
524097a140dSpatrick return true;
525097a140dSpatrick }
526097a140dSpatrick
changeColor(enum Colors colors,bool bold,bool bg)527097a140dSpatrick raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
528097a140dSpatrick if (!prepare_colors())
529097a140dSpatrick return *this;
530097a140dSpatrick
531097a140dSpatrick const char *colorcode =
532097a140dSpatrick (colors == SAVEDCOLOR)
533097a140dSpatrick ? sys::Process::OutputBold(bg)
534097a140dSpatrick : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
535097a140dSpatrick if (colorcode)
536097a140dSpatrick write(colorcode, strlen(colorcode));
537097a140dSpatrick return *this;
538097a140dSpatrick }
539097a140dSpatrick
resetColor()540097a140dSpatrick raw_ostream &raw_ostream::resetColor() {
541097a140dSpatrick if (!prepare_colors())
542097a140dSpatrick return *this;
543097a140dSpatrick
544097a140dSpatrick if (const char *colorcode = sys::Process::ResetColor())
545097a140dSpatrick write(colorcode, strlen(colorcode));
546097a140dSpatrick return *this;
547097a140dSpatrick }
548097a140dSpatrick
reverseColor()549097a140dSpatrick raw_ostream &raw_ostream::reverseColor() {
550097a140dSpatrick if (!prepare_colors())
551097a140dSpatrick return *this;
552097a140dSpatrick
553097a140dSpatrick if (const char *colorcode = sys::Process::OutputReverse())
554097a140dSpatrick write(colorcode, strlen(colorcode));
555097a140dSpatrick return *this;
556097a140dSpatrick }
557097a140dSpatrick
anchor()55809467b48Spatrick void raw_ostream::anchor() {}
55909467b48Spatrick
56009467b48Spatrick //===----------------------------------------------------------------------===//
56109467b48Spatrick // Formatted Output
56209467b48Spatrick //===----------------------------------------------------------------------===//
56309467b48Spatrick
56409467b48Spatrick // Out of line virtual method.
home()56509467b48Spatrick void format_object_base::home() {
56609467b48Spatrick }
56709467b48Spatrick
56809467b48Spatrick //===----------------------------------------------------------------------===//
56909467b48Spatrick // raw_fd_ostream
57009467b48Spatrick //===----------------------------------------------------------------------===//
57109467b48Spatrick
getFD(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)57209467b48Spatrick static int getFD(StringRef Filename, std::error_code &EC,
57309467b48Spatrick sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
57409467b48Spatrick sys::fs::OpenFlags Flags) {
57509467b48Spatrick assert((Access & sys::fs::FA_Write) &&
57609467b48Spatrick "Cannot make a raw_ostream from a read-only descriptor!");
57709467b48Spatrick
57809467b48Spatrick // Handle "-" as stdout. Note that when we do this, we consider ourself
57909467b48Spatrick // the owner of stdout and may set the "binary" flag globally based on Flags.
58009467b48Spatrick if (Filename == "-") {
58109467b48Spatrick EC = std::error_code();
58273471bf0Spatrick // Change stdout's text/binary mode based on the Flags.
58373471bf0Spatrick sys::ChangeStdoutMode(Flags);
58409467b48Spatrick return STDOUT_FILENO;
58509467b48Spatrick }
58609467b48Spatrick
58709467b48Spatrick int FD;
58809467b48Spatrick if (Access & sys::fs::FA_Read)
58909467b48Spatrick EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
59009467b48Spatrick else
59109467b48Spatrick EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
59209467b48Spatrick if (EC)
59309467b48Spatrick return -1;
59409467b48Spatrick
59509467b48Spatrick return FD;
59609467b48Spatrick }
59709467b48Spatrick
raw_fd_ostream(StringRef Filename,std::error_code & EC)59809467b48Spatrick raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
59909467b48Spatrick : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
60009467b48Spatrick sys::fs::OF_None) {}
60109467b48Spatrick
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp)60209467b48Spatrick raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
60309467b48Spatrick sys::fs::CreationDisposition Disp)
60409467b48Spatrick : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
60509467b48Spatrick
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::FileAccess Access)60609467b48Spatrick raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
60709467b48Spatrick sys::fs::FileAccess Access)
60809467b48Spatrick : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
60909467b48Spatrick sys::fs::OF_None) {}
61009467b48Spatrick
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::OpenFlags Flags)61109467b48Spatrick raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
61209467b48Spatrick sys::fs::OpenFlags Flags)
61309467b48Spatrick : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
61409467b48Spatrick Flags) {}
61509467b48Spatrick
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)61609467b48Spatrick raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
61709467b48Spatrick sys::fs::CreationDisposition Disp,
61809467b48Spatrick sys::fs::FileAccess Access,
61909467b48Spatrick sys::fs::OpenFlags Flags)
62009467b48Spatrick : raw_fd_ostream(getFD(Filename, EC, Disp, Access, Flags), true) {}
62109467b48Spatrick
62209467b48Spatrick /// FD is the file descriptor that this writes to. If ShouldClose is true, this
62309467b48Spatrick /// closes the file when the stream is destroyed.
raw_fd_ostream(int fd,bool shouldClose,bool unbuffered,OStreamKind K)62473471bf0Spatrick raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
62573471bf0Spatrick OStreamKind K)
62673471bf0Spatrick : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
62709467b48Spatrick if (FD < 0 ) {
62809467b48Spatrick ShouldClose = false;
62909467b48Spatrick return;
63009467b48Spatrick }
63109467b48Spatrick
632097a140dSpatrick enable_colors(true);
633097a140dSpatrick
63409467b48Spatrick // Do not attempt to close stdout or stderr. We used to try to maintain the
63509467b48Spatrick // property that tools that support writing file to stdout should not also
63609467b48Spatrick // write informational output to stdout, but in practice we were never able to
63709467b48Spatrick // maintain this invariant. Many features have been added to LLVM and clang
63809467b48Spatrick // (-fdump-record-layouts, optimization remarks, etc) that print to stdout, so
63909467b48Spatrick // users must simply be aware that mixed output and remarks is a possibility.
64009467b48Spatrick if (FD <= STDERR_FILENO)
64109467b48Spatrick ShouldClose = false;
64209467b48Spatrick
64309467b48Spatrick #ifdef _WIN32
64409467b48Spatrick // Check if this is a console device. This is not equivalent to isatty.
64509467b48Spatrick IsWindowsConsole =
64609467b48Spatrick ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
64709467b48Spatrick #endif
64809467b48Spatrick
64909467b48Spatrick // Get the starting position.
65009467b48Spatrick off_t loc = ::lseek(FD, 0, SEEK_CUR);
65109467b48Spatrick sys::fs::file_status Status;
65209467b48Spatrick std::error_code EC = status(FD, Status);
653*d415bd75Srobert IsRegularFile = Status.type() == sys::fs::file_type::regular_file;
654*d415bd75Srobert #ifdef _WIN32
655*d415bd75Srobert // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
656*d415bd75Srobert SupportsSeeking = !EC && IsRegularFile;
65709467b48Spatrick #else
658*d415bd75Srobert SupportsSeeking = !EC && loc != (off_t)-1;
65909467b48Spatrick #endif
66009467b48Spatrick if (!SupportsSeeking)
66109467b48Spatrick pos = 0;
66209467b48Spatrick else
66309467b48Spatrick pos = static_cast<uint64_t>(loc);
66409467b48Spatrick }
66509467b48Spatrick
~raw_fd_ostream()66609467b48Spatrick raw_fd_ostream::~raw_fd_ostream() {
66709467b48Spatrick if (FD >= 0) {
66809467b48Spatrick flush();
66909467b48Spatrick if (ShouldClose) {
67009467b48Spatrick if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
67109467b48Spatrick error_detected(EC);
67209467b48Spatrick }
67309467b48Spatrick }
67409467b48Spatrick
67509467b48Spatrick #ifdef __MINGW32__
67609467b48Spatrick // On mingw, global dtors should not call exit().
67709467b48Spatrick // report_fatal_error() invokes exit(). We know report_fatal_error()
67809467b48Spatrick // might not write messages to stderr when any errors were detected
67909467b48Spatrick // on FD == 2.
68009467b48Spatrick if (FD == 2) return;
68109467b48Spatrick #endif
68209467b48Spatrick
68309467b48Spatrick // If there are any pending errors, report them now. Clients wishing
68409467b48Spatrick // to avoid report_fatal_error calls should check for errors with
68509467b48Spatrick // has_error() and clear the error flag with clear_error() before
68609467b48Spatrick // destructing raw_ostream objects which may have errors.
68709467b48Spatrick if (has_error())
688*d415bd75Srobert report_fatal_error(Twine("IO failure on output stream: ") +
689*d415bd75Srobert error().message(),
69009467b48Spatrick /*gen_crash_diag=*/false);
69109467b48Spatrick }
69209467b48Spatrick
69309467b48Spatrick #if defined(_WIN32)
69409467b48Spatrick // The most reliable way to print unicode in a Windows console is with
69509467b48Spatrick // WriteConsoleW. To use that, first transcode from UTF-8 to UTF-16. This
69609467b48Spatrick // assumes that LLVM programs always print valid UTF-8 to the console. The data
69709467b48Spatrick // might not be UTF-8 for two major reasons:
69809467b48Spatrick // 1. The program is printing binary (-filetype=obj -o -), in which case it
69909467b48Spatrick // would have been gibberish anyway.
70009467b48Spatrick // 2. The program is printing text in a semi-ascii compatible codepage like
70109467b48Spatrick // shift-jis or cp1252.
70209467b48Spatrick //
70309467b48Spatrick // Most LLVM programs don't produce non-ascii text unless they are quoting
70409467b48Spatrick // user source input. A well-behaved LLVM program should either validate that
70509467b48Spatrick // the input is UTF-8 or transcode from the local codepage to UTF-8 before
70609467b48Spatrick // quoting it. If they don't, this may mess up the encoding, but this is still
70709467b48Spatrick // probably the best compromise we can make.
write_console_impl(int FD,StringRef Data)70809467b48Spatrick static bool write_console_impl(int FD, StringRef Data) {
70909467b48Spatrick SmallVector<wchar_t, 256> WideText;
71009467b48Spatrick
71109467b48Spatrick // Fall back to ::write if it wasn't valid UTF-8.
71209467b48Spatrick if (auto EC = sys::windows::UTF8ToUTF16(Data, WideText))
71309467b48Spatrick return false;
71409467b48Spatrick
71509467b48Spatrick // On Windows 7 and earlier, WriteConsoleW has a low maximum amount of data
71609467b48Spatrick // that can be written to the console at a time.
71709467b48Spatrick size_t MaxWriteSize = WideText.size();
71809467b48Spatrick if (!RunningWindows8OrGreater())
71909467b48Spatrick MaxWriteSize = 32767;
72009467b48Spatrick
72109467b48Spatrick size_t WCharsWritten = 0;
72209467b48Spatrick do {
72309467b48Spatrick size_t WCharsToWrite =
72409467b48Spatrick std::min(MaxWriteSize, WideText.size() - WCharsWritten);
72509467b48Spatrick DWORD ActuallyWritten;
72609467b48Spatrick bool Success =
72709467b48Spatrick ::WriteConsoleW((HANDLE)::_get_osfhandle(FD), &WideText[WCharsWritten],
72809467b48Spatrick WCharsToWrite, &ActuallyWritten,
72909467b48Spatrick /*Reserved=*/nullptr);
73009467b48Spatrick
73109467b48Spatrick // The most likely reason for WriteConsoleW to fail is that FD no longer
73209467b48Spatrick // points to a console. Fall back to ::write. If this isn't the first loop
73309467b48Spatrick // iteration, something is truly wrong.
73409467b48Spatrick if (!Success)
73509467b48Spatrick return false;
73609467b48Spatrick
73709467b48Spatrick WCharsWritten += ActuallyWritten;
73809467b48Spatrick } while (WCharsWritten != WideText.size());
73909467b48Spatrick return true;
74009467b48Spatrick }
74109467b48Spatrick #endif
74209467b48Spatrick
write_impl(const char * Ptr,size_t Size)74309467b48Spatrick void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
74409467b48Spatrick assert(FD >= 0 && "File already closed.");
74509467b48Spatrick pos += Size;
74609467b48Spatrick
74709467b48Spatrick #if defined(_WIN32)
74809467b48Spatrick // If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
74909467b48Spatrick // and using WriteConsoleW. If that fails, fall back to plain write().
75009467b48Spatrick if (IsWindowsConsole)
75109467b48Spatrick if (write_console_impl(FD, StringRef(Ptr, Size)))
75209467b48Spatrick return;
75309467b48Spatrick #endif
75409467b48Spatrick
75509467b48Spatrick // The maximum write size is limited to INT32_MAX. A write
75609467b48Spatrick // greater than SSIZE_MAX is implementation-defined in POSIX,
75709467b48Spatrick // and Windows _write requires 32 bit input.
75809467b48Spatrick size_t MaxWriteSize = INT32_MAX;
75909467b48Spatrick
76009467b48Spatrick #if defined(__linux__)
76109467b48Spatrick // It is observed that Linux returns EINVAL for a very large write (>2G).
76209467b48Spatrick // Make it a reasonably small value.
76309467b48Spatrick MaxWriteSize = 1024 * 1024 * 1024;
76409467b48Spatrick #endif
76509467b48Spatrick
76609467b48Spatrick do {
76709467b48Spatrick size_t ChunkSize = std::min(Size, MaxWriteSize);
76809467b48Spatrick ssize_t ret = ::write(FD, Ptr, ChunkSize);
76909467b48Spatrick
77009467b48Spatrick if (ret < 0) {
77109467b48Spatrick // If it's a recoverable error, swallow it and retry the write.
77209467b48Spatrick //
77309467b48Spatrick // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
77409467b48Spatrick // raw_ostream isn't designed to do non-blocking I/O. However, some
77509467b48Spatrick // programs, such as old versions of bjam, have mistakenly used
77609467b48Spatrick // O_NONBLOCK. For compatibility, emulate blocking semantics by
77709467b48Spatrick // spinning until the write succeeds. If you don't want spinning,
77809467b48Spatrick // don't use O_NONBLOCK file descriptors with raw_ostream.
77909467b48Spatrick if (errno == EINTR || errno == EAGAIN
78009467b48Spatrick #ifdef EWOULDBLOCK
78109467b48Spatrick || errno == EWOULDBLOCK
78209467b48Spatrick #endif
78309467b48Spatrick )
78409467b48Spatrick continue;
78509467b48Spatrick
786*d415bd75Srobert #ifdef _WIN32
787*d415bd75Srobert // Windows equivalents of SIGPIPE/EPIPE.
788*d415bd75Srobert DWORD WinLastError = GetLastError();
789*d415bd75Srobert if (WinLastError == ERROR_BROKEN_PIPE ||
790*d415bd75Srobert (WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
791*d415bd75Srobert llvm::sys::CallOneShotPipeSignalHandler();
792*d415bd75Srobert errno = EPIPE;
793*d415bd75Srobert }
794*d415bd75Srobert #endif
79509467b48Spatrick // Otherwise it's a non-recoverable error. Note it and quit.
79609467b48Spatrick error_detected(std::error_code(errno, std::generic_category()));
79709467b48Spatrick break;
79809467b48Spatrick }
79909467b48Spatrick
80009467b48Spatrick // The write may have written some or all of the data. Update the
80109467b48Spatrick // size and buffer pointer to reflect the remainder that needs
80209467b48Spatrick // to be written. If there are no bytes left, we're done.
80309467b48Spatrick Ptr += ret;
80409467b48Spatrick Size -= ret;
80509467b48Spatrick } while (Size > 0);
80609467b48Spatrick }
80709467b48Spatrick
close()80809467b48Spatrick void raw_fd_ostream::close() {
80909467b48Spatrick assert(ShouldClose);
81009467b48Spatrick ShouldClose = false;
81109467b48Spatrick flush();
81209467b48Spatrick if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
81309467b48Spatrick error_detected(EC);
81409467b48Spatrick FD = -1;
81509467b48Spatrick }
81609467b48Spatrick
seek(uint64_t off)81709467b48Spatrick uint64_t raw_fd_ostream::seek(uint64_t off) {
81809467b48Spatrick assert(SupportsSeeking && "Stream does not support seeking!");
81909467b48Spatrick flush();
82009467b48Spatrick #ifdef _WIN32
82109467b48Spatrick pos = ::_lseeki64(FD, off, SEEK_SET);
82209467b48Spatrick #else
82309467b48Spatrick pos = ::lseek(FD, off, SEEK_SET);
82409467b48Spatrick #endif
82509467b48Spatrick if (pos == (uint64_t)-1)
82609467b48Spatrick error_detected(std::error_code(errno, std::generic_category()));
82709467b48Spatrick return pos;
82809467b48Spatrick }
82909467b48Spatrick
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)83009467b48Spatrick void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size,
83109467b48Spatrick uint64_t Offset) {
83209467b48Spatrick uint64_t Pos = tell();
83309467b48Spatrick seek(Offset);
83409467b48Spatrick write(Ptr, Size);
83509467b48Spatrick seek(Pos);
83609467b48Spatrick }
83709467b48Spatrick
preferred_buffer_size() const83809467b48Spatrick size_t raw_fd_ostream::preferred_buffer_size() const {
83909467b48Spatrick #if defined(_WIN32)
84009467b48Spatrick // Disable buffering for console devices. Console output is re-encoded from
84109467b48Spatrick // UTF-8 to UTF-16 on Windows, and buffering it would require us to split the
84209467b48Spatrick // buffer on a valid UTF-8 codepoint boundary. Terminal buffering is disabled
84309467b48Spatrick // below on most other OSs, so do the same thing on Windows and avoid that
84409467b48Spatrick // complexity.
84509467b48Spatrick if (IsWindowsConsole)
84609467b48Spatrick return 0;
84709467b48Spatrick return raw_ostream::preferred_buffer_size();
84809467b48Spatrick #elif !defined(__minix)
84909467b48Spatrick // Minix has no st_blksize.
85009467b48Spatrick assert(FD >= 0 && "File not yet open!");
85109467b48Spatrick struct stat statbuf;
85209467b48Spatrick if (fstat(FD, &statbuf) != 0)
85309467b48Spatrick return 0;
85409467b48Spatrick
85509467b48Spatrick // If this is a terminal, don't use buffering. Line buffering
85609467b48Spatrick // would be a more traditional thing to do, but it's not worth
85709467b48Spatrick // the complexity.
858097a140dSpatrick if (S_ISCHR(statbuf.st_mode) && is_displayed())
85909467b48Spatrick return 0;
86009467b48Spatrick // Return the preferred block size.
86109467b48Spatrick return statbuf.st_blksize;
86209467b48Spatrick #else
86309467b48Spatrick return raw_ostream::preferred_buffer_size();
86409467b48Spatrick #endif
86509467b48Spatrick }
86609467b48Spatrick
is_displayed() const86709467b48Spatrick bool raw_fd_ostream::is_displayed() const {
86809467b48Spatrick return sys::Process::FileDescriptorIsDisplayed(FD);
86909467b48Spatrick }
87009467b48Spatrick
has_colors() const87109467b48Spatrick bool raw_fd_ostream::has_colors() const {
87273471bf0Spatrick if (!HasColors)
87373471bf0Spatrick HasColors = sys::Process::FileDescriptorHasColors(FD);
87473471bf0Spatrick return *HasColors;
87573471bf0Spatrick }
87673471bf0Spatrick
lock()87773471bf0Spatrick Expected<sys::fs::FileLocker> raw_fd_ostream::lock() {
87873471bf0Spatrick std::error_code EC = sys::fs::lockFile(FD);
87973471bf0Spatrick if (!EC)
88073471bf0Spatrick return sys::fs::FileLocker(FD);
88173471bf0Spatrick return errorCodeToError(EC);
88273471bf0Spatrick }
88373471bf0Spatrick
88473471bf0Spatrick Expected<sys::fs::FileLocker>
tryLockFor(Duration const & Timeout)885*d415bd75Srobert raw_fd_ostream::tryLockFor(Duration const& Timeout) {
886*d415bd75Srobert std::error_code EC = sys::fs::tryLockFile(FD, Timeout.getDuration());
88773471bf0Spatrick if (!EC)
88873471bf0Spatrick return sys::fs::FileLocker(FD);
88973471bf0Spatrick return errorCodeToError(EC);
89009467b48Spatrick }
89109467b48Spatrick
anchor()89209467b48Spatrick void raw_fd_ostream::anchor() {}
89309467b48Spatrick
89409467b48Spatrick //===----------------------------------------------------------------------===//
89509467b48Spatrick // outs(), errs(), nulls()
89609467b48Spatrick //===----------------------------------------------------------------------===//
89709467b48Spatrick
outs()898097a140dSpatrick raw_fd_ostream &llvm::outs() {
89909467b48Spatrick // Set buffer settings to model stdout behavior.
90009467b48Spatrick std::error_code EC;
90109467b48Spatrick static raw_fd_ostream S("-", EC, sys::fs::OF_None);
90209467b48Spatrick assert(!EC);
90309467b48Spatrick return S;
90409467b48Spatrick }
90509467b48Spatrick
errs()906097a140dSpatrick raw_fd_ostream &llvm::errs() {
907097a140dSpatrick // Set standard error to be unbuffered and tied to outs() by default.
90809467b48Spatrick static raw_fd_ostream S(STDERR_FILENO, false, true);
90909467b48Spatrick return S;
91009467b48Spatrick }
91109467b48Spatrick
91209467b48Spatrick /// nulls() - This returns a reference to a raw_ostream which discards output.
nulls()91309467b48Spatrick raw_ostream &llvm::nulls() {
91409467b48Spatrick static raw_null_ostream S;
91509467b48Spatrick return S;
91609467b48Spatrick }
91709467b48Spatrick
91809467b48Spatrick //===----------------------------------------------------------------------===//
91973471bf0Spatrick // File Streams
92073471bf0Spatrick //===----------------------------------------------------------------------===//
92173471bf0Spatrick
raw_fd_stream(StringRef Filename,std::error_code & EC)92273471bf0Spatrick raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
92373471bf0Spatrick : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
92473471bf0Spatrick sys::fs::FA_Write | sys::fs::FA_Read,
92573471bf0Spatrick sys::fs::OF_None),
92673471bf0Spatrick true, false, OStreamKind::OK_FDStream) {
92773471bf0Spatrick if (EC)
92873471bf0Spatrick return;
92973471bf0Spatrick
930*d415bd75Srobert if (!isRegularFile())
93173471bf0Spatrick EC = std::make_error_code(std::errc::invalid_argument);
93273471bf0Spatrick }
93373471bf0Spatrick
read(char * Ptr,size_t Size)93473471bf0Spatrick ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
93573471bf0Spatrick assert(get_fd() >= 0 && "File already closed.");
93673471bf0Spatrick ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
93773471bf0Spatrick if (Ret >= 0)
93873471bf0Spatrick inc_pos(Ret);
93973471bf0Spatrick else
94073471bf0Spatrick error_detected(std::error_code(errno, std::generic_category()));
94173471bf0Spatrick return Ret;
94273471bf0Spatrick }
94373471bf0Spatrick
classof(const raw_ostream * OS)94473471bf0Spatrick bool raw_fd_stream::classof(const raw_ostream *OS) {
94573471bf0Spatrick return OS->get_kind() == OStreamKind::OK_FDStream;
94673471bf0Spatrick }
94773471bf0Spatrick
94873471bf0Spatrick //===----------------------------------------------------------------------===//
94909467b48Spatrick // raw_string_ostream
95009467b48Spatrick //===----------------------------------------------------------------------===//
95109467b48Spatrick
write_impl(const char * Ptr,size_t Size)95209467b48Spatrick void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
95309467b48Spatrick OS.append(Ptr, Size);
95409467b48Spatrick }
95509467b48Spatrick
95609467b48Spatrick //===----------------------------------------------------------------------===//
95709467b48Spatrick // raw_svector_ostream
95809467b48Spatrick //===----------------------------------------------------------------------===//
95909467b48Spatrick
current_pos() const96009467b48Spatrick uint64_t raw_svector_ostream::current_pos() const { return OS.size(); }
96109467b48Spatrick
write_impl(const char * Ptr,size_t Size)96209467b48Spatrick void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
96309467b48Spatrick OS.append(Ptr, Ptr + Size);
96409467b48Spatrick }
96509467b48Spatrick
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)96609467b48Spatrick void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
96709467b48Spatrick uint64_t Offset) {
96809467b48Spatrick memcpy(OS.data() + Offset, Ptr, Size);
96909467b48Spatrick }
97009467b48Spatrick
97109467b48Spatrick //===----------------------------------------------------------------------===//
97209467b48Spatrick // raw_null_ostream
97309467b48Spatrick //===----------------------------------------------------------------------===//
97409467b48Spatrick
~raw_null_ostream()97509467b48Spatrick raw_null_ostream::~raw_null_ostream() {
97609467b48Spatrick #ifndef NDEBUG
97709467b48Spatrick // ~raw_ostream asserts that the buffer is empty. This isn't necessary
97809467b48Spatrick // with raw_null_ostream, but it's better to have raw_null_ostream follow
97909467b48Spatrick // the rules than to change the rules just for raw_null_ostream.
98009467b48Spatrick flush();
98109467b48Spatrick #endif
98209467b48Spatrick }
98309467b48Spatrick
write_impl(const char * Ptr,size_t Size)98409467b48Spatrick void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
98509467b48Spatrick }
98609467b48Spatrick
current_pos() const98709467b48Spatrick uint64_t raw_null_ostream::current_pos() const {
98809467b48Spatrick return 0;
98909467b48Spatrick }
99009467b48Spatrick
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)99109467b48Spatrick void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
99209467b48Spatrick uint64_t Offset) {}
99309467b48Spatrick
anchor()99409467b48Spatrick void raw_pwrite_stream::anchor() {}
99509467b48Spatrick
anchor()99609467b48Spatrick void buffer_ostream::anchor() {}
99773471bf0Spatrick
anchor()99873471bf0Spatrick void buffer_unique_ostream::anchor() {}
99973471bf0Spatrick
writeToOutput(StringRef OutputFileName,std::function<Error (raw_ostream &)> Write)100073471bf0Spatrick Error llvm::writeToOutput(StringRef OutputFileName,
100173471bf0Spatrick std::function<Error(raw_ostream &)> Write) {
100273471bf0Spatrick if (OutputFileName == "-")
100373471bf0Spatrick return Write(outs());
100473471bf0Spatrick
100573471bf0Spatrick if (OutputFileName == "/dev/null") {
100673471bf0Spatrick raw_null_ostream Out;
100773471bf0Spatrick return Write(Out);
100873471bf0Spatrick }
100973471bf0Spatrick
101073471bf0Spatrick unsigned Mode = sys::fs::all_read | sys::fs::all_write | sys::fs::all_exe;
101173471bf0Spatrick Expected<sys::fs::TempFile> Temp =
101273471bf0Spatrick sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode);
101373471bf0Spatrick if (!Temp)
101473471bf0Spatrick return createFileError(OutputFileName, Temp.takeError());
101573471bf0Spatrick
101673471bf0Spatrick raw_fd_ostream Out(Temp->FD, false);
101773471bf0Spatrick
101873471bf0Spatrick if (Error E = Write(Out)) {
101973471bf0Spatrick if (Error DiscardError = Temp->discard())
102073471bf0Spatrick return joinErrors(std::move(E), std::move(DiscardError));
102173471bf0Spatrick return E;
102273471bf0Spatrick }
102373471bf0Spatrick Out.flush();
102473471bf0Spatrick
102573471bf0Spatrick return Temp->keep(OutputFileName);
102673471bf0Spatrick }
1027