diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 48bb623b063..4a6b51ac609 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -72,7 +72,7 @@ private: public: // color order matches ANSI escape sequence, don't change - enum Colors { + enum class Colors { BLACK = 0, RED, GREEN, @@ -81,9 +81,21 @@ public: MAGENTA, CYAN, WHITE, - SAVEDCOLOR + SAVEDCOLOR, + RESET, }; + static const Colors BLACK = Colors::BLACK; + static const Colors RED = Colors::RED; + static const Colors GREEN = Colors::GREEN; + static const Colors YELLOW = Colors::YELLOW; + static const Colors BLUE = Colors::BLUE; + static const Colors MAGENTA = Colors::MAGENTA; + static const Colors CYAN = Colors::CYAN; + static const Colors WHITE = Colors::WHITE; + static const Colors SAVEDCOLOR = Colors::SAVEDCOLOR; + static const Colors RESET = Colors::RESET; + explicit raw_ostream(bool unbuffered = false) : BufferMode(unbuffered ? Unbuffered : InternalBuffer) { // Start out ready to flush. @@ -214,6 +226,9 @@ public: /// Output \p N in hexadecimal, without any prefix or padding. raw_ostream &write_hex(unsigned long long N); + // Change the foreground color of text. + raw_ostream &operator<<(Colors C); + /// Output a formatted UUID with dash separators. using uuid_t = uint8_t[16]; raw_ostream &write_uuid(const uuid_t UUID); @@ -277,6 +292,10 @@ public: /// This function determines if this stream is displayed and supports colors. virtual bool has_colors() const { return is_displayed(); } + // Enable or disable colors. Once disable_colors() is called, + // changeColor() has no effect until enable_colors() is called. + virtual void enable_colors(bool enable) {} + //===--------------------------------------------------------------------===// // Subclass Interface //===--------------------------------------------------------------------===// @@ -365,8 +384,8 @@ public: class raw_fd_ostream : public raw_pwrite_stream { int FD; bool ShouldClose; - bool SupportsSeeking; + bool ColorEnabled = true; #ifdef _WIN32 /// True if this fd refers to a Windows console device. Mintty and other @@ -442,6 +461,8 @@ public: bool has_colors() const override; + void enable_colors(bool enable) override { ColorEnabled = enable; } + std::error_code error() const { return EC; } /// Return the value of the flag in this raw_fd_ostream indicating whether an diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 16e56ed7835..b9989371f5e 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -65,6 +65,17 @@ 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; + raw_ostream::~raw_ostream() { // raw_ostream's subclasses should take care to flush the buffer // in their destructors. @@ -133,6 +144,14 @@ raw_ostream &raw_ostream::write_hex(unsigned long long N) { return *this; } +raw_ostream &raw_ostream::operator<<(Colors C) { + if (C == Colors::RESET) + resetColor(); + else + changeColor(C); + return *this; +} + raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) { for (int Idx = 0; Idx < 16; ++Idx) { *this << format("%02" PRIX32, UUID[Idx]); @@ -784,11 +803,15 @@ size_t raw_fd_ostream::preferred_buffer_size() const { 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(colors, bold, bg); + (colors == SAVEDCOLOR) + ? sys::Process::OutputBold(bg) + : sys::Process::OutputColor(static_cast(colors), bold, bg); if (colorcode) { size_t len = strlen(colorcode); write(colorcode, len); @@ -799,6 +822,9 @@ raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold, } raw_ostream &raw_fd_ostream::resetColor() { + if (!ColorEnabled) + return *this; + if (sys::Process::ColorNeedsFlush()) flush(); const char *colorcode = sys::Process::ResetColor(); @@ -812,6 +838,9 @@ raw_ostream &raw_fd_ostream::resetColor() { } raw_ostream &raw_fd_ostream::reverseColor() { + if (!ColorEnabled) + return *this; + if (sys::Process::ColorNeedsFlush()) flush(); const char *colorcode = sys::Process::OutputReverse();