summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTorok Edwin <edwintorok@gmail.com>2009-06-04 07:09:50 +0000
committerTorok Edwin <edwintorok@gmail.com>2009-06-04 07:09:50 +0000
commit9b5a47fc3c5acad4f1637e1825787834d8357b70 (patch)
tree42872f1f633198ea769de9ee8d3bddb4d4e514bc /llvm/lib
parent75ac061fdb28f3b0135fbf45c3fd283c1463edb0 (diff)
downloadbcm5719-llvm-9b5a47fc3c5acad4f1637e1825787834d8357b70.tar.gz
bcm5719-llvm-9b5a47fc3c5acad4f1637e1825787834d8357b70.zip
Add support for outputting ANSI colors to raw_fd_ostream.
llvm-svn: 72854
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Support/raw_ostream.cpp30
-rw-r--r--llvm/lib/System/Unix/Process.inc59
-rw-r--r--llvm/lib/System/Win32/Process.inc66
3 files changed, 155 insertions, 0 deletions
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 6ac37bc840c..42e6fda97ba 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
#include "llvm/System/Program.h"
+#include "llvm/System/Process.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
@@ -301,6 +302,35 @@ uint64_t raw_fd_ostream::seek(uint64_t off) {
return pos;
}
+raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold,
+ bool bg) {
+ if (sys::Process::ColorNeedsFlush())
+ flush();
+ const char *colorcode =
+ (colors == SAVEDCOLOR) ? sys::Process::OutputBold(bg)
+ : sys::Process::OutputColor(colors, bold, bg);
+ if (colorcode) {
+ unsigned len = strlen(colorcode);
+ write(colorcode, len);
+ // don't account colors towards output characters
+ pos -= len;
+ }
+ return *this;
+}
+
+raw_ostream &raw_fd_ostream::resetColor() {
+ if (sys::Process::ColorNeedsFlush())
+ flush();
+ const char *colorcode = sys::Process::ResetColor();
+ if (colorcode) {
+ unsigned len = strlen(colorcode);
+ write(colorcode, len);
+ // don't account colors towards output characters
+ pos -= len;
+ }
+ return *this;
+}
+
//===----------------------------------------------------------------------===//
// raw_stdout/err_ostream
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/System/Unix/Process.inc b/llvm/lib/System/Unix/Process.inc
index 74b9bb8b142..2da31c9f215 100644
--- a/llvm/lib/System/Unix/Process.inc
+++ b/llvm/lib/System/Unix/Process.inc
@@ -235,3 +235,62 @@ unsigned Process::StandardErrColumns() {
return getColumns(2);
}
+
+static bool terminalHasColors() {
+ if (const char *term = std::getenv("TERM")) {
+ // Most modern terminals support ANSI escape sequences for colors.
+ // We could check terminfo, or have a list of known terms that support
+ // colors, but that would be overkill.
+ // The user can always ask for no colors by setting TERM to dumb, or
+ // using a commandline flag.
+ return strcmp(term, "dumb") != 0;
+ }
+ return false;
+}
+
+bool Process::StandardOutHasColors() {
+ if (!StandardOutIsDisplayed())
+ return false;
+ return terminalHasColors();
+}
+
+bool Process::StandardErrHasColors() {
+ if (!StandardErrIsDisplayed())
+ return false;
+ return terminalHasColors();
+}
+
+bool Process::ColorNeedsFlush() {
+ // No, we use ANSI escape sequences.
+ return false;
+}
+
+#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
+
+#define ALLCOLORS(FGBG,BOLD) {\
+ COLOR(FGBG, "0", BOLD),\
+ COLOR(FGBG, "1", BOLD),\
+ COLOR(FGBG, "2", BOLD),\
+ COLOR(FGBG, "3", BOLD),\
+ COLOR(FGBG, "4", BOLD),\
+ COLOR(FGBG, "5", BOLD),\
+ COLOR(FGBG, "6", BOLD),\
+ COLOR(FGBG, "7", BOLD)\
+ }
+
+static const char* colorcodes[2][2][8] = {
+ { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
+ { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
+};
+
+const char *Process::OutputColor(char code, bool bold, bool bg) {
+ return colorcodes[bg?1:0][bold?1:0][code&7];
+}
+
+const char *Process::OutputBold(bool bg) {
+ return "\033[1m";
+}
+
+const char *Process::ResetColor() {
+ return "\033[0m";
+}
diff --git a/llvm/lib/System/Win32/Process.inc b/llvm/lib/System/Win32/Process.inc
index e1d7a9222f7..97eba5808df 100644
--- a/llvm/lib/System/Win32/Process.inc
+++ b/llvm/lib/System/Win32/Process.inc
@@ -147,4 +147,70 @@ unsigned Process::StandardErrColumns() {
return Columns;
}
+// it always has colors
+bool Process::StandardErrHasColors() {
+ return StandardErrIsDisplayed();
+}
+
+bool Process::StandardOutHasColors() {
+ return StandardOutIsDisplayed();
+}
+namespace {
+class DefaultColors
+{
+ private:
+ WORD defaultColor;
+ public:
+ DefaultColors()
+ :defaultColor(GetCurrentColor()) {}
+ static unsigned GetCurrentColor() {
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ return csbi.wAttributes;
+ return 0;
+ }
+ WORD operator()() const { return defaultColor; }
+};
+
+DefaultColors defaultColors;
+}
+
+bool Process::ColorNeedsFlush() {
+ return true;
+}
+
+const char *Process::OutputBold(bool bg) {
+ WORD colors = DefaultColors::GetCurrentColor();
+ if (bg)
+ colors |= BACKGROUND_INTENSITY;
+ else
+ colors |= FOREGROUND_INTENSITY;
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+const char *Process::OutputColor(char code, bool bold, bool bg) {
+ WORD colors;
+ if (bg) {
+ colors = ((code&1) ? BACKGROUND_RED : 0) |
+ ((code&2) ? BACKGROUND_GREEN : 0 ) |
+ ((code&4) ? BACKGROUND_BLUE : 0);
+ if (bold)
+ colors |= BACKGROUND_INTENSITY;
+ } else {
+ colors = ((code&1) ? FOREGROUND_RED : 0) |
+ ((code&2) ? FOREGROUND_GREEN : 0 ) |
+ ((code&4) ? FOREGROUND_BLUE : 0);
+ if (bold)
+ colors |= FOREGROUND_INTENSITY;
+ }
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+const char *Process::ResetColor() {
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
+ return 0;
+}
+
}
OpenPOWER on IntegriCloud