106f32e7eSjoerg //===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This implements support for bulk buffered stream output.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg
1306f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
1406f32e7eSjoerg #include "llvm/ADT/STLExtras.h"
1506f32e7eSjoerg #include "llvm/ADT/StringExtras.h"
1606f32e7eSjoerg #include "llvm/Config/config.h"
1706f32e7eSjoerg #include "llvm/Support/Compiler.h"
1806f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
1906f32e7eSjoerg #include "llvm/Support/FileSystem.h"
2006f32e7eSjoerg #include "llvm/Support/Format.h"
2106f32e7eSjoerg #include "llvm/Support/FormatVariadic.h"
2206f32e7eSjoerg #include "llvm/Support/MathExtras.h"
2306f32e7eSjoerg #include "llvm/Support/NativeFormatting.h"
2406f32e7eSjoerg #include "llvm/Support/Process.h"
2506f32e7eSjoerg #include "llvm/Support/Program.h"
2606f32e7eSjoerg #include <algorithm>
2706f32e7eSjoerg #include <cctype>
2806f32e7eSjoerg #include <cerrno>
2906f32e7eSjoerg #include <cstdio>
3006f32e7eSjoerg #include <iterator>
3106f32e7eSjoerg #include <sys/stat.h>
3206f32e7eSjoerg
3306f32e7eSjoerg // <fcntl.h> may provide O_BINARY.
3406f32e7eSjoerg #if defined(HAVE_FCNTL_H)
3506f32e7eSjoerg # include <fcntl.h>
3606f32e7eSjoerg #endif
3706f32e7eSjoerg
3806f32e7eSjoerg #if defined(HAVE_UNISTD_H)
3906f32e7eSjoerg # include <unistd.h>
4006f32e7eSjoerg #endif
4106f32e7eSjoerg
4206f32e7eSjoerg #if defined(__CYGWIN__)
4306f32e7eSjoerg #include <io.h>
4406f32e7eSjoerg #endif
4506f32e7eSjoerg
4606f32e7eSjoerg #if defined(_MSC_VER)
4706f32e7eSjoerg #include <io.h>
4806f32e7eSjoerg #ifndef STDIN_FILENO
4906f32e7eSjoerg # define STDIN_FILENO 0
5006f32e7eSjoerg #endif
5106f32e7eSjoerg #ifndef STDOUT_FILENO
5206f32e7eSjoerg # define STDOUT_FILENO 1
5306f32e7eSjoerg #endif
5406f32e7eSjoerg #ifndef STDERR_FILENO
5506f32e7eSjoerg # define STDERR_FILENO 2
5606f32e7eSjoerg #endif
5706f32e7eSjoerg #endif
5806f32e7eSjoerg
5906f32e7eSjoerg #ifdef _WIN32
6006f32e7eSjoerg #include "llvm/Support/ConvertUTF.h"
61*da58b97aSjoerg #include "llvm/Support/Windows/WindowsSupport.h"
6206f32e7eSjoerg #endif
6306f32e7eSjoerg
6406f32e7eSjoerg using namespace llvm;
6506f32e7eSjoerg
66*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::BLACK;
67*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::RED;
68*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::GREEN;
69*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::YELLOW;
70*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::BLUE;
71*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::MAGENTA;
72*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::CYAN;
73*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::WHITE;
74*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
75*da58b97aSjoerg constexpr raw_ostream::Colors raw_ostream::RESET;
7606f32e7eSjoerg
~raw_ostream()7706f32e7eSjoerg raw_ostream::~raw_ostream() {
7806f32e7eSjoerg // raw_ostream's subclasses should take care to flush the buffer
7906f32e7eSjoerg // in their destructors.
8006f32e7eSjoerg assert(OutBufCur == OutBufStart &&
8106f32e7eSjoerg "raw_ostream destructor called with non-empty buffer!");
8206f32e7eSjoerg
83*da58b97aSjoerg if (BufferMode == BufferKind::InternalBuffer)
8406f32e7eSjoerg delete [] OutBufStart;
8506f32e7eSjoerg }
8606f32e7eSjoerg
preferred_buffer_size() const8706f32e7eSjoerg size_t raw_ostream::preferred_buffer_size() const {
8806f32e7eSjoerg // BUFSIZ is intended to be a reasonable default.
8906f32e7eSjoerg return BUFSIZ;
9006f32e7eSjoerg }
9106f32e7eSjoerg
SetBuffered()9206f32e7eSjoerg void raw_ostream::SetBuffered() {
9306f32e7eSjoerg // Ask the subclass to determine an appropriate buffer size.
9406f32e7eSjoerg if (size_t Size = preferred_buffer_size())
9506f32e7eSjoerg SetBufferSize(Size);
9606f32e7eSjoerg else
9706f32e7eSjoerg // It may return 0, meaning this stream should be unbuffered.
9806f32e7eSjoerg SetUnbuffered();
9906f32e7eSjoerg }
10006f32e7eSjoerg
SetBufferAndMode(char * BufferStart,size_t Size,BufferKind Mode)10106f32e7eSjoerg void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
10206f32e7eSjoerg BufferKind Mode) {
103*da58b97aSjoerg assert(((Mode == BufferKind::Unbuffered && !BufferStart && Size == 0) ||
104*da58b97aSjoerg (Mode != BufferKind::Unbuffered && BufferStart && Size != 0)) &&
10506f32e7eSjoerg "stream must be unbuffered or have at least one byte");
10606f32e7eSjoerg // Make sure the current buffer is free of content (we can't flush here; the
10706f32e7eSjoerg // child buffer management logic will be in write_impl).
10806f32e7eSjoerg assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
10906f32e7eSjoerg
110*da58b97aSjoerg if (BufferMode == BufferKind::InternalBuffer)
11106f32e7eSjoerg delete [] OutBufStart;
11206f32e7eSjoerg OutBufStart = BufferStart;
11306f32e7eSjoerg OutBufEnd = OutBufStart+Size;
11406f32e7eSjoerg OutBufCur = OutBufStart;
11506f32e7eSjoerg BufferMode = Mode;
11606f32e7eSjoerg
11706f32e7eSjoerg assert(OutBufStart <= OutBufEnd && "Invalid size!");
11806f32e7eSjoerg }
11906f32e7eSjoerg
operator <<(unsigned long N)12006f32e7eSjoerg raw_ostream &raw_ostream::operator<<(unsigned long N) {
12106f32e7eSjoerg write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
12206f32e7eSjoerg return *this;
12306f32e7eSjoerg }
12406f32e7eSjoerg
operator <<(long N)12506f32e7eSjoerg raw_ostream &raw_ostream::operator<<(long N) {
12606f32e7eSjoerg write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
12706f32e7eSjoerg return *this;
12806f32e7eSjoerg }
12906f32e7eSjoerg
operator <<(unsigned long long N)13006f32e7eSjoerg raw_ostream &raw_ostream::operator<<(unsigned long long N) {
13106f32e7eSjoerg write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
13206f32e7eSjoerg return *this;
13306f32e7eSjoerg }
13406f32e7eSjoerg
operator <<(long long N)13506f32e7eSjoerg raw_ostream &raw_ostream::operator<<(long long N) {
13606f32e7eSjoerg write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
13706f32e7eSjoerg return *this;
13806f32e7eSjoerg }
13906f32e7eSjoerg
write_hex(unsigned long long N)14006f32e7eSjoerg raw_ostream &raw_ostream::write_hex(unsigned long long N) {
14106f32e7eSjoerg llvm::write_hex(*this, N, HexPrintStyle::Lower);
14206f32e7eSjoerg return *this;
14306f32e7eSjoerg }
14406f32e7eSjoerg
operator <<(Colors C)14506f32e7eSjoerg raw_ostream &raw_ostream::operator<<(Colors C) {
14606f32e7eSjoerg if (C == Colors::RESET)
14706f32e7eSjoerg resetColor();
14806f32e7eSjoerg else
14906f32e7eSjoerg changeColor(C);
15006f32e7eSjoerg return *this;
15106f32e7eSjoerg }
15206f32e7eSjoerg
write_uuid(const uuid_t UUID)15306f32e7eSjoerg raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
15406f32e7eSjoerg for (int Idx = 0; Idx < 16; ++Idx) {
15506f32e7eSjoerg *this << format("%02" PRIX32, UUID[Idx]);
15606f32e7eSjoerg if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9)
15706f32e7eSjoerg *this << "-";
15806f32e7eSjoerg }
15906f32e7eSjoerg return *this;
16006f32e7eSjoerg }
16106f32e7eSjoerg
16206f32e7eSjoerg
write_escaped(StringRef Str,bool UseHexEscapes)16306f32e7eSjoerg raw_ostream &raw_ostream::write_escaped(StringRef Str,
16406f32e7eSjoerg bool UseHexEscapes) {
16506f32e7eSjoerg for (unsigned char c : Str) {
16606f32e7eSjoerg switch (c) {
16706f32e7eSjoerg case '\\':
16806f32e7eSjoerg *this << '\\' << '\\';
16906f32e7eSjoerg break;
17006f32e7eSjoerg case '\t':
17106f32e7eSjoerg *this << '\\' << 't';
17206f32e7eSjoerg break;
17306f32e7eSjoerg case '\n':
17406f32e7eSjoerg *this << '\\' << 'n';
17506f32e7eSjoerg break;
17606f32e7eSjoerg case '"':
17706f32e7eSjoerg *this << '\\' << '"';
17806f32e7eSjoerg break;
17906f32e7eSjoerg default:
18006f32e7eSjoerg if (isPrint(c)) {
18106f32e7eSjoerg *this << c;
18206f32e7eSjoerg break;
18306f32e7eSjoerg }
18406f32e7eSjoerg
18506f32e7eSjoerg // Write out the escaped representation.
18606f32e7eSjoerg if (UseHexEscapes) {
18706f32e7eSjoerg *this << '\\' << 'x';
18806f32e7eSjoerg *this << hexdigit((c >> 4 & 0xF));
18906f32e7eSjoerg *this << hexdigit((c >> 0) & 0xF);
19006f32e7eSjoerg } else {
19106f32e7eSjoerg // Always use a full 3-character octal escape.
19206f32e7eSjoerg *this << '\\';
19306f32e7eSjoerg *this << char('0' + ((c >> 6) & 7));
19406f32e7eSjoerg *this << char('0' + ((c >> 3) & 7));
19506f32e7eSjoerg *this << char('0' + ((c >> 0) & 7));
19606f32e7eSjoerg }
19706f32e7eSjoerg }
19806f32e7eSjoerg }
19906f32e7eSjoerg
20006f32e7eSjoerg return *this;
20106f32e7eSjoerg }
20206f32e7eSjoerg
operator <<(const void * P)20306f32e7eSjoerg raw_ostream &raw_ostream::operator<<(const void *P) {
20406f32e7eSjoerg llvm::write_hex(*this, (uintptr_t)P, HexPrintStyle::PrefixLower);
20506f32e7eSjoerg return *this;
20606f32e7eSjoerg }
20706f32e7eSjoerg
operator <<(double N)20806f32e7eSjoerg raw_ostream &raw_ostream::operator<<(double N) {
20906f32e7eSjoerg llvm::write_double(*this, N, FloatStyle::Exponent);
21006f32e7eSjoerg return *this;
21106f32e7eSjoerg }
21206f32e7eSjoerg
flush_nonempty()21306f32e7eSjoerg void raw_ostream::flush_nonempty() {
21406f32e7eSjoerg assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
21506f32e7eSjoerg size_t Length = OutBufCur - OutBufStart;
21606f32e7eSjoerg OutBufCur = OutBufStart;
217*da58b97aSjoerg flush_tied_then_write(OutBufStart, Length);
21806f32e7eSjoerg }
21906f32e7eSjoerg
write(unsigned char C)22006f32e7eSjoerg raw_ostream &raw_ostream::write(unsigned char C) {
22106f32e7eSjoerg // Group exceptional cases into a single branch.
22206f32e7eSjoerg if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
22306f32e7eSjoerg if (LLVM_UNLIKELY(!OutBufStart)) {
224*da58b97aSjoerg if (BufferMode == BufferKind::Unbuffered) {
225*da58b97aSjoerg flush_tied_then_write(reinterpret_cast<char *>(&C), 1);
22606f32e7eSjoerg return *this;
22706f32e7eSjoerg }
22806f32e7eSjoerg // Set up a buffer and start over.
22906f32e7eSjoerg SetBuffered();
23006f32e7eSjoerg return write(C);
23106f32e7eSjoerg }
23206f32e7eSjoerg
23306f32e7eSjoerg flush_nonempty();
23406f32e7eSjoerg }
23506f32e7eSjoerg
23606f32e7eSjoerg *OutBufCur++ = C;
23706f32e7eSjoerg return *this;
23806f32e7eSjoerg }
23906f32e7eSjoerg
write(const char * Ptr,size_t Size)24006f32e7eSjoerg raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
24106f32e7eSjoerg // Group exceptional cases into a single branch.
24206f32e7eSjoerg if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
24306f32e7eSjoerg if (LLVM_UNLIKELY(!OutBufStart)) {
244*da58b97aSjoerg if (BufferMode == BufferKind::Unbuffered) {
245*da58b97aSjoerg flush_tied_then_write(Ptr, Size);
24606f32e7eSjoerg return *this;
24706f32e7eSjoerg }
24806f32e7eSjoerg // Set up a buffer and start over.
24906f32e7eSjoerg SetBuffered();
25006f32e7eSjoerg return write(Ptr, Size);
25106f32e7eSjoerg }
25206f32e7eSjoerg
25306f32e7eSjoerg size_t NumBytes = OutBufEnd - OutBufCur;
25406f32e7eSjoerg
25506f32e7eSjoerg // If the buffer is empty at this point we have a string that is larger
25606f32e7eSjoerg // than the buffer. Directly write the chunk that is a multiple of the
25706f32e7eSjoerg // preferred buffer size and put the remainder in the buffer.
25806f32e7eSjoerg if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
25906f32e7eSjoerg assert(NumBytes != 0 && "undefined behavior");
26006f32e7eSjoerg size_t BytesToWrite = Size - (Size % NumBytes);
261*da58b97aSjoerg flush_tied_then_write(Ptr, BytesToWrite);
26206f32e7eSjoerg size_t BytesRemaining = Size - BytesToWrite;
26306f32e7eSjoerg if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
26406f32e7eSjoerg // Too much left over to copy into our buffer.
26506f32e7eSjoerg return write(Ptr + BytesToWrite, BytesRemaining);
26606f32e7eSjoerg }
26706f32e7eSjoerg copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
26806f32e7eSjoerg return *this;
26906f32e7eSjoerg }
27006f32e7eSjoerg
27106f32e7eSjoerg // We don't have enough space in the buffer to fit the string in. Insert as
27206f32e7eSjoerg // much as possible, flush and start over with the remainder.
27306f32e7eSjoerg copy_to_buffer(Ptr, NumBytes);
27406f32e7eSjoerg flush_nonempty();
27506f32e7eSjoerg return write(Ptr + NumBytes, Size - NumBytes);
27606f32e7eSjoerg }
27706f32e7eSjoerg
27806f32e7eSjoerg copy_to_buffer(Ptr, Size);
27906f32e7eSjoerg
28006f32e7eSjoerg return *this;
28106f32e7eSjoerg }
28206f32e7eSjoerg
copy_to_buffer(const char * Ptr,size_t Size)28306f32e7eSjoerg void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
28406f32e7eSjoerg assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!");
28506f32e7eSjoerg
28606f32e7eSjoerg // Handle short strings specially, memcpy isn't very good at very short
28706f32e7eSjoerg // strings.
28806f32e7eSjoerg switch (Size) {
28906f32e7eSjoerg case 4: OutBufCur[3] = Ptr[3]; LLVM_FALLTHROUGH;
29006f32e7eSjoerg case 3: OutBufCur[2] = Ptr[2]; LLVM_FALLTHROUGH;
29106f32e7eSjoerg case 2: OutBufCur[1] = Ptr[1]; LLVM_FALLTHROUGH;
29206f32e7eSjoerg case 1: OutBufCur[0] = Ptr[0]; LLVM_FALLTHROUGH;
29306f32e7eSjoerg case 0: break;
29406f32e7eSjoerg default:
29506f32e7eSjoerg memcpy(OutBufCur, Ptr, Size);
29606f32e7eSjoerg break;
29706f32e7eSjoerg }
29806f32e7eSjoerg
29906f32e7eSjoerg OutBufCur += Size;
30006f32e7eSjoerg }
30106f32e7eSjoerg
flush_tied_then_write(const char * Ptr,size_t Size)302*da58b97aSjoerg void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) {
303*da58b97aSjoerg if (TiedStream)
304*da58b97aSjoerg TiedStream->flush();
305*da58b97aSjoerg write_impl(Ptr, Size);
306*da58b97aSjoerg }
307*da58b97aSjoerg
30806f32e7eSjoerg // Formatted output.
operator <<(const format_object_base & Fmt)30906f32e7eSjoerg raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
31006f32e7eSjoerg // If we have more than a few bytes left in our output buffer, try
31106f32e7eSjoerg // formatting directly onto its end.
31206f32e7eSjoerg size_t NextBufferSize = 127;
31306f32e7eSjoerg size_t BufferBytesLeft = OutBufEnd - OutBufCur;
31406f32e7eSjoerg if (BufferBytesLeft > 3) {
31506f32e7eSjoerg size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
31606f32e7eSjoerg
31706f32e7eSjoerg // Common case is that we have plenty of space.
31806f32e7eSjoerg if (BytesUsed <= BufferBytesLeft) {
31906f32e7eSjoerg OutBufCur += BytesUsed;
32006f32e7eSjoerg return *this;
32106f32e7eSjoerg }
32206f32e7eSjoerg
32306f32e7eSjoerg // Otherwise, we overflowed and the return value tells us the size to try
32406f32e7eSjoerg // again with.
32506f32e7eSjoerg NextBufferSize = BytesUsed;
32606f32e7eSjoerg }
32706f32e7eSjoerg
32806f32e7eSjoerg // If we got here, we didn't have enough space in the output buffer for the
32906f32e7eSjoerg // string. Try printing into a SmallVector that is resized to have enough
33006f32e7eSjoerg // space. Iterate until we win.
33106f32e7eSjoerg SmallVector<char, 128> V;
33206f32e7eSjoerg
33306f32e7eSjoerg while (true) {
33406f32e7eSjoerg V.resize(NextBufferSize);
33506f32e7eSjoerg
33606f32e7eSjoerg // Try formatting into the SmallVector.
33706f32e7eSjoerg size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
33806f32e7eSjoerg
33906f32e7eSjoerg // If BytesUsed fit into the vector, we win.
34006f32e7eSjoerg if (BytesUsed <= NextBufferSize)
34106f32e7eSjoerg return write(V.data(), BytesUsed);
34206f32e7eSjoerg
34306f32e7eSjoerg // Otherwise, try again with a new size.
34406f32e7eSjoerg assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
34506f32e7eSjoerg NextBufferSize = BytesUsed;
34606f32e7eSjoerg }
34706f32e7eSjoerg }
34806f32e7eSjoerg
operator <<(const formatv_object_base & Obj)34906f32e7eSjoerg raw_ostream &raw_ostream::operator<<(const formatv_object_base &Obj) {
35006f32e7eSjoerg Obj.format(*this);
35106f32e7eSjoerg return *this;
35206f32e7eSjoerg }
35306f32e7eSjoerg
operator <<(const FormattedString & FS)35406f32e7eSjoerg raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
355*da58b97aSjoerg unsigned LeftIndent = 0;
356*da58b97aSjoerg unsigned RightIndent = 0;
357*da58b97aSjoerg const ssize_t Difference = FS.Width - FS.Str.size();
358*da58b97aSjoerg if (Difference > 0) {
35906f32e7eSjoerg switch (FS.Justify) {
360*da58b97aSjoerg case FormattedString::JustifyNone:
361*da58b97aSjoerg break;
36206f32e7eSjoerg case FormattedString::JustifyLeft:
363*da58b97aSjoerg RightIndent = Difference;
36406f32e7eSjoerg break;
36506f32e7eSjoerg case FormattedString::JustifyRight:
366*da58b97aSjoerg LeftIndent = Difference;
36706f32e7eSjoerg break;
368*da58b97aSjoerg case FormattedString::JustifyCenter:
369*da58b97aSjoerg LeftIndent = Difference / 2;
370*da58b97aSjoerg RightIndent = Difference - LeftIndent;
37106f32e7eSjoerg break;
37206f32e7eSjoerg }
37306f32e7eSjoerg }
374*da58b97aSjoerg indent(LeftIndent);
375*da58b97aSjoerg (*this) << FS.Str;
376*da58b97aSjoerg indent(RightIndent);
37706f32e7eSjoerg return *this;
37806f32e7eSjoerg }
37906f32e7eSjoerg
operator <<(const FormattedNumber & FN)38006f32e7eSjoerg raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
38106f32e7eSjoerg if (FN.Hex) {
38206f32e7eSjoerg HexPrintStyle Style;
38306f32e7eSjoerg if (FN.Upper && FN.HexPrefix)
38406f32e7eSjoerg Style = HexPrintStyle::PrefixUpper;
38506f32e7eSjoerg else if (FN.Upper && !FN.HexPrefix)
38606f32e7eSjoerg Style = HexPrintStyle::Upper;
38706f32e7eSjoerg else if (!FN.Upper && FN.HexPrefix)
38806f32e7eSjoerg Style = HexPrintStyle::PrefixLower;
38906f32e7eSjoerg else
39006f32e7eSjoerg Style = HexPrintStyle::Lower;
39106f32e7eSjoerg llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
39206f32e7eSjoerg } else {
39306f32e7eSjoerg llvm::SmallString<16> Buffer;
39406f32e7eSjoerg llvm::raw_svector_ostream Stream(Buffer);
39506f32e7eSjoerg llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
39606f32e7eSjoerg if (Buffer.size() < FN.Width)
39706f32e7eSjoerg indent(FN.Width - Buffer.size());
39806f32e7eSjoerg (*this) << Buffer;
39906f32e7eSjoerg }
40006f32e7eSjoerg return *this;
40106f32e7eSjoerg }
40206f32e7eSjoerg
operator <<(const FormattedBytes & FB)40306f32e7eSjoerg raw_ostream &raw_ostream::operator<<(const FormattedBytes &FB) {
40406f32e7eSjoerg if (FB.Bytes.empty())
40506f32e7eSjoerg return *this;
40606f32e7eSjoerg
40706f32e7eSjoerg size_t LineIndex = 0;
40806f32e7eSjoerg auto Bytes = FB.Bytes;
40906f32e7eSjoerg const size_t Size = Bytes.size();
41006f32e7eSjoerg HexPrintStyle HPS = FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower;
41106f32e7eSjoerg uint64_t OffsetWidth = 0;
41206f32e7eSjoerg if (FB.FirstByteOffset.hasValue()) {
41306f32e7eSjoerg // Figure out how many nibbles are needed to print the largest offset
41406f32e7eSjoerg // represented by this data set, so that we can align the offset field
41506f32e7eSjoerg // to the right width.
41606f32e7eSjoerg size_t Lines = Size / FB.NumPerLine;
41706f32e7eSjoerg uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
41806f32e7eSjoerg unsigned Power = 0;
41906f32e7eSjoerg if (MaxOffset > 0)
42006f32e7eSjoerg Power = llvm::Log2_64_Ceil(MaxOffset);
42106f32e7eSjoerg OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
42206f32e7eSjoerg }
42306f32e7eSjoerg
42406f32e7eSjoerg // The width of a block of data including all spaces for group separators.
42506f32e7eSjoerg unsigned NumByteGroups =
42606f32e7eSjoerg alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
42706f32e7eSjoerg unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
42806f32e7eSjoerg
42906f32e7eSjoerg while (!Bytes.empty()) {
43006f32e7eSjoerg indent(FB.IndentLevel);
43106f32e7eSjoerg
43206f32e7eSjoerg if (FB.FirstByteOffset.hasValue()) {
43306f32e7eSjoerg uint64_t Offset = FB.FirstByteOffset.getValue();
43406f32e7eSjoerg llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
43506f32e7eSjoerg *this << ": ";
43606f32e7eSjoerg }
43706f32e7eSjoerg
43806f32e7eSjoerg auto Line = Bytes.take_front(FB.NumPerLine);
43906f32e7eSjoerg
44006f32e7eSjoerg size_t CharsPrinted = 0;
44106f32e7eSjoerg // Print the hex bytes for this line in groups
44206f32e7eSjoerg for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
44306f32e7eSjoerg if (I && (I % FB.ByteGroupSize) == 0) {
44406f32e7eSjoerg ++CharsPrinted;
44506f32e7eSjoerg *this << " ";
44606f32e7eSjoerg }
44706f32e7eSjoerg llvm::write_hex(*this, Line[I], HPS, 2);
44806f32e7eSjoerg }
44906f32e7eSjoerg
45006f32e7eSjoerg if (FB.ASCII) {
45106f32e7eSjoerg // Print any spaces needed for any bytes that we didn't print on this
45206f32e7eSjoerg // line so that the ASCII bytes are correctly aligned.
45306f32e7eSjoerg assert(BlockCharWidth >= CharsPrinted);
45406f32e7eSjoerg indent(BlockCharWidth - CharsPrinted + 2);
45506f32e7eSjoerg *this << "|";
45606f32e7eSjoerg
45706f32e7eSjoerg // Print the ASCII char values for each byte on this line
45806f32e7eSjoerg for (uint8_t Byte : Line) {
45906f32e7eSjoerg if (isPrint(Byte))
46006f32e7eSjoerg *this << static_cast<char>(Byte);
46106f32e7eSjoerg else
46206f32e7eSjoerg *this << '.';
46306f32e7eSjoerg }
46406f32e7eSjoerg *this << '|';
46506f32e7eSjoerg }
46606f32e7eSjoerg
46706f32e7eSjoerg Bytes = Bytes.drop_front(Line.size());
46806f32e7eSjoerg LineIndex += Line.size();
46906f32e7eSjoerg if (LineIndex < Size)
47006f32e7eSjoerg *this << '\n';
47106f32e7eSjoerg }
47206f32e7eSjoerg return *this;
47306f32e7eSjoerg }
47406f32e7eSjoerg
47506f32e7eSjoerg template <char C>
write_padding(raw_ostream & OS,unsigned NumChars)47606f32e7eSjoerg static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
47706f32e7eSjoerg static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
47806f32e7eSjoerg C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
47906f32e7eSjoerg C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
48006f32e7eSjoerg C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
48106f32e7eSjoerg C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C};
48206f32e7eSjoerg
48306f32e7eSjoerg // Usually the indentation is small, handle it with a fastpath.
48406f32e7eSjoerg if (NumChars < array_lengthof(Chars))
48506f32e7eSjoerg return OS.write(Chars, NumChars);
48606f32e7eSjoerg
48706f32e7eSjoerg while (NumChars) {
48806f32e7eSjoerg unsigned NumToWrite = std::min(NumChars,
48906f32e7eSjoerg (unsigned)array_lengthof(Chars)-1);
49006f32e7eSjoerg OS.write(Chars, NumToWrite);
49106f32e7eSjoerg NumChars -= NumToWrite;
49206f32e7eSjoerg }
49306f32e7eSjoerg return OS;
49406f32e7eSjoerg }
49506f32e7eSjoerg
49606f32e7eSjoerg /// indent - Insert 'NumSpaces' spaces.
indent(unsigned NumSpaces)49706f32e7eSjoerg raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
49806f32e7eSjoerg return write_padding<' '>(*this, NumSpaces);
49906f32e7eSjoerg }
50006f32e7eSjoerg
50106f32e7eSjoerg /// write_zeros - Insert 'NumZeros' nulls.
write_zeros(unsigned NumZeros)50206f32e7eSjoerg raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
50306f32e7eSjoerg return write_padding<'\0'>(*this, NumZeros);
50406f32e7eSjoerg }
50506f32e7eSjoerg
prepare_colors()506*da58b97aSjoerg bool raw_ostream::prepare_colors() {
507*da58b97aSjoerg // Colors were explicitly disabled.
508*da58b97aSjoerg if (!ColorEnabled)
509*da58b97aSjoerg return false;
510*da58b97aSjoerg
511*da58b97aSjoerg // Colors require changing the terminal but this stream is not going to a
512*da58b97aSjoerg // terminal.
513*da58b97aSjoerg if (sys::Process::ColorNeedsFlush() && !is_displayed())
514*da58b97aSjoerg return false;
515*da58b97aSjoerg
516*da58b97aSjoerg if (sys::Process::ColorNeedsFlush())
517*da58b97aSjoerg flush();
518*da58b97aSjoerg
519*da58b97aSjoerg return true;
520*da58b97aSjoerg }
521*da58b97aSjoerg
changeColor(enum Colors colors,bool bold,bool bg)522*da58b97aSjoerg raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
523*da58b97aSjoerg if (!prepare_colors())
524*da58b97aSjoerg return *this;
525*da58b97aSjoerg
526*da58b97aSjoerg const char *colorcode =
527*da58b97aSjoerg (colors == SAVEDCOLOR)
528*da58b97aSjoerg ? sys::Process::OutputBold(bg)
529*da58b97aSjoerg : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
530*da58b97aSjoerg if (colorcode)
531*da58b97aSjoerg write(colorcode, strlen(colorcode));
532*da58b97aSjoerg return *this;
533*da58b97aSjoerg }
534*da58b97aSjoerg
resetColor()535*da58b97aSjoerg raw_ostream &raw_ostream::resetColor() {
536*da58b97aSjoerg if (!prepare_colors())
537*da58b97aSjoerg return *this;
538*da58b97aSjoerg
539*da58b97aSjoerg if (const char *colorcode = sys::Process::ResetColor())
540*da58b97aSjoerg write(colorcode, strlen(colorcode));
541*da58b97aSjoerg return *this;
542*da58b97aSjoerg }
543*da58b97aSjoerg
reverseColor()544*da58b97aSjoerg raw_ostream &raw_ostream::reverseColor() {
545*da58b97aSjoerg if (!prepare_colors())
546*da58b97aSjoerg return *this;
547*da58b97aSjoerg
548*da58b97aSjoerg if (const char *colorcode = sys::Process::OutputReverse())
549*da58b97aSjoerg write(colorcode, strlen(colorcode));
550*da58b97aSjoerg return *this;
551*da58b97aSjoerg }
552*da58b97aSjoerg
anchor()55306f32e7eSjoerg void raw_ostream::anchor() {}
55406f32e7eSjoerg
55506f32e7eSjoerg //===----------------------------------------------------------------------===//
55606f32e7eSjoerg // Formatted Output
55706f32e7eSjoerg //===----------------------------------------------------------------------===//
55806f32e7eSjoerg
55906f32e7eSjoerg // Out of line virtual method.
home()56006f32e7eSjoerg void format_object_base::home() {
56106f32e7eSjoerg }
56206f32e7eSjoerg
56306f32e7eSjoerg //===----------------------------------------------------------------------===//
56406f32e7eSjoerg // raw_fd_ostream
56506f32e7eSjoerg //===----------------------------------------------------------------------===//
56606f32e7eSjoerg
getFD(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)56706f32e7eSjoerg static int getFD(StringRef Filename, std::error_code &EC,
56806f32e7eSjoerg sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
56906f32e7eSjoerg sys::fs::OpenFlags Flags) {
57006f32e7eSjoerg assert((Access & sys::fs::FA_Write) &&
57106f32e7eSjoerg "Cannot make a raw_ostream from a read-only descriptor!");
57206f32e7eSjoerg
57306f32e7eSjoerg // Handle "-" as stdout. Note that when we do this, we consider ourself
57406f32e7eSjoerg // the owner of stdout and may set the "binary" flag globally based on Flags.
57506f32e7eSjoerg if (Filename == "-") {
57606f32e7eSjoerg EC = std::error_code();
577*da58b97aSjoerg // Change stdout's text/binary mode based on the Flags.
578*da58b97aSjoerg sys::ChangeStdoutMode(Flags);
57906f32e7eSjoerg return STDOUT_FILENO;
58006f32e7eSjoerg }
58106f32e7eSjoerg
58206f32e7eSjoerg int FD;
58306f32e7eSjoerg if (Access & sys::fs::FA_Read)
58406f32e7eSjoerg EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
58506f32e7eSjoerg else
58606f32e7eSjoerg EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
58706f32e7eSjoerg if (EC)
58806f32e7eSjoerg return -1;
58906f32e7eSjoerg
59006f32e7eSjoerg return FD;
59106f32e7eSjoerg }
59206f32e7eSjoerg
raw_fd_ostream(StringRef Filename,std::error_code & EC)59306f32e7eSjoerg raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
59406f32e7eSjoerg : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
59506f32e7eSjoerg sys::fs::OF_None) {}
59606f32e7eSjoerg
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp)59706f32e7eSjoerg raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
59806f32e7eSjoerg sys::fs::CreationDisposition Disp)
59906f32e7eSjoerg : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
60006f32e7eSjoerg
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::FileAccess Access)60106f32e7eSjoerg raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
60206f32e7eSjoerg sys::fs::FileAccess Access)
60306f32e7eSjoerg : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
60406f32e7eSjoerg sys::fs::OF_None) {}
60506f32e7eSjoerg
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::OpenFlags Flags)60606f32e7eSjoerg raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
60706f32e7eSjoerg sys::fs::OpenFlags Flags)
60806f32e7eSjoerg : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
60906f32e7eSjoerg Flags) {}
61006f32e7eSjoerg
raw_fd_ostream(StringRef Filename,std::error_code & EC,sys::fs::CreationDisposition Disp,sys::fs::FileAccess Access,sys::fs::OpenFlags Flags)61106f32e7eSjoerg raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
61206f32e7eSjoerg sys::fs::CreationDisposition Disp,
61306f32e7eSjoerg sys::fs::FileAccess Access,
61406f32e7eSjoerg sys::fs::OpenFlags Flags)
61506f32e7eSjoerg : raw_fd_ostream(getFD(Filename, EC, Disp, Access, Flags), true) {}
61606f32e7eSjoerg
61706f32e7eSjoerg /// FD is the file descriptor that this writes to. If ShouldClose is true, this
61806f32e7eSjoerg /// closes the file when the stream is destroyed.
raw_fd_ostream(int fd,bool shouldClose,bool unbuffered,OStreamKind K)619*da58b97aSjoerg raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
620*da58b97aSjoerg OStreamKind K)
621*da58b97aSjoerg : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) {
62206f32e7eSjoerg if (FD < 0 ) {
62306f32e7eSjoerg ShouldClose = false;
62406f32e7eSjoerg return;
62506f32e7eSjoerg }
62606f32e7eSjoerg
627*da58b97aSjoerg enable_colors(true);
628*da58b97aSjoerg
62906f32e7eSjoerg // Do not attempt to close stdout or stderr. We used to try to maintain the
63006f32e7eSjoerg // property that tools that support writing file to stdout should not also
63106f32e7eSjoerg // write informational output to stdout, but in practice we were never able to
63206f32e7eSjoerg // maintain this invariant. Many features have been added to LLVM and clang
63306f32e7eSjoerg // (-fdump-record-layouts, optimization remarks, etc) that print to stdout, so
63406f32e7eSjoerg // users must simply be aware that mixed output and remarks is a possibility.
63506f32e7eSjoerg if (FD <= STDERR_FILENO)
63606f32e7eSjoerg ShouldClose = false;
63706f32e7eSjoerg
63806f32e7eSjoerg #ifdef _WIN32
63906f32e7eSjoerg // Check if this is a console device. This is not equivalent to isatty.
64006f32e7eSjoerg IsWindowsConsole =
64106f32e7eSjoerg ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR;
64206f32e7eSjoerg #endif
64306f32e7eSjoerg
64406f32e7eSjoerg // Get the starting position.
64506f32e7eSjoerg off_t loc = ::lseek(FD, 0, SEEK_CUR);
64606f32e7eSjoerg #ifdef _WIN32
64706f32e7eSjoerg // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
64806f32e7eSjoerg sys::fs::file_status Status;
64906f32e7eSjoerg std::error_code EC = status(FD, Status);
65006f32e7eSjoerg SupportsSeeking = !EC && Status.type() == sys::fs::file_type::regular_file;
65106f32e7eSjoerg #else
65206f32e7eSjoerg SupportsSeeking = loc != (off_t)-1;
65306f32e7eSjoerg #endif
65406f32e7eSjoerg if (!SupportsSeeking)
65506f32e7eSjoerg pos = 0;
65606f32e7eSjoerg else
65706f32e7eSjoerg pos = static_cast<uint64_t>(loc);
65806f32e7eSjoerg }
65906f32e7eSjoerg
~raw_fd_ostream()66006f32e7eSjoerg raw_fd_ostream::~raw_fd_ostream() {
66106f32e7eSjoerg if (FD >= 0) {
66206f32e7eSjoerg flush();
66306f32e7eSjoerg if (ShouldClose) {
66406f32e7eSjoerg if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
66506f32e7eSjoerg error_detected(EC);
66606f32e7eSjoerg }
66706f32e7eSjoerg }
66806f32e7eSjoerg
66906f32e7eSjoerg #ifdef __MINGW32__
67006f32e7eSjoerg // On mingw, global dtors should not call exit().
67106f32e7eSjoerg // report_fatal_error() invokes exit(). We know report_fatal_error()
67206f32e7eSjoerg // might not write messages to stderr when any errors were detected
67306f32e7eSjoerg // on FD == 2.
67406f32e7eSjoerg if (FD == 2) return;
67506f32e7eSjoerg #endif
67606f32e7eSjoerg
67706f32e7eSjoerg // If there are any pending errors, report them now. Clients wishing
67806f32e7eSjoerg // to avoid report_fatal_error calls should check for errors with
67906f32e7eSjoerg // has_error() and clear the error flag with clear_error() before
68006f32e7eSjoerg // destructing raw_ostream objects which may have errors.
68106f32e7eSjoerg if (has_error())
68206f32e7eSjoerg report_fatal_error("IO failure on output stream: " + error().message(),
68306f32e7eSjoerg /*gen_crash_diag=*/false);
68406f32e7eSjoerg }
68506f32e7eSjoerg
68606f32e7eSjoerg #if defined(_WIN32)
68706f32e7eSjoerg // The most reliable way to print unicode in a Windows console is with
68806f32e7eSjoerg // WriteConsoleW. To use that, first transcode from UTF-8 to UTF-16. This
68906f32e7eSjoerg // assumes that LLVM programs always print valid UTF-8 to the console. The data
69006f32e7eSjoerg // might not be UTF-8 for two major reasons:
69106f32e7eSjoerg // 1. The program is printing binary (-filetype=obj -o -), in which case it
69206f32e7eSjoerg // would have been gibberish anyway.
69306f32e7eSjoerg // 2. The program is printing text in a semi-ascii compatible codepage like
69406f32e7eSjoerg // shift-jis or cp1252.
69506f32e7eSjoerg //
69606f32e7eSjoerg // Most LLVM programs don't produce non-ascii text unless they are quoting
69706f32e7eSjoerg // user source input. A well-behaved LLVM program should either validate that
69806f32e7eSjoerg // the input is UTF-8 or transcode from the local codepage to UTF-8 before
69906f32e7eSjoerg // quoting it. If they don't, this may mess up the encoding, but this is still
70006f32e7eSjoerg // probably the best compromise we can make.
write_console_impl(int FD,StringRef Data)70106f32e7eSjoerg static bool write_console_impl(int FD, StringRef Data) {
70206f32e7eSjoerg SmallVector<wchar_t, 256> WideText;
70306f32e7eSjoerg
70406f32e7eSjoerg // Fall back to ::write if it wasn't valid UTF-8.
70506f32e7eSjoerg if (auto EC = sys::windows::UTF8ToUTF16(Data, WideText))
70606f32e7eSjoerg return false;
70706f32e7eSjoerg
70806f32e7eSjoerg // On Windows 7 and earlier, WriteConsoleW has a low maximum amount of data
70906f32e7eSjoerg // that can be written to the console at a time.
71006f32e7eSjoerg size_t MaxWriteSize = WideText.size();
71106f32e7eSjoerg if (!RunningWindows8OrGreater())
71206f32e7eSjoerg MaxWriteSize = 32767;
71306f32e7eSjoerg
71406f32e7eSjoerg size_t WCharsWritten = 0;
71506f32e7eSjoerg do {
71606f32e7eSjoerg size_t WCharsToWrite =
71706f32e7eSjoerg std::min(MaxWriteSize, WideText.size() - WCharsWritten);
71806f32e7eSjoerg DWORD ActuallyWritten;
71906f32e7eSjoerg bool Success =
72006f32e7eSjoerg ::WriteConsoleW((HANDLE)::_get_osfhandle(FD), &WideText[WCharsWritten],
72106f32e7eSjoerg WCharsToWrite, &ActuallyWritten,
72206f32e7eSjoerg /*Reserved=*/nullptr);
72306f32e7eSjoerg
72406f32e7eSjoerg // The most likely reason for WriteConsoleW to fail is that FD no longer
72506f32e7eSjoerg // points to a console. Fall back to ::write. If this isn't the first loop
72606f32e7eSjoerg // iteration, something is truly wrong.
72706f32e7eSjoerg if (!Success)
72806f32e7eSjoerg return false;
72906f32e7eSjoerg
73006f32e7eSjoerg WCharsWritten += ActuallyWritten;
73106f32e7eSjoerg } while (WCharsWritten != WideText.size());
73206f32e7eSjoerg return true;
73306f32e7eSjoerg }
73406f32e7eSjoerg #endif
73506f32e7eSjoerg
write_impl(const char * Ptr,size_t Size)73606f32e7eSjoerg void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
73706f32e7eSjoerg assert(FD >= 0 && "File already closed.");
73806f32e7eSjoerg pos += Size;
73906f32e7eSjoerg
74006f32e7eSjoerg #if defined(_WIN32)
74106f32e7eSjoerg // If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
74206f32e7eSjoerg // and using WriteConsoleW. If that fails, fall back to plain write().
74306f32e7eSjoerg if (IsWindowsConsole)
74406f32e7eSjoerg if (write_console_impl(FD, StringRef(Ptr, Size)))
74506f32e7eSjoerg return;
74606f32e7eSjoerg #endif
74706f32e7eSjoerg
74806f32e7eSjoerg // The maximum write size is limited to INT32_MAX. A write
74906f32e7eSjoerg // greater than SSIZE_MAX is implementation-defined in POSIX,
75006f32e7eSjoerg // and Windows _write requires 32 bit input.
75106f32e7eSjoerg size_t MaxWriteSize = INT32_MAX;
75206f32e7eSjoerg
75306f32e7eSjoerg #if defined(__linux__)
75406f32e7eSjoerg // It is observed that Linux returns EINVAL for a very large write (>2G).
75506f32e7eSjoerg // Make it a reasonably small value.
75606f32e7eSjoerg MaxWriteSize = 1024 * 1024 * 1024;
75706f32e7eSjoerg #endif
75806f32e7eSjoerg
75906f32e7eSjoerg do {
76006f32e7eSjoerg size_t ChunkSize = std::min(Size, MaxWriteSize);
76106f32e7eSjoerg ssize_t ret = ::write(FD, Ptr, ChunkSize);
76206f32e7eSjoerg
76306f32e7eSjoerg if (ret < 0) {
76406f32e7eSjoerg // If it's a recoverable error, swallow it and retry the write.
76506f32e7eSjoerg //
76606f32e7eSjoerg // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
76706f32e7eSjoerg // raw_ostream isn't designed to do non-blocking I/O. However, some
76806f32e7eSjoerg // programs, such as old versions of bjam, have mistakenly used
76906f32e7eSjoerg // O_NONBLOCK. For compatibility, emulate blocking semantics by
77006f32e7eSjoerg // spinning until the write succeeds. If you don't want spinning,
77106f32e7eSjoerg // don't use O_NONBLOCK file descriptors with raw_ostream.
77206f32e7eSjoerg if (errno == EINTR || errno == EAGAIN
77306f32e7eSjoerg #ifdef EWOULDBLOCK
77406f32e7eSjoerg || errno == EWOULDBLOCK
77506f32e7eSjoerg #endif
77606f32e7eSjoerg )
77706f32e7eSjoerg continue;
77806f32e7eSjoerg
77906f32e7eSjoerg // Otherwise it's a non-recoverable error. Note it and quit.
78006f32e7eSjoerg error_detected(std::error_code(errno, std::generic_category()));
78106f32e7eSjoerg break;
78206f32e7eSjoerg }
78306f32e7eSjoerg
78406f32e7eSjoerg // The write may have written some or all of the data. Update the
78506f32e7eSjoerg // size and buffer pointer to reflect the remainder that needs
78606f32e7eSjoerg // to be written. If there are no bytes left, we're done.
78706f32e7eSjoerg Ptr += ret;
78806f32e7eSjoerg Size -= ret;
78906f32e7eSjoerg } while (Size > 0);
79006f32e7eSjoerg }
79106f32e7eSjoerg
close()79206f32e7eSjoerg void raw_fd_ostream::close() {
79306f32e7eSjoerg assert(ShouldClose);
79406f32e7eSjoerg ShouldClose = false;
79506f32e7eSjoerg flush();
79606f32e7eSjoerg if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
79706f32e7eSjoerg error_detected(EC);
79806f32e7eSjoerg FD = -1;
79906f32e7eSjoerg }
80006f32e7eSjoerg
seek(uint64_t off)80106f32e7eSjoerg uint64_t raw_fd_ostream::seek(uint64_t off) {
80206f32e7eSjoerg assert(SupportsSeeking && "Stream does not support seeking!");
80306f32e7eSjoerg flush();
80406f32e7eSjoerg #ifdef _WIN32
80506f32e7eSjoerg pos = ::_lseeki64(FD, off, SEEK_SET);
80606f32e7eSjoerg #elif defined(HAVE_LSEEK64)
80706f32e7eSjoerg pos = ::lseek64(FD, off, SEEK_SET);
80806f32e7eSjoerg #else
80906f32e7eSjoerg pos = ::lseek(FD, off, SEEK_SET);
81006f32e7eSjoerg #endif
81106f32e7eSjoerg if (pos == (uint64_t)-1)
81206f32e7eSjoerg error_detected(std::error_code(errno, std::generic_category()));
81306f32e7eSjoerg return pos;
81406f32e7eSjoerg }
81506f32e7eSjoerg
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)81606f32e7eSjoerg void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size,
81706f32e7eSjoerg uint64_t Offset) {
81806f32e7eSjoerg uint64_t Pos = tell();
81906f32e7eSjoerg seek(Offset);
82006f32e7eSjoerg write(Ptr, Size);
82106f32e7eSjoerg seek(Pos);
82206f32e7eSjoerg }
82306f32e7eSjoerg
preferred_buffer_size() const82406f32e7eSjoerg size_t raw_fd_ostream::preferred_buffer_size() const {
82506f32e7eSjoerg #if defined(_WIN32)
82606f32e7eSjoerg // Disable buffering for console devices. Console output is re-encoded from
82706f32e7eSjoerg // UTF-8 to UTF-16 on Windows, and buffering it would require us to split the
82806f32e7eSjoerg // buffer on a valid UTF-8 codepoint boundary. Terminal buffering is disabled
82906f32e7eSjoerg // below on most other OSs, so do the same thing on Windows and avoid that
83006f32e7eSjoerg // complexity.
83106f32e7eSjoerg if (IsWindowsConsole)
83206f32e7eSjoerg return 0;
83306f32e7eSjoerg return raw_ostream::preferred_buffer_size();
83406f32e7eSjoerg #elif !defined(__minix)
83506f32e7eSjoerg // Minix has no st_blksize.
83606f32e7eSjoerg assert(FD >= 0 && "File not yet open!");
83706f32e7eSjoerg struct stat statbuf;
83806f32e7eSjoerg if (fstat(FD, &statbuf) != 0)
83906f32e7eSjoerg return 0;
84006f32e7eSjoerg
84106f32e7eSjoerg // If this is a terminal, don't use buffering. Line buffering
84206f32e7eSjoerg // would be a more traditional thing to do, but it's not worth
84306f32e7eSjoerg // the complexity.
844*da58b97aSjoerg if (S_ISCHR(statbuf.st_mode) && is_displayed())
84506f32e7eSjoerg return 0;
84606f32e7eSjoerg // Return the preferred block size.
84706f32e7eSjoerg return statbuf.st_blksize;
84806f32e7eSjoerg #else
84906f32e7eSjoerg return raw_ostream::preferred_buffer_size();
85006f32e7eSjoerg #endif
85106f32e7eSjoerg }
85206f32e7eSjoerg
is_displayed() const85306f32e7eSjoerg bool raw_fd_ostream::is_displayed() const {
85406f32e7eSjoerg return sys::Process::FileDescriptorIsDisplayed(FD);
85506f32e7eSjoerg }
85606f32e7eSjoerg
has_colors() const85706f32e7eSjoerg bool raw_fd_ostream::has_colors() const {
858*da58b97aSjoerg if (!HasColors)
859*da58b97aSjoerg HasColors = sys::Process::FileDescriptorHasColors(FD);
860*da58b97aSjoerg return *HasColors;
861*da58b97aSjoerg }
862*da58b97aSjoerg
lock()863*da58b97aSjoerg Expected<sys::fs::FileLocker> raw_fd_ostream::lock() {
864*da58b97aSjoerg std::error_code EC = sys::fs::lockFile(FD);
865*da58b97aSjoerg if (!EC)
866*da58b97aSjoerg return sys::fs::FileLocker(FD);
867*da58b97aSjoerg return errorCodeToError(EC);
868*da58b97aSjoerg }
869*da58b97aSjoerg
870*da58b97aSjoerg Expected<sys::fs::FileLocker>
tryLockFor(std::chrono::milliseconds Timeout)871*da58b97aSjoerg raw_fd_ostream::tryLockFor(std::chrono::milliseconds Timeout) {
872*da58b97aSjoerg std::error_code EC = sys::fs::tryLockFile(FD, Timeout);
873*da58b97aSjoerg if (!EC)
874*da58b97aSjoerg return sys::fs::FileLocker(FD);
875*da58b97aSjoerg return errorCodeToError(EC);
87606f32e7eSjoerg }
87706f32e7eSjoerg
anchor()87806f32e7eSjoerg void raw_fd_ostream::anchor() {}
87906f32e7eSjoerg
88006f32e7eSjoerg //===----------------------------------------------------------------------===//
88106f32e7eSjoerg // outs(), errs(), nulls()
88206f32e7eSjoerg //===----------------------------------------------------------------------===//
88306f32e7eSjoerg
outs()884*da58b97aSjoerg raw_fd_ostream &llvm::outs() {
88506f32e7eSjoerg // Set buffer settings to model stdout behavior.
88606f32e7eSjoerg std::error_code EC;
88706f32e7eSjoerg static raw_fd_ostream S("-", EC, sys::fs::OF_None);
88806f32e7eSjoerg assert(!EC);
88906f32e7eSjoerg return S;
89006f32e7eSjoerg }
89106f32e7eSjoerg
errs()892*da58b97aSjoerg raw_fd_ostream &llvm::errs() {
893*da58b97aSjoerg // Set standard error to be unbuffered and tied to outs() by default.
89406f32e7eSjoerg static raw_fd_ostream S(STDERR_FILENO, false, true);
89506f32e7eSjoerg return S;
89606f32e7eSjoerg }
89706f32e7eSjoerg
89806f32e7eSjoerg /// nulls() - This returns a reference to a raw_ostream which discards output.
nulls()89906f32e7eSjoerg raw_ostream &llvm::nulls() {
90006f32e7eSjoerg static raw_null_ostream S;
90106f32e7eSjoerg return S;
90206f32e7eSjoerg }
90306f32e7eSjoerg
90406f32e7eSjoerg //===----------------------------------------------------------------------===//
905*da58b97aSjoerg // File Streams
906*da58b97aSjoerg //===----------------------------------------------------------------------===//
907*da58b97aSjoerg
raw_fd_stream(StringRef Filename,std::error_code & EC)908*da58b97aSjoerg raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
909*da58b97aSjoerg : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
910*da58b97aSjoerg sys::fs::FA_Write | sys::fs::FA_Read,
911*da58b97aSjoerg sys::fs::OF_None),
912*da58b97aSjoerg true, false, OStreamKind::OK_FDStream) {
913*da58b97aSjoerg if (EC)
914*da58b97aSjoerg return;
915*da58b97aSjoerg
916*da58b97aSjoerg // Do not support non-seekable files.
917*da58b97aSjoerg if (!supportsSeeking())
918*da58b97aSjoerg EC = std::make_error_code(std::errc::invalid_argument);
919*da58b97aSjoerg }
920*da58b97aSjoerg
read(char * Ptr,size_t Size)921*da58b97aSjoerg ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
922*da58b97aSjoerg assert(get_fd() >= 0 && "File already closed.");
923*da58b97aSjoerg ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
924*da58b97aSjoerg if (Ret >= 0)
925*da58b97aSjoerg inc_pos(Ret);
926*da58b97aSjoerg else
927*da58b97aSjoerg error_detected(std::error_code(errno, std::generic_category()));
928*da58b97aSjoerg return Ret;
929*da58b97aSjoerg }
930*da58b97aSjoerg
classof(const raw_ostream * OS)931*da58b97aSjoerg bool raw_fd_stream::classof(const raw_ostream *OS) {
932*da58b97aSjoerg return OS->get_kind() == OStreamKind::OK_FDStream;
933*da58b97aSjoerg }
934*da58b97aSjoerg
935*da58b97aSjoerg //===----------------------------------------------------------------------===//
93606f32e7eSjoerg // raw_string_ostream
93706f32e7eSjoerg //===----------------------------------------------------------------------===//
93806f32e7eSjoerg
~raw_string_ostream()93906f32e7eSjoerg raw_string_ostream::~raw_string_ostream() {
94006f32e7eSjoerg flush();
94106f32e7eSjoerg }
94206f32e7eSjoerg
write_impl(const char * Ptr,size_t Size)94306f32e7eSjoerg void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
94406f32e7eSjoerg OS.append(Ptr, Size);
94506f32e7eSjoerg }
94606f32e7eSjoerg
94706f32e7eSjoerg //===----------------------------------------------------------------------===//
94806f32e7eSjoerg // raw_svector_ostream
94906f32e7eSjoerg //===----------------------------------------------------------------------===//
95006f32e7eSjoerg
current_pos() const95106f32e7eSjoerg uint64_t raw_svector_ostream::current_pos() const { return OS.size(); }
95206f32e7eSjoerg
write_impl(const char * Ptr,size_t Size)95306f32e7eSjoerg void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
95406f32e7eSjoerg OS.append(Ptr, Ptr + Size);
95506f32e7eSjoerg }
95606f32e7eSjoerg
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)95706f32e7eSjoerg void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
95806f32e7eSjoerg uint64_t Offset) {
95906f32e7eSjoerg memcpy(OS.data() + Offset, Ptr, Size);
96006f32e7eSjoerg }
96106f32e7eSjoerg
96206f32e7eSjoerg //===----------------------------------------------------------------------===//
96306f32e7eSjoerg // raw_null_ostream
96406f32e7eSjoerg //===----------------------------------------------------------------------===//
96506f32e7eSjoerg
~raw_null_ostream()96606f32e7eSjoerg raw_null_ostream::~raw_null_ostream() {
96706f32e7eSjoerg #ifndef NDEBUG
96806f32e7eSjoerg // ~raw_ostream asserts that the buffer is empty. This isn't necessary
96906f32e7eSjoerg // with raw_null_ostream, but it's better to have raw_null_ostream follow
97006f32e7eSjoerg // the rules than to change the rules just for raw_null_ostream.
97106f32e7eSjoerg flush();
97206f32e7eSjoerg #endif
97306f32e7eSjoerg }
97406f32e7eSjoerg
write_impl(const char * Ptr,size_t Size)97506f32e7eSjoerg void raw_null_ostream::write_impl(const char *Ptr, size_t Size) {
97606f32e7eSjoerg }
97706f32e7eSjoerg
current_pos() const97806f32e7eSjoerg uint64_t raw_null_ostream::current_pos() const {
97906f32e7eSjoerg return 0;
98006f32e7eSjoerg }
98106f32e7eSjoerg
pwrite_impl(const char * Ptr,size_t Size,uint64_t Offset)98206f32e7eSjoerg void raw_null_ostream::pwrite_impl(const char *Ptr, size_t Size,
98306f32e7eSjoerg uint64_t Offset) {}
98406f32e7eSjoerg
anchor()98506f32e7eSjoerg void raw_pwrite_stream::anchor() {}
98606f32e7eSjoerg
anchor()98706f32e7eSjoerg void buffer_ostream::anchor() {}
988*da58b97aSjoerg
anchor()989*da58b97aSjoerg void buffer_unique_ostream::anchor() {}
990*da58b97aSjoerg
writeToOutput(StringRef OutputFileName,std::function<Error (raw_ostream &)> Write)991*da58b97aSjoerg Error llvm::writeToOutput(StringRef OutputFileName,
992*da58b97aSjoerg std::function<Error(raw_ostream &)> Write) {
993*da58b97aSjoerg if (OutputFileName == "-")
994*da58b97aSjoerg return Write(outs());
995*da58b97aSjoerg
996*da58b97aSjoerg if (OutputFileName == "/dev/null") {
997*da58b97aSjoerg raw_null_ostream Out;
998*da58b97aSjoerg return Write(Out);
999*da58b97aSjoerg }
1000*da58b97aSjoerg
1001*da58b97aSjoerg unsigned Mode = sys::fs::all_read | sys::fs::all_write | sys::fs::all_exe;
1002*da58b97aSjoerg Expected<sys::fs::TempFile> Temp =
1003*da58b97aSjoerg sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode);
1004*da58b97aSjoerg if (!Temp)
1005*da58b97aSjoerg return createFileError(OutputFileName, Temp.takeError());
1006*da58b97aSjoerg
1007*da58b97aSjoerg raw_fd_ostream Out(Temp->FD, false);
1008*da58b97aSjoerg
1009*da58b97aSjoerg if (Error E = Write(Out)) {
1010*da58b97aSjoerg if (Error DiscardError = Temp->discard())
1011*da58b97aSjoerg return joinErrors(std::move(E), std::move(DiscardError));
1012*da58b97aSjoerg return E;
1013*da58b97aSjoerg }
1014*da58b97aSjoerg Out.flush();
1015*da58b97aSjoerg
1016*da58b97aSjoerg return Temp->keep(OutputFileName);
1017*da58b97aSjoerg }
1018