summaryrefslogtreecommitdiff
path: root/llvm/lib/Support/raw_ostream.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/Support/raw_ostream.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'llvm/lib/Support/raw_ostream.cpp')
-rw-r--r--llvm/lib/Support/raw_ostream.cpp194
1 files changed, 95 insertions, 99 deletions
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 4bb315f824af2..f2d78d7732397 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -60,21 +60,21 @@
#ifdef _WIN32
#include "llvm/Support/ConvertUTF.h"
-#include "Windows/WindowsSupport.h"
+#include "llvm/Support/Windows/WindowsSupport.h"
#endif
using namespace llvm;
-const raw_ostream::Colors raw_ostream::BLACK;
-const raw_ostream::Colors raw_ostream::RED;
-const raw_ostream::Colors raw_ostream::GREEN;
-const raw_ostream::Colors raw_ostream::YELLOW;
-const raw_ostream::Colors raw_ostream::BLUE;
-const raw_ostream::Colors raw_ostream::MAGENTA;
-const raw_ostream::Colors raw_ostream::CYAN;
-const raw_ostream::Colors raw_ostream::WHITE;
-const raw_ostream::Colors raw_ostream::SAVEDCOLOR;
-const raw_ostream::Colors raw_ostream::RESET;
+constexpr raw_ostream::Colors raw_ostream::BLACK;
+constexpr raw_ostream::Colors raw_ostream::RED;
+constexpr raw_ostream::Colors raw_ostream::GREEN;
+constexpr raw_ostream::Colors raw_ostream::YELLOW;
+constexpr raw_ostream::Colors raw_ostream::BLUE;
+constexpr raw_ostream::Colors raw_ostream::MAGENTA;
+constexpr raw_ostream::Colors raw_ostream::CYAN;
+constexpr raw_ostream::Colors raw_ostream::WHITE;
+constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
+constexpr raw_ostream::Colors raw_ostream::RESET;
raw_ostream::~raw_ostream() {
// raw_ostream's subclasses should take care to flush the buffer
@@ -216,7 +216,7 @@ void raw_ostream::flush_nonempty() {
assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
size_t Length = OutBufCur - OutBufStart;
OutBufCur = OutBufStart;
- write_impl(OutBufStart, Length);
+ flush_tied_then_write(OutBufStart, Length);
}
raw_ostream &raw_ostream::write(unsigned char C) {
@@ -224,7 +224,7 @@ raw_ostream &raw_ostream::write(unsigned char C) {
if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
if (LLVM_UNLIKELY(!OutBufStart)) {
if (BufferMode == BufferKind::Unbuffered) {
- write_impl(reinterpret_cast<char*>(&C), 1);
+ flush_tied_then_write(reinterpret_cast<char *>(&C), 1);
return *this;
}
// Set up a buffer and start over.
@@ -244,7 +244,7 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
if (LLVM_UNLIKELY(!OutBufStart)) {
if (BufferMode == BufferKind::Unbuffered) {
- write_impl(Ptr, Size);
+ flush_tied_then_write(Ptr, Size);
return *this;
}
// Set up a buffer and start over.
@@ -260,7 +260,7 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
assert(NumBytes != 0 && "undefined behavior");
size_t BytesToWrite = Size - (Size % NumBytes);
- write_impl(Ptr, BytesToWrite);
+ flush_tied_then_write(Ptr, BytesToWrite);
size_t BytesRemaining = Size - BytesToWrite;
if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
// Too much left over to copy into our buffer.
@@ -301,6 +301,12 @@ void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
OutBufCur += Size;
}
+void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) {
+ if (TiedStream)
+ TiedStream->flush();
+ write_impl(Ptr, Size);
+}
+
// Formatted output.
raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
// If we have more than a few bytes left in our output buffer, try
@@ -343,36 +349,33 @@ raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
}
raw_ostream &raw_ostream::operator<<(const formatv_object_base &Obj) {
- SmallString<128> S;
Obj.format(*this);
return *this;
}
raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
- if (FS.Str.size() >= FS.Width || FS.Justify == FormattedString::JustifyNone) {
- this->operator<<(FS.Str);
- return *this;
- }
- const size_t Difference = FS.Width - FS.Str.size();
- switch (FS.Justify) {
- case FormattedString::JustifyLeft:
- this->operator<<(FS.Str);
- this->indent(Difference);
- break;
- case FormattedString::JustifyRight:
- this->indent(Difference);
- this->operator<<(FS.Str);
- break;
- case FormattedString::JustifyCenter: {
- int PadAmount = Difference / 2;
- this->indent(PadAmount);
- this->operator<<(FS.Str);
- this->indent(Difference - PadAmount);
- break;
- }
- default:
- llvm_unreachable("Bad Justification");
+ unsigned LeftIndent = 0;
+ unsigned RightIndent = 0;
+ const ssize_t Difference = FS.Width - FS.Str.size();
+ if (Difference > 0) {
+ switch (FS.Justify) {
+ case FormattedString::JustifyNone:
+ break;
+ case FormattedString::JustifyLeft:
+ RightIndent = Difference;
+ break;
+ case FormattedString::JustifyRight:
+ LeftIndent = Difference;
+ break;
+ case FormattedString::JustifyCenter:
+ LeftIndent = Difference / 2;
+ RightIndent = Difference - LeftIndent;
+ break;
+ }
}
+ indent(LeftIndent);
+ (*this) << FS.Str;
+ indent(RightIndent);
return *this;
}
@@ -502,6 +505,53 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
return write_padding<'\0'>(*this, NumZeros);
}
+bool raw_ostream::prepare_colors() {
+ // Colors were explicitly disabled.
+ if (!ColorEnabled)
+ return false;
+
+ // Colors require changing the terminal but this stream is not going to a
+ // terminal.
+ if (sys::Process::ColorNeedsFlush() && !is_displayed())
+ return false;
+
+ if (sys::Process::ColorNeedsFlush())
+ flush();
+
+ return true;
+}
+
+raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
+ if (!prepare_colors())
+ return *this;
+
+ const char *colorcode =
+ (colors == SAVEDCOLOR)
+ ? sys::Process::OutputBold(bg)
+ : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
+ if (colorcode)
+ write(colorcode, strlen(colorcode));
+ return *this;
+}
+
+raw_ostream &raw_ostream::resetColor() {
+ if (!prepare_colors())
+ return *this;
+
+ if (const char *colorcode = sys::Process::ResetColor())
+ write(colorcode, strlen(colorcode));
+ return *this;
+}
+
+raw_ostream &raw_ostream::reverseColor() {
+ if (!prepare_colors())
+ return *this;
+
+ if (const char *colorcode = sys::Process::OutputReverse())
+ write(colorcode, strlen(colorcode));
+ return *this;
+}
+
void raw_ostream::anchor() {}
//===----------------------------------------------------------------------===//
@@ -577,6 +627,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
return;
}
+ enable_colors(true);
+
// Do not attempt to close stdout or stderr. We used to try to maintain the
// property that tools that support writing file to stdout should not also
// write informational output to stdout, but in practice we were never able to
@@ -792,7 +844,7 @@ size_t raw_fd_ostream::preferred_buffer_size() const {
// If this is a terminal, don't use buffering. Line buffering
// would be a more traditional thing to do, but it's not worth
// the complexity.
- if (S_ISCHR(statbuf.st_mode) && isatty(FD))
+ if (S_ISCHR(statbuf.st_mode) && is_displayed())
return 0;
// Return the preferred block size.
return statbuf.st_blksize;
@@ -801,58 +853,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const {
#endif
}
-raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold,
- bool bg) {
- if (!ColorEnabled)
- return *this;
-
- if (sys::Process::ColorNeedsFlush())
- flush();
- const char *colorcode =
- (colors == SAVEDCOLOR)
- ? sys::Process::OutputBold(bg)
- : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
- if (colorcode) {
- size_t len = strlen(colorcode);
- write(colorcode, len);
- // don't account colors towards output characters
- pos -= len;
- }
- return *this;
-}
-
-raw_ostream &raw_fd_ostream::resetColor() {
- if (!ColorEnabled)
- return *this;
-
- if (sys::Process::ColorNeedsFlush())
- flush();
- const char *colorcode = sys::Process::ResetColor();
- if (colorcode) {
- size_t len = strlen(colorcode);
- write(colorcode, len);
- // don't account colors towards output characters
- pos -= len;
- }
- return *this;
-}
-
-raw_ostream &raw_fd_ostream::reverseColor() {
- if (!ColorEnabled)
- return *this;
-
- if (sys::Process::ColorNeedsFlush())
- flush();
- const char *colorcode = sys::Process::OutputReverse();
- if (colorcode) {
- size_t len = strlen(colorcode);
- write(colorcode, len);
- // don't account colors towards output characters
- pos -= len;
- }
- return *this;
-}
-
bool raw_fd_ostream::is_displayed() const {
return sys::Process::FileDescriptorIsDisplayed(FD);
}
@@ -867,9 +867,7 @@ void raw_fd_ostream::anchor() {}
// outs(), errs(), nulls()
//===----------------------------------------------------------------------===//
-/// outs() - This returns a reference to a raw_ostream for standard output.
-/// Use it like: outs() << "foo" << "bar";
-raw_ostream &llvm::outs() {
+raw_fd_ostream &llvm::outs() {
// Set buffer settings to model stdout behavior.
std::error_code EC;
static raw_fd_ostream S("-", EC, sys::fs::OF_None);
@@ -877,10 +875,8 @@ raw_ostream &llvm::outs() {
return S;
}
-/// errs() - This returns a reference to a raw_ostream for standard error.
-/// Use it like: errs() << "foo" << "bar";
-raw_ostream &llvm::errs() {
- // Set standard error to be unbuffered by default.
+raw_fd_ostream &llvm::errs() {
+ // Set standard error to be unbuffered and tied to outs() by default.
static raw_fd_ostream S(STDERR_FILENO, false, true);
return S;
}