From be6cf883b322b52371f7a45bea4d0339ed2fc29d Mon Sep 17 00:00:00 2001 From: Jose Fonseca Date: Thu, 5 May 2016 11:03:22 +0100 Subject: highlight: Move into libs. --- lib/CMakeLists.txt | 1 + lib/highlight/CMakeLists.txt | 4 + lib/highlight/highlight.cpp | 324 +++++++++++++++++++++++++++++++++++++++++++ lib/highlight/highlight.hpp | 86 ++++++++++++ 4 files changed, 415 insertions(+) create mode 100644 lib/highlight/CMakeLists.txt create mode 100644 lib/highlight/highlight.cpp create mode 100644 lib/highlight/highlight.hpp (limited to 'lib') diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 2bdad31e..3ce90a6e 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory (guids) +add_subdirectory (highlight) diff --git a/lib/highlight/CMakeLists.txt b/lib/highlight/CMakeLists.txt new file mode 100644 index 00000000..1f3c5962 --- /dev/null +++ b/lib/highlight/CMakeLists.txt @@ -0,0 +1,4 @@ +add_convenience_library (highlight + highlight.hpp + highlight.cpp +) diff --git a/lib/highlight/highlight.cpp b/lib/highlight/highlight.cpp new file mode 100644 index 00000000..f3555f3f --- /dev/null +++ b/lib/highlight/highlight.cpp @@ -0,0 +1,324 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +/* + * Helpers for coloring output. + */ + + +#ifdef _WIN32 + +#include +#include // _isatty +#include // _fileno + +#ifndef COMMON_LVB_LEADING_BYTE +#define COMMON_LVB_LEADING_BYTE 0x0100 +#endif + +#ifndef COMMON_LVB_TRAILING_BYTE +#define COMMON_LVB_TRAILING_BYTE 0x0200 +#endif + +#ifndef COMMON_LVB_GRID_HORIZONTAL +#define COMMON_LVB_GRID_HORIZONTAL 0x0400 +#endif + +#ifndef COMMON_LVB_GRID_LVERTICAL +#define COMMON_LVB_GRID_LVERTICAL 0x0800 +#endif + +#ifndef COMMON_LVB_GRID_RVERTICAL +#define COMMON_LVB_GRID_RVERTICAL 0x1000 +#endif + +#ifndef COMMON_LVB_REVERSE_VIDEO +#define COMMON_LVB_REVERSE_VIDEO 0x4000 +#endif + +#ifndef COMMON_LVB_UNDERSCORE +#define COMMON_LVB_UNDERSCORE 0x8000 +#endif + +#else /* !_WIN32 */ + +#include // isatty + +#endif /* !_WIN32 */ + + +#include "highlight.hpp" + + +namespace highlight { + + +class PlainAttribute : public Attribute { +public: + PlainAttribute(void) {} + virtual void apply(std::ostream &) const override {} +}; + +static const PlainAttribute plainAttribute; + + +class PlainHighlighter : public Highlighter { +public: + PlainHighlighter(void) {} + virtual const Attribute & normal(void) const override { return plainAttribute; } + virtual const Attribute & bold(void) const override { return plainAttribute; } + virtual const Attribute & italic(void) const override { return plainAttribute; } + virtual const Attribute & strike(void) const override { return plainAttribute; } + virtual const Attribute & color(Color) const override { return plainAttribute; } +}; + +static const PlainHighlighter plainHighlighter; + + +class AnsiAttribute : public Attribute { +protected: + const char *escape; + +public: + AnsiAttribute(const char *_escape) : + escape(_escape) + {} + + void apply(std::ostream& os) const override { + os << "\33[" << escape; + } +}; + +static const AnsiAttribute ansiNormal("0m"); +static const AnsiAttribute ansiBold("1m"); +static const AnsiAttribute ansiItalic("3m"); +static const AnsiAttribute ansiStrike("9m"); +static const AnsiAttribute ansiRed("31m"); +static const AnsiAttribute ansiGreen("32m"); +static const AnsiAttribute ansiBlue("34m"); +static const AnsiAttribute ansiGray("37m"); + + +/** + * Highlighter for plain-text files which outputs ANSI escape codes. See + * http://en.wikipedia.org/wiki/ANSI_escape_code for more information + * concerning ANSI escape codes. + */ +class AnsiHighlighter : public Highlighter { +public: + AnsiHighlighter(void) {} + virtual const Attribute & normal(void) const override { return ansiNormal; } + virtual const Attribute & bold(void) const override { return ansiBold; } + virtual const Attribute & italic(void) const override { + /* Italic is not widely supported, or worse, implemented with a reverse */ + if (0) + return ansiItalic; + else + return plainAttribute; + } + virtual const Attribute & strike(void) const override { return ansiStrike; } + virtual const Attribute & color(Color c) const override { + switch (c) { + case RED: + return ansiRed; + case GREEN: + return ansiGreen; + case BLUE: + return ansiBlue; + case GRAY: + return ansiGray; + default: + return plainAttribute; + } + } +}; + +static const AnsiHighlighter ansiHighlighter; + + +#ifdef _WIN32 + + +class WindowsAttribute : public Attribute { +protected: + WORD wAttributes; + +public: + WindowsAttribute(WORD _wAttributes) : + wAttributes(_wAttributes) + {} + + void apply(std::ostream& os) const { + DWORD nStdHandleOutput; + if (&os == &std::cout) { + nStdHandleOutput = STD_OUTPUT_HANDLE; + } else if (&os == &std::cerr) { + nStdHandleOutput = STD_ERROR_HANDLE; + } else { + return; + } + HANDLE hConsoleOutput = GetStdHandle(nStdHandleOutput); + if (hConsoleOutput == INVALID_HANDLE_VALUE) { + return; + } + + SetConsoleTextAttribute(hConsoleOutput, wAttributes); + } +}; + +static const WindowsAttribute winNormal(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); +static const WindowsAttribute winBold(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); +static const WindowsAttribute winItalic(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); +static const WindowsAttribute winStrike(COMMON_LVB_REVERSE_VIDEO | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); +static const WindowsAttribute winRed(FOREGROUND_RED | FOREGROUND_INTENSITY); +static const WindowsAttribute winGreen(FOREGROUND_GREEN | FOREGROUND_INTENSITY); +static const WindowsAttribute winBlue(FOREGROUND_BLUE | FOREGROUND_INTENSITY); + + +/** + * Highlighter for the Windows Console. + */ +class WindowsHighlighter : public Highlighter { +public: + virtual const Attribute & normal(void) const { return winNormal; } + virtual const Attribute & bold(void) const { return winBold; } + virtual const Attribute & italic(void) const { return winItalic; } + virtual const Attribute & strike(void) const { return winStrike; } + virtual const Attribute & color(Color c) const { + switch (c) { + case RED: + return winRed; + case GREEN: + return winGreen; + case BLUE: + return winBlue; + default: + return plainAttribute; + } + } +}; + +static const WindowsHighlighter windowsHighlighter; + + +static bool +haveAnsi(void) +{ + static bool checked = false; + static bool result = false; + + if (!checked) { + // https://conemu.github.io/en/ConEmuEnvironment.html + // XXX: Didn't quite work for me + if (0) { + const char *conEmuANSI = getenv("ConEmuANSI"); + if (conEmuANSI && + strcmp(conEmuANSI, "ON") == 0) { + result = true; + checked = true; + return result; + } + } + + // Cygwin shell + if (1) { + const char *term = getenv("TERM"); + if (term && + strcmp(term, "xterm") == 0) { + result = true; + checked = true; + return result; + } + } + + // http://wiki.winehq.org/DeveloperFaq#detect-wine + HMODULE hNtDll = GetModuleHandleA("ntdll"); + if (hNtDll) { + result = GetProcAddress(hNtDll, "wine_get_version") != NULL; + } + + checked = true; + } + + return result; +} + + +#endif /* _WIN32 */ + + +const Highlighter & +defaultHighlighter(bool color) { + if (color) { +#ifdef _WIN32 + if (haveAnsi()) { + return ansiHighlighter; + } else { + return windowsHighlighter; + } +#else + return ansiHighlighter; +#endif + } else { + return plainHighlighter; + } +} + + +bool +isAtty(std::ostream &os) { + int fd; + if (&os == &std::cout) { +#ifdef _WIN32 + fd = _fileno(stdout); +#else + fd = STDOUT_FILENO; +#endif + } else if (&os == &std::cerr) { +#ifdef _WIN32 + fd = _fileno(stderr); +#else + fd = STDERR_FILENO; +#endif + } else { + return false; + } +#ifdef _WIN32 + return _isatty(fd); +#else + return isatty(fd); +#endif +} + + +const Highlighter & +defaultHighlighter(std::ostream & os) +{ + return defaultHighlighter(isAtty(os)); +} + + + +} /* namespace highlight */ diff --git a/lib/highlight/highlight.hpp b/lib/highlight/highlight.hpp new file mode 100644 index 00000000..bda49142 --- /dev/null +++ b/lib/highlight/highlight.hpp @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +/* + * Helpers for coloring output. + */ + +#pragma once + + +#include + + +namespace highlight { + + +/* + * See also http://bytes.com/topic/c/answers/63822-design-question-little-c-header-colorizing-text-linux-comments-ideas + */ + +class Attribute { +public: + virtual void apply(std::ostream &) const = 0; +}; + + +inline std::ostream & +operator << (std::ostream & os, const Attribute & attr) { + attr.apply(os); + return os; +} + + +enum Color { + RED, + GREEN, + BLUE, + GRAY, +}; + + +class Highlighter { +public: + virtual const Attribute & normal(void) const = 0; + virtual const Attribute & bold(void) const = 0; + virtual const Attribute & italic(void) const = 0; + virtual const Attribute & strike(void) const = 0; + virtual const Attribute & color(Color) const = 0; +}; + + +bool +isAtty(std::ostream & os); + +const Highlighter & +defaultHighlighter(bool color = true); + +const Highlighter & +defaultHighlighter(std::ostream & os); + + +} /* namespace highlight */ + + -- cgit v1.2.3