Add reverseColor to raw_ostream.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 16 Apr 2012 07:07:38 +0000 (07:07 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 16 Apr 2012 07:07:38 +0000 (07:07 +0000)
To be used in printing unprintable source in clang diagnostics.
Patch by Seth Cantrell!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154800 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/Process.h
include/llvm/Support/raw_ostream.h
lib/Support/Unix/Process.inc
lib/Support/Windows/Process.inc
lib/Support/raw_ostream.cpp

index 33799229ff3576156ddf4978f9576a0b5102e09b..d796b7906d378f54d0579e06b7457872d786cebc 100644 (file)
@@ -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();
     /// @}
index 6bfae5e298225499df05dd6b68f5e9006d5ecb99..6c5d4787e0f5096dc1e510edaf0f20472dbbb87b 100644 (file)
@@ -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
index 2d7fd384e8bba0608ad65b9784b73ab116f78175..f640462a45174ad7b20e804537a648fcfc42182f 100644 (file)
@@ -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";
 }
index 913b0734ddc9b21bf9afaf17ab23fd949cb9844c..a61ce5517065fd47d9d4d31df221860537422687 100644 (file)
@@ -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;
index 72d3986f41ddd23973a0a1e9369767da4b054a10..86cdca1572784acba96bfc7a3babf847b8f0eb56 100644 (file)
@@ -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);
 }