Merge pull request #60 from data-man/termcolor_latest

Update termcolor to latest
This commit is contained in:
Pranav
2020-05-25 08:22:14 -05:00
committed by GitHub

View File

@@ -17,433 +17,618 @@
// defines the appropriate macro that is used to wrap some // defines the appropriate macro that is used to wrap some
// platform specific things // platform specific things
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
#define TERMCOLOR_OS_WINDOWS # define TERMCOLOR_OS_WINDOWS
#elif defined(__APPLE__) #elif defined(__APPLE__)
#define TERMCOLOR_OS_MACOS # define TERMCOLOR_OS_MACOS
#elif defined(__unix__) || defined(__unix) #elif defined(__unix__) || defined(__unix)
#define TERMCOLOR_OS_LINUX # define TERMCOLOR_OS_LINUX
#else #else
#error unsupported platform # error unsupported platform
#endif #endif
// This headers provides the `isatty()`/`fileno()` functions, // This headers provides the `isatty()`/`fileno()` functions,
// which are used for testing whether a standart stream refers // which are used for testing whether a standart stream refers
// to the terminal. As for Windows, we also need WinApi funcs // to the terminal. As for Windows, we also need WinApi funcs
// for changing colors attributes of the terminal. // for changing colors attributes of the terminal.
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#include <unistd.h> # include <unistd.h>
#elif defined(TERMCOLOR_OS_WINDOWS) #elif defined(TERMCOLOR_OS_WINDOWS)
#if !defined(NOMINMAX) # include <io.h>
#define NOMINMAX # include <windows.h>
#endif
#include <io.h>
#include <windows.h>
#endif #endif
#include <cstdio>
#include <iostream> #include <iostream>
#include <cstdio>
namespace termcolor {
// Forward declaration of the `_internal` namespace.
// All comments are below.
namespace _internal {
// An index to be used to access a private storage of I/O streams. See
// colorize / nocolorize I/O manipulators for details.
static int colorize_index = std::ios_base::xalloc();
inline FILE *get_standard_stream(const std::ostream &stream); namespace termcolor
inline bool is_colorized(std::ostream &stream); {
inline bool is_atty(const std::ostream &stream); // Forward declaration of the `_internal` namespace.
// All comments are below.
namespace _internal
{
// An index to be used to access a private storage of I/O streams. See
// colorize / nocolorize I/O manipulators for details.
static int colorize_index = std::ios_base::xalloc();
#if defined(TERMCOLOR_OS_WINDOWS) inline FILE* get_standard_stream(const std::ostream& stream);
inline void win_change_attributes(std::ostream &stream, int foreground, int background = -1); inline bool is_colorized(std::ostream& stream);
#endif inline bool is_atty(const std::ostream& stream);
} // namespace _internal
inline std::ostream &colorize(std::ostream &stream) { #if defined(TERMCOLOR_OS_WINDOWS)
stream.iword(_internal::colorize_index) = 1L; inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
return stream; #endif
} }
inline std::ostream &nocolorize(std::ostream &stream) { inline
stream.iword(_internal::colorize_index) = 0L; std::ostream& colorize(std::ostream& stream)
return stream; {
} stream.iword(_internal::colorize_index) = 1L;
return stream;
}
inline std::ostream &reset(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& nocolorize(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[00m"; stream.iword(_internal::colorize_index) = 0L;
#elif defined(TERMCOLOR_OS_WINDOWS) return stream;
_internal::win_change_attributes(stream, -1, -1); }
#endif
}
return stream;
}
inline std::ostream &bold(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& reset(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[1m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[00m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} _internal::win_change_attributes(stream, -1, -1);
#endif
}
return stream;
}
inline std::ostream &dark(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& bold(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[2m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[1m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} #endif
}
return stream;
}
inline std::ostream &italic(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& dark(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[3m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[2m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} #endif
}
return stream;
}
inline std::ostream &underline(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& italic(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[4m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[3m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} #endif
}
return stream;
}
inline std::ostream &blink(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& underline(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[5m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[4m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} #endif
}
return stream;
}
inline std::ostream &reverse(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& blink(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[7m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[5m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} #endif
}
return stream;
}
inline std::ostream &concealed(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& reverse(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[8m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[7m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} #endif
}
return stream;
}
inline std::ostream &crossed(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& concealed(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[9m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
#endif #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} stream << "\033[8m";
return stream; #elif defined(TERMCOLOR_OS_WINDOWS)
} #endif
}
return stream;
}
inline std::ostream &grey(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& crossed(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[30m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
0 // grey (black) stream << "\033[9m";
); #elif defined(TERMCOLOR_OS_WINDOWS)
#endif #endif
} }
return stream; return stream;
} }
inline std::ostream &red(std::ostream &stream) { template <uint8_t code> inline
if (_internal::is_colorized(stream)) { std::ostream& color(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[31m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, FOREGROUND_RED); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif char command[12];
} std::snprintf(command, sizeof(command), "\033[38;5;%dm", code);
return stream; stream << command;
} #elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline std::ostream &green(std::ostream &stream) { template <uint8_t code> inline
if (_internal::is_colorized(stream)) { std::ostream& on_color(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[32m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, FOREGROUND_GREEN); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif char command[12];
} std::snprintf(command, sizeof(command), "\033[48;5;%dm", code);
return stream; stream << command;
} #elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline std::ostream &yellow(std::ostream &stream) { template <uint8_t r, uint8_t g, uint8_t b> inline
if (_internal::is_colorized(stream)) { std::ostream& color(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[33m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, FOREGROUND_GREEN | FOREGROUND_RED); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif char command[20];
} std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b);
return stream; stream << command;
} #elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline std::ostream &blue(std::ostream &stream) { template <uint8_t r, uint8_t g, uint8_t b> inline
if (_internal::is_colorized(stream)) { std::ostream& on_color(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[34m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, FOREGROUND_BLUE); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif char command[20];
} std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b);
return stream; stream << command;
} #elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline std::ostream &magenta(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& grey(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[35m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_RED); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif stream << "\033[30m";
} #elif defined(TERMCOLOR_OS_WINDOWS)
return stream; _internal::win_change_attributes(stream,
} 0 // grey (black)
);
#endif
}
return stream;
}
inline std::ostream &cyan(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& red(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[36m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_GREEN); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif stream << "\033[31m";
} #elif defined(TERMCOLOR_OS_WINDOWS)
return stream; _internal::win_change_attributes(stream,
} FOREGROUND_RED
);
#endif
}
return stream;
}
inline std::ostream &white(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& green(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[37m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif stream << "\033[32m";
} #elif defined(TERMCOLOR_OS_WINDOWS)
return stream; _internal::win_change_attributes(stream,
} FOREGROUND_GREEN
);
#endif
}
return stream;
}
inline std::ostream &on_grey(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& yellow(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[40m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, -1, #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
0 // grey (black) stream << "\033[33m";
); #elif defined(TERMCOLOR_OS_WINDOWS)
#endif _internal::win_change_attributes(stream,
} FOREGROUND_GREEN | FOREGROUND_RED
return stream; );
} #endif
}
return stream;
}
inline std::ostream &on_red(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& blue(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[41m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, -1, BACKGROUND_RED); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif stream << "\033[34m";
} #elif defined(TERMCOLOR_OS_WINDOWS)
return stream; _internal::win_change_attributes(stream,
} FOREGROUND_BLUE
);
#endif
}
return stream;
}
inline std::ostream &on_green(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& magenta(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[42m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, -1, BACKGROUND_GREEN); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif stream << "\033[35m";
} #elif defined(TERMCOLOR_OS_WINDOWS)
return stream; _internal::win_change_attributes(stream,
} FOREGROUND_BLUE | FOREGROUND_RED
);
#endif
}
return stream;
}
inline std::ostream &on_yellow(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& cyan(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[43m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_RED); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif stream << "\033[36m";
} #elif defined(TERMCOLOR_OS_WINDOWS)
return stream; _internal::win_change_attributes(stream,
} FOREGROUND_BLUE | FOREGROUND_GREEN
);
#endif
}
return stream;
}
inline std::ostream &on_blue(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& white(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[44m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, -1, BACKGROUND_BLUE); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
#endif stream << "\033[37m";
} #elif defined(TERMCOLOR_OS_WINDOWS)
return stream; _internal::win_change_attributes(stream,
} FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
);
#endif
}
return stream;
}
inline std::ostream &on_magenta(std::ostream &stream) {
if (_internal::is_colorized(stream)) {
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[45m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1, BACKGROUND_BLUE | BACKGROUND_RED);
#endif
}
return stream;
}
inline std::ostream &on_cyan(std::ostream &stream) {
if (_internal::is_colorized(stream)) {
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[46m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_BLUE);
#endif
}
return stream;
}
inline std::ostream &on_white(std::ostream &stream) { inline
if (_internal::is_colorized(stream)) { std::ostream& on_grey(std::ostream& stream)
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) {
stream << "\033[47m"; if (_internal::is_colorized(stream))
#elif defined(TERMCOLOR_OS_WINDOWS) {
_internal::win_change_attributes(stream, -1, #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED); stream << "\033[40m";
#endif #elif defined(TERMCOLOR_OS_WINDOWS)
} _internal::win_change_attributes(stream, -1,
0 // grey (black)
);
#endif
}
return stream;
}
return stream; inline
} std::ostream& on_red(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[41m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_RED
);
#endif
}
return stream;
}
//! Since C++ hasn't a way to hide something in the header from inline
//! the outer access, I have to introduce this namespace which std::ostream& on_green(std::ostream& stream)
//! is used for internal purpose and should't be access from {
//! the user code. if (_internal::is_colorized(stream))
namespace _internal { {
//! Since C++ hasn't a true way to extract stream handler #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
//! from the a given `std::ostream` object, I have to write stream << "\033[42m";
//! this kind of hack. #elif defined(TERMCOLOR_OS_WINDOWS)
inline FILE *get_standard_stream(const std::ostream &stream) { _internal::win_change_attributes(stream, -1,
if (&stream == &std::cout) BACKGROUND_GREEN
return stdout; );
else if ((&stream == &std::cerr) || (&stream == &std::clog)) #endif
return stderr; }
return stream;
}
return 0; inline
} std::ostream& on_yellow(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[43m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_RED
);
#endif
}
return stream;
}
// Say whether a given stream should be colorized or not. It's always inline
// true for ATTY streams and may be true for streams marked with std::ostream& on_blue(std::ostream& stream)
// colorize flag. {
inline bool is_colorized(std::ostream &stream) { if (_internal::is_colorized(stream))
return is_atty(stream) || static_cast<bool>(stream.iword(colorize_index)); {
} #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[44m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE
);
#endif
}
return stream;
}
//! Test whether a given `std::ostream` object refers to inline
//! a terminal. std::ostream& on_magenta(std::ostream& stream)
inline bool is_atty(const std::ostream &stream) { {
FILE *std_stream = get_standard_stream(stream); if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[45m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
return stream;
}
// Unfortunately, fileno() ends with segmentation fault inline
// if invalid file descriptor is passed. So we need to std::ostream& on_cyan(std::ostream& stream)
// handle this case gracefully and assume it's not a tty {
// if standard stream is not detected, and 0 is returned. if (_internal::is_colorized(stream))
if (!std_stream) {
return false; #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[46m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE
);
#endif
}
return stream;
}
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) inline
return ::isatty(fileno(std_stream)); std::ostream& on_white(std::ostream& stream)
#elif defined(TERMCOLOR_OS_WINDOWS) {
return ::_isatty(_fileno(std_stream)); if (_internal::is_colorized(stream))
#endif {
} #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\033[47m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
#if defined(TERMCOLOR_OS_WINDOWS) return stream;
//! Change Windows Terminal colors attribute. If some }
//! parameter is `-1` then attribute won't changed.
inline void win_change_attributes(std::ostream &stream, int foreground, int background) {
// yeah, i know.. it's ugly, it's windows.
static WORD defaultAttributes = 0;
// Windows doesn't have ANSI escape sequences and so we use special
// API to change Terminal output color. That means we can't
// manipulate colors by means of "std::stringstream" and hence
// should do nothing in this case.
if (!_internal::is_atty(stream))
return;
// get terminal handle
HANDLE hTerminal = INVALID_HANDLE_VALUE;
if (&stream == &std::cout)
hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
else if (&stream == &std::cerr)
hTerminal = GetStdHandle(STD_ERROR_HANDLE);
// save default terminal attributes if it unsaved //! Since C++ hasn't a way to hide something in the header from
if (!defaultAttributes) { //! the outer access, I have to introduce this namespace which
CONSOLE_SCREEN_BUFFER_INFO info; //! is used for internal purpose and should't be access from
if (!GetConsoleScreenBufferInfo(hTerminal, &info)) //! the user code.
return; namespace _internal
defaultAttributes = info.wAttributes; {
} //! Since C++ hasn't a true way to extract stream handler
//! from the a given `std::ostream` object, I have to write
//! this kind of hack.
inline
FILE* get_standard_stream(const std::ostream& stream)
{
if (&stream == &std::cout)
return stdout;
else if ((&stream == &std::cerr) || (&stream == &std::clog))
return stderr;
// restore all default settings return nullptr;
if (foreground == -1 && background == -1) { }
SetConsoleTextAttribute(hTerminal, defaultAttributes);
return;
}
// get current settings // Say whether a given stream should be colorized or not. It's always
CONSOLE_SCREEN_BUFFER_INFO info; // true for ATTY streams and may be true for streams marked with
if (!GetConsoleScreenBufferInfo(hTerminal, &info)) // colorize flag.
return; inline
bool is_colorized(std::ostream& stream)
{
return is_atty(stream) || static_cast<bool>(stream.iword(colorize_index));
}
if (foreground != -1) { //! Test whether a given `std::ostream` object refers to
info.wAttributes &= ~(info.wAttributes & 0x0F); //! a terminal.
info.wAttributes |= static_cast<WORD>(foreground); inline
} bool is_atty(const std::ostream& stream)
{
FILE* std_stream = get_standard_stream(stream);
if (background != -1) { // Unfortunately, fileno() ends with segmentation fault
info.wAttributes &= ~(info.wAttributes & 0xF0); // if invalid file descriptor is passed. So we need to
info.wAttributes |= static_cast<WORD>(background); // handle this case gracefully and assume it's not a tty
} // if standard stream is not detected, and 0 is returned.
if (!std_stream)
return false;
SetConsoleTextAttribute(hTerminal, info.wAttributes); #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
} return ::isatty(fileno(std_stream));
#endif // TERMCOLOR_OS_WINDOWS #elif defined(TERMCOLOR_OS_WINDOWS)
return ::_isatty(_fileno(std_stream));
#endif
}
} // namespace _internal #if defined(TERMCOLOR_OS_WINDOWS)
//! Change Windows Terminal colors attribute. If some
//! parameter is `-1` then attribute won't changed.
inline void win_change_attributes(std::ostream& stream, int foreground, int background)
{
// yeah, i know.. it's ugly, it's windows.
static WORD defaultAttributes = 0;
// Windows doesn't have ANSI escape sequences and so we use special
// API to change Terminal output color. That means we can't
// manipulate colors by means of "std::stringstream" and hence
// should do nothing in this case.
if (!_internal::is_atty(stream))
return;
// get terminal handle
HANDLE hTerminal = INVALID_HANDLE_VALUE;
if (&stream == &std::cout)
hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
else if (&stream == &std::cerr)
hTerminal = GetStdHandle(STD_ERROR_HANDLE);
// save default terminal attributes if it unsaved
if (!defaultAttributes)
{
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
return;
defaultAttributes = info.wAttributes;
}
// restore all default settings
if (foreground == -1 && background == -1)
{
SetConsoleTextAttribute(hTerminal, defaultAttributes);
return;
}
// get current settings
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
return;
if (foreground != -1)
{
info.wAttributes &= ~(info.wAttributes & 0x0F);
info.wAttributes |= static_cast<WORD>(foreground);
}
if (background != -1)
{
info.wAttributes &= ~(info.wAttributes & 0xF0);
info.wAttributes |= static_cast<WORD>(background);
}
SetConsoleTextAttribute(hTerminal, info.wAttributes);
}
#endif // TERMCOLOR_OS_WINDOWS
} // namespace _internal
} // namespace termcolor } // namespace termcolor
#undef TERMCOLOR_OS_WINDOWS #undef TERMCOLOR_OS_WINDOWS
#undef TERMCOLOR_OS_MACOS #undef TERMCOLOR_OS_MACOS
#undef TERMCOLOR_OS_LINUX #undef TERMCOLOR_OS_LINUX