From 7904bbfa9b1b70c3dabc8caa364c672deed70f2f Mon Sep 17 00:00:00 2001
From: Seth Cantrell <seth.cantrell@gmail.com>
Date: Fri, 23 Mar 2012 02:45:43 -0400
Subject: [PATCH] Add reverseColor to raw_ostream

to be used in printing unprintable source in clang diagnostics
---
 include/llvm/Support/Process.h     |    4 ++++
 include/llvm/Support/raw_ostream.h |    5 +++++
 lib/Support/Unix/Process.inc       |    4 ++++
 lib/Support/Windows/Process.inc    |    6 ++++++
 lib/Support/raw_ostream.cpp        |   13 +++++++++++++
 5 files changed, 32 insertions(+)

diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 3379922..d796b79 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 6bfae5e..6c5d478 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 5cdb11c..88cf50a 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 913b073..55264b4 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -215,6 +215,12 @@ const char *Process::OutputColor(char code, bool bold, bool bg) {
   return 0;
 }
 
+const char *Process::OutputReverse() {
+  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
+                          COMMON_LVB_REVERSE_VIDEO);
+  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 72d3986..86cdca1 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);
 }
-- 
1.7.9.4

