summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Support/Process.h4
-rw-r--r--include/llvm/Support/raw_ostream.h5
-rw-r--r--lib/Support/Unix/Process.inc4
-rw-r--r--lib/Support/Windows/Process.inc33
-rw-r--r--lib/Support/raw_ostream.cpp13
5 files changed, 59 insertions, 0 deletions
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 33799229ff..d796b7906d 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -136,6 +136,10 @@ namespace sys {
/// Same as OutputColor, but only enables the bold attribute.
static const char *OutputBold(bool bg);
+ /// This function returns the escape sequence to reverse forground and
+ /// background colors.
+ static const char *OutputReverse();
+
/// Resets the terminals colors, or returns an escape sequence to do so.
static const char *ResetColor();
/// @}
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 6bfae5e298..6c5d4787e0 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -222,6 +222,9 @@ public:
/// outputting colored text, or before program exit.
virtual raw_ostream &resetColor() { return *this; }
+ /// Reverses the forground and background colors.
+ virtual raw_ostream &reverseColor() { return *this; }
+
/// This function determines if this stream is connected to a "tty" or
/// "console" window. That is, the output would be displayed to the user
/// rather than being put on a pipe or stored in a file.
@@ -379,6 +382,8 @@ public:
bool bg=false);
virtual raw_ostream &resetColor();
+ virtual raw_ostream &reverseColor();
+
virtual bool is_displayed() const;
/// has_error - Return the value of the flag in this raw_fd_ostream indicating
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index 2d7fd384e8..f640462a45 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -290,6 +290,10 @@ const char *Process::OutputBold(bool bg) {
return "\033[1m";
}
+const char *Process::OutputReverse() {
+ return "\033[7m";
+}
+
const char *Process::ResetColor() {
return "\033[0m";
}
diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc
index 913b0734dd..a61ce55170 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -215,6 +215,39 @@ const char *Process::OutputColor(char code, bool bold, bool bg) {
return 0;
}
+WORD GetConsoleTextAttribute(__in HANDLE hConsoleOutput)
+{
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&info);
+ return info.wAttributes;
+}
+
+const char *Process::OutputReverse() {
+ const WORD attributes
+ = GetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE));
+
+ const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
+ FOREGROUND_RED | FOREGROUND_INTENSITY;
+ const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
+ BACKGROUND_RED | BACKGROUND_INTENSITY;
+ const WORD color_mask = foreground_mask | background_mask;
+
+ WORD new_attributes =
+ ((attributes & FOREGROUND_BLUE )?BACKGROUND_BLUE :0) |
+ ((attributes & FOREGROUND_GREEN )?BACKGROUND_GREEN :0) |
+ ((attributes & FOREGROUND_RED )?BACKGROUND_RED :0) |
+ ((attributes & FOREGROUND_INTENSITY)?BACKGROUND_INTENSITY:0) |
+ ((attributes & BACKGROUND_BLUE )?FOREGROUND_BLUE :0) |
+ ((attributes & BACKGROUND_GREEN )?FOREGROUND_GREEN :0) |
+ ((attributes & BACKGROUND_RED )?FOREGROUND_RED :0) |
+ ((attributes & BACKGROUND_INTENSITY)?FOREGROUND_INTENSITY:0) |
+ 0;
+ new_attributes = (attributes & ~color_mask) | (new_attributes & color_mask);
+
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),new_attributes);
+ return 0;
+}
+
const char *Process::ResetColor() {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
return 0;
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 72d3986f41..86cdca1572 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -633,6 +633,19 @@ raw_ostream &raw_fd_ostream::resetColor() {
return *this;
}
+raw_ostream &raw_fd_ostream::reverseColor() {
+ 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);
}