From c338b5b280ae0a41ff149f1f96f769ac9171ce25 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Sun, 2 May 2021 23:17:24 -0500 Subject: [PATCH] Updated termcolor to v2.0. Bumped indicators to v2.1, closes #94 --- CMakeLists.txt | 6 +- README.md | 12 +- include/indicators/termcolor.hpp | 468 +++-- single_include/indicators/indicators.hpp | 1976 ++++++++++++++++++++-- utils/amalgamate/amalgamate.py | 8 +- 5 files changed, 2237 insertions(+), 233 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e5003d..82a696d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,14 +5,14 @@ if(DEFINED PROJECT_NAME) endif() if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.12") - project(indicators VERSION 2.0.0 LANGUAGES CXX + project(indicators VERSION 2.1.0 LANGUAGES CXX HOMEPAGE_URL "https://github.com/p-ranav/indicators" DESCRIPTION "Activity Indicators for Modern C++") elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.9") - project(indicators VERSION 2.0.0 LANGUAGES CXX + project(indicators VERSION 2.1.0 LANGUAGES CXX DESCRIPTION "Activity Indicators for Modern C++") else() - project(indicators VERSION 2.0.0 LANGUAGES CXX) + project(indicators VERSION 2.1.0 LANGUAGES CXX) endif() if(EXISTS "${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") diff --git a/README.md b/README.md index c614609..f3d8f85 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ license - version + version

@@ -944,6 +944,16 @@ cmake -DINDICATORS_SAMPLES=ON -DINDICATORS_DEMO=ON .. make ``` +### WinLibs + MinGW + +For Windows, if you use WinLibs like I do, the cmake command would look like this: + +```console +foo@bar:~$ mkdir build && cd build +foo@bar:~$ cmake -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER="C:/WinLibs/mingw64/bin/g++.exe" -DINDICATORS_SAMPLES=ON -DINDICATORS_DEMO=ON .. +foo@bar:~$ make -j4 +``` + ## Generating Single Header ```bash diff --git a/include/indicators/termcolor.hpp b/include/indicators/termcolor.hpp index 0023c3e..ca684ef 100644 --- a/include/indicators/termcolor.hpp +++ b/include/indicators/termcolor.hpp @@ -1,4 +1,3 @@ - //! //! termcolor //! ~~~~~~~~~ @@ -13,39 +12,37 @@ #ifndef TERMCOLOR_HPP_ #define TERMCOLOR_HPP_ -// the following snippet of code detects the current OS and -// defines the appropriate macro that is used to wrap some -// platform specific things +#include +#include + +// Detect target's platform and set some macros in order to wrap platform +// specific code this library depends on. #if defined(_WIN32) || defined(_WIN64) -# define TERMCOLOR_OS_WINDOWS -#elif defined(__APPLE__) -# define TERMCOLOR_OS_MACOS -#elif defined(__unix__) || defined(__unix) -# define TERMCOLOR_OS_LINUX -#else -# error unsupported platform +# define TERMCOLOR_TARGET_WINDOWS +#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) +# define TERMCOLOR_TARGET_POSIX #endif +// If implementation has not been explicitly set, try to choose one based on +// target platform. +#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP) +# if defined(TERMCOLOR_TARGET_POSIX) +# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# elif defined(TERMCOLOR_TARGET_WINDOWS) +# define TERMCOLOR_USE_WINDOWS_API +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# endif +#endif -// This headers provides the `isatty()`/`fileno()` functions, -// which are used for testing whether a standart stream refers -// to the terminal. As for Windows, we also need WinApi funcs -// for changing colors attributes of the terminal. -#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) +// These headers provide isatty()/fileno() functions, which are used for +// testing whether a standard stream refers to the terminal. +#if defined(TERMCOLOR_TARGET_POSIX) # include -#elif defined(TERMCOLOR_OS_WINDOWS) -#if defined(_MSC_VER) -#if !defined(NOMINMAX) -#define NOMINMAX -#endif +#elif defined(TERMCOLOR_TARGET_WINDOWS) # include # include #endif -#endif - - -#include -#include namespace termcolor @@ -54,15 +51,12 @@ namespace termcolor // 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 int colorize_index(); inline FILE* get_standard_stream(const std::ostream& stream); inline bool is_colorized(std::ostream& stream); inline bool is_atty(const std::ostream& stream); - #if defined(TERMCOLOR_OS_WINDOWS) + #if defined(TERMCOLOR_TARGET_WINDOWS) inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1); #endif } @@ -70,14 +64,14 @@ namespace termcolor inline std::ostream& colorize(std::ostream& stream) { - stream.iword(_internal::colorize_index) = 1L; + stream.iword(_internal::colorize_index()) = 1L; return stream; } inline std::ostream& nocolorize(std::ostream& stream) { - stream.iword(_internal::colorize_index) = 0L; + stream.iword(_internal::colorize_index()) = 0L; return stream; } @@ -86,9 +80,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[00m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, -1); #endif } @@ -100,9 +94,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[1m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -113,9 +107,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[2m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -126,9 +120,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[3m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -139,9 +133,10 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[4m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE); #endif } return stream; @@ -152,9 +147,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[5m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -165,9 +160,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[7m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -178,9 +173,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[8m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -191,9 +186,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[9m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -204,11 +199,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[12]; std::snprintf(command, sizeof(command), "\033[38;5;%dm", code); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -219,11 +214,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[12]; std::snprintf(command, sizeof(command), "\033[48;5;%dm", code); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -234,11 +229,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[20]; std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -249,11 +244,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[20]; std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -264,9 +259,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[30m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, 0 // grey (black) ); @@ -280,9 +275,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[31m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_RED ); @@ -296,9 +291,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[32m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_GREEN ); @@ -312,9 +307,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[33m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_GREEN | FOREGROUND_RED ); @@ -328,9 +323,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[34m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE ); @@ -344,9 +339,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[35m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_RED ); @@ -360,9 +355,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[36m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_GREEN ); @@ -376,9 +371,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[37m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ); @@ -388,15 +383,143 @@ namespace termcolor } + inline + std::ostream& bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[90m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 | FOREGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[91m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[92m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[93m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[94m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[95m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[96m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[97m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + inline std::ostream& on_grey(std::ostream& stream) { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[40m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, 0 // grey (black) ); @@ -410,9 +533,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[41m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_RED ); @@ -426,9 +549,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[42m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN ); @@ -442,9 +565,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[43m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_RED ); @@ -458,9 +581,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[44m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_BLUE ); @@ -474,9 +597,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[45m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_BLUE | BACKGROUND_RED ); @@ -490,9 +613,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[46m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_BLUE ); @@ -506,9 +629,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[47m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED ); @@ -519,6 +642,136 @@ namespace termcolor } + inline + std::ostream& on_bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[100m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 | BACKGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[101m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[102m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[103m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[104m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[105m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[106m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[107m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + + return stream; + } + + //! Since C++ hasn't a way to hide something in the header from //! the outer access, I have to introduce this namespace which @@ -526,6 +779,17 @@ namespace termcolor //! the user code. namespace _internal { + // An index to be used to access a private storage of I/O streams. See + // colorize / nocolorize I/O manipulators for details. Due to the fact + // that static variables ain't shared between translation units, inline + // function with local static variable is used to do the trick and share + // the variable value between translation units. + inline int colorize_index() + { + static int colorize_index = std::ios_base::xalloc(); + return colorize_index; + } + //! 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. @@ -546,7 +810,7 @@ namespace termcolor inline bool is_colorized(std::ostream& stream) { - return is_atty(stream) || static_cast(stream.iword(colorize_index)); + return is_atty(stream) || static_cast(stream.iword(colorize_index())); } //! Test whether a given `std::ostream` object refers to @@ -563,14 +827,16 @@ namespace termcolor if (!std_stream) return false; - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_TARGET_POSIX) return ::isatty(fileno(std_stream)); - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_TARGET_WINDOWS) return ::_isatty(_fileno(std_stream)); + #else + return false; #endif } - #if defined(TERMCOLOR_OS_WINDOWS) + #if defined(TERMCOLOR_TARGET_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) @@ -627,15 +893,19 @@ namespace termcolor SetConsoleTextAttribute(hTerminal, info.wAttributes); } - #endif // TERMCOLOR_OS_WINDOWS + #endif // TERMCOLOR_TARGET_WINDOWS } // namespace _internal } // namespace termcolor -#undef TERMCOLOR_OS_WINDOWS -#undef TERMCOLOR_OS_MACOS -#undef TERMCOLOR_OS_LINUX +#undef TERMCOLOR_TARGET_POSIX +#undef TERMCOLOR_TARGET_WINDOWS + +#if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION) +# undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# undef TERMCOLOR_USE_WINDOWS_API +#endif #endif // TERMCOLOR_HPP_ diff --git a/single_include/indicators/indicators.hpp b/single_include/indicators/indicators.hpp index e8dc5a8..71f0411 100644 --- a/single_include/indicators/indicators.hpp +++ b/single_include/indicators/indicators.hpp @@ -15,7 +15,6 @@ enum class FontStyle { bold, dark, italic, underline, blink, reverse, concealed, namespace indicators { enum class ProgressType { incremental, decremental }; } - //! //! termcolor //! ~~~~~~~~~ @@ -30,39 +29,37 @@ enum class ProgressType { incremental, decremental }; #ifndef TERMCOLOR_HPP_ #define TERMCOLOR_HPP_ -// the following snippet of code detects the current OS and -// defines the appropriate macro that is used to wrap some -// platform specific things +#include +#include + +// Detect target's platform and set some macros in order to wrap platform +// specific code this library depends on. #if defined(_WIN32) || defined(_WIN64) -# define TERMCOLOR_OS_WINDOWS -#elif defined(__APPLE__) -# define TERMCOLOR_OS_MACOS -#elif defined(__unix__) || defined(__unix) -# define TERMCOLOR_OS_LINUX -#else -# error unsupported platform +# define TERMCOLOR_TARGET_WINDOWS +#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) +# define TERMCOLOR_TARGET_POSIX #endif +// If implementation has not been explicitly set, try to choose one based on +// target platform. +#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP) +# if defined(TERMCOLOR_TARGET_POSIX) +# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# elif defined(TERMCOLOR_TARGET_WINDOWS) +# define TERMCOLOR_USE_WINDOWS_API +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# endif +#endif -// This headers provides the `isatty()`/`fileno()` functions, -// which are used for testing whether a standart stream refers -// to the terminal. As for Windows, we also need WinApi funcs -// for changing colors attributes of the terminal. -#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) +// These headers provide isatty()/fileno() functions, which are used for +// testing whether a standard stream refers to the terminal. +#if defined(TERMCOLOR_TARGET_POSIX) # include -#elif defined(TERMCOLOR_OS_WINDOWS) -#if defined(_MSC_VER) -#if !defined(NOMINMAX) -#define NOMINMAX -#endif +#elif defined(TERMCOLOR_TARGET_WINDOWS) # include # include #endif -#endif - - -#include -#include namespace termcolor @@ -71,15 +68,12 @@ namespace termcolor // 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 int colorize_index(); inline FILE* get_standard_stream(const std::ostream& stream); inline bool is_colorized(std::ostream& stream); inline bool is_atty(const std::ostream& stream); - #if defined(TERMCOLOR_OS_WINDOWS) + #if defined(TERMCOLOR_TARGET_WINDOWS) inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1); #endif } @@ -87,14 +81,14 @@ namespace termcolor inline std::ostream& colorize(std::ostream& stream) { - stream.iword(_internal::colorize_index) = 1L; + stream.iword(_internal::colorize_index()) = 1L; return stream; } inline std::ostream& nocolorize(std::ostream& stream) { - stream.iword(_internal::colorize_index) = 0L; + stream.iword(_internal::colorize_index()) = 0L; return stream; } @@ -103,9 +97,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[00m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, -1); #endif } @@ -117,9 +111,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[1m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -130,9 +124,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[2m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -143,9 +137,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[3m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -156,9 +150,10 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[4m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE); #endif } return stream; @@ -169,9 +164,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[5m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -182,9 +177,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[7m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -195,9 +190,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[8m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -208,9 +203,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[9m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -221,11 +216,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[12]; std::snprintf(command, sizeof(command), "\033[38;5;%dm", code); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -236,11 +231,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[12]; std::snprintf(command, sizeof(command), "\033[48;5;%dm", code); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -251,11 +246,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[20]; std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -266,11 +261,11 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) char command[20]; std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b); stream << command; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) #endif } return stream; @@ -281,9 +276,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[30m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, 0 // grey (black) ); @@ -297,9 +292,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[31m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_RED ); @@ -313,9 +308,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[32m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_GREEN ); @@ -329,9 +324,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[33m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_GREEN | FOREGROUND_RED ); @@ -345,9 +340,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[34m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE ); @@ -361,9 +356,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[35m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_RED ); @@ -377,9 +372,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[36m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_GREEN ); @@ -393,9 +388,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[37m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ); @@ -405,15 +400,143 @@ namespace termcolor } + inline + std::ostream& bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[90m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 | FOREGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[91m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[92m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[93m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[94m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[95m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[96m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[97m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + inline std::ostream& on_grey(std::ostream& stream) { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[40m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, 0 // grey (black) ); @@ -427,9 +550,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[41m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_RED ); @@ -443,9 +566,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[42m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN ); @@ -459,9 +582,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[43m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_RED ); @@ -475,9 +598,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[44m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_BLUE ); @@ -491,9 +614,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[45m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_BLUE | BACKGROUND_RED ); @@ -507,9 +630,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[46m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_BLUE ); @@ -523,9 +646,9 @@ namespace termcolor { if (_internal::is_colorized(stream)) { - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) stream << "\033[47m"; - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_USE_WINDOWS_API) _internal::win_change_attributes(stream, -1, BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED ); @@ -536,6 +659,136 @@ namespace termcolor } + inline + std::ostream& on_bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[100m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 | BACKGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[101m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[102m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[103m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[104m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[105m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[106m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[107m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + + return stream; + } + + //! Since C++ hasn't a way to hide something in the header from //! the outer access, I have to introduce this namespace which @@ -543,6 +796,17 @@ namespace termcolor //! the user code. namespace _internal { + // An index to be used to access a private storage of I/O streams. See + // colorize / nocolorize I/O manipulators for details. Due to the fact + // that static variables ain't shared between translation units, inline + // function with local static variable is used to do the trick and share + // the variable value between translation units. + inline int colorize_index() + { + static int colorize_index = std::ios_base::xalloc(); + return colorize_index; + } + //! 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. @@ -563,7 +827,7 @@ namespace termcolor inline bool is_colorized(std::ostream& stream) { - return is_atty(stream) || static_cast(stream.iword(colorize_index)); + return is_atty(stream) || static_cast(stream.iword(colorize_index())); } //! Test whether a given `std::ostream` object refers to @@ -580,14 +844,16 @@ namespace termcolor if (!std_stream) return false; - #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + #if defined(TERMCOLOR_TARGET_POSIX) return ::isatty(fileno(std_stream)); - #elif defined(TERMCOLOR_OS_WINDOWS) + #elif defined(TERMCOLOR_TARGET_WINDOWS) return ::_isatty(_fileno(std_stream)); + #else + return false; #endif } - #if defined(TERMCOLOR_OS_WINDOWS) + #if defined(TERMCOLOR_TARGET_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) @@ -644,16 +910,20 @@ namespace termcolor SetConsoleTextAttribute(hTerminal, info.wAttributes); } - #endif // TERMCOLOR_OS_WINDOWS + #endif // TERMCOLOR_TARGET_WINDOWS } // namespace _internal } // namespace termcolor -#undef TERMCOLOR_OS_WINDOWS -#undef TERMCOLOR_OS_MACOS -#undef TERMCOLOR_OS_LINUX +#undef TERMCOLOR_TARGET_POSIX +#undef TERMCOLOR_TARGET_WINDOWS + +#if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION) +# undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# undef TERMCOLOR_USE_WINDOWS_API +#endif #endif // TERMCOLOR_HPP_ @@ -729,8 +999,25 @@ SOFTWARE. #include // #include + + +namespace indicators { +enum class Color { grey, red, green, yellow, blue, magenta, cyan, white, unspecified }; +} + // #include + +namespace indicators { +enum class FontStyle { bold, dark, italic, underline, blink, reverse, concealed, crossed }; +} + // #include + + +namespace indicators { +enum class ProgressType { incremental, decremental }; +} + #include #include #include @@ -1317,34 +1604,1386 @@ static inline int display_width(const std::wstring &input) { } // namespace unicode // #include -// #include +/* +Activity Indicators for Modern C++ +https://github.com/p-ranav/indicators -#include -#include -#include -#include -#include -#include +Licensed under the MIT License . +SPDX-License-Identifier: MIT +Copyright (c) 2019 Dawid Pilarski . -#include -#include +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: -namespace indicators { -namespace details { +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -inline void set_stream_color(std::ostream &os, Color color) { - switch (color) { - case Color::grey: - os << termcolor::grey; - break; - case Color::red: - os << termcolor::red; - break; - case Color::green: - os << termcolor::green; - break; - case Color::yellow: - os << termcolor::yellow; +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. +*/ + + +#include +// #include +// #include +// #include +#include +#include +#include +#include +#include + +namespace indicators { + +namespace details { + +template struct if_else; + +template <> struct if_else { using type = std::true_type; }; + +template <> struct if_else { using type = std::false_type; }; + +template struct if_else_type; + +template struct if_else_type { + using type = True; +}; + +template struct if_else_type { + using type = False; +}; + +template struct conjuction; + +template <> struct conjuction<> : std::true_type {}; + +template +struct conjuction + : if_else_type>::type {}; + +template struct disjunction; + +template <> struct disjunction<> : std::false_type {}; + +template +struct disjunction + : if_else_type>::type {}; + +enum class ProgressBarOption { + bar_width = 0, + prefix_text, + postfix_text, + start, + end, + fill, + lead, + remainder, + max_postfix_text_len, + completed, + show_percentage, + show_elapsed_time, + show_remaining_time, + saved_start_time, + foreground_color, + spinner_show, + spinner_states, + font_styles, + hide_bar_when_complete, + min_progress, + max_progress, + progress_type, + stream +}; + +template struct Setting { + template ::value>::type> + explicit Setting(Args &&... args) : value(std::forward(args)...) {} + Setting(const Setting &) = default; + Setting(Setting &&) = default; + + static constexpr auto id = Id; + using type = T; + + T value{}; +}; + +template struct is_setting : std::false_type {}; + +template struct is_setting> : std::true_type {}; + +template +struct are_settings : if_else...>::value>::type {}; + +template <> struct are_settings<> : std::true_type {}; + +template struct is_setting_from_tuple; + +template struct is_setting_from_tuple> : std::true_type {}; + +template +struct is_setting_from_tuple> + : if_else...>::value>::type {}; + +template +struct are_settings_from_tuple + : if_else...>::value>::type {}; + +template struct always_true { static constexpr auto value = true; }; + +template Default &&get_impl(Default &&def) { + return std::forward(def); +} + +template +auto get_impl(Default && /*def*/, T &&first, Args &&... /*tail*/) -> + typename std::enable_if<(std::decay::type::id == Id), + decltype(std::forward(first))>::type { + return std::forward(first); +} + +template +auto get_impl(Default &&def, T && /*first*/, Args &&... tail) -> + typename std::enable_if<(std::decay::type::id != Id), + decltype(get_impl(std::forward(def), + std::forward(tail)...))>::type { + return get_impl(std::forward(def), std::forward(tail)...); +} + +template ::value, void>::type> +auto get(Default &&def, Args &&... args) + -> decltype(details::get_impl(std::forward(def), std::forward(args)...)) { + return details::get_impl(std::forward(def), std::forward(args)...); +} + +template using StringSetting = Setting; + +template using IntegerSetting = Setting; + +template using BooleanSetting = Setting; + +template struct option_idx; + +template +struct option_idx, counter> + : if_else_type<(Id == T::id), std::integral_constant, + option_idx, counter + 1>>::type {}; + +template struct option_idx, counter> { + static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found"); +}; + +template +auto get_value(Settings &&settings) + -> decltype((std::get::type>::value>( + std::declval()))) { + return std::get::type>::value>( + std::forward(settings)); +} + +} // namespace details + +namespace option { +using BarWidth = details::IntegerSetting; +using PrefixText = details::StringSetting; +using PostfixText = details::StringSetting; +using Start = details::StringSetting; +using End = details::StringSetting; +using Fill = details::StringSetting; +using Lead = details::StringSetting; +using Remainder = details::StringSetting; +using MaxPostfixTextLen = details::IntegerSetting; +using Completed = details::BooleanSetting; +using ShowPercentage = details::BooleanSetting; +using ShowElapsedTime = details::BooleanSetting; +using ShowRemainingTime = details::BooleanSetting; +using SavedStartTime = details::BooleanSetting; +using ForegroundColor = details::Setting; +using ShowSpinner = details::BooleanSetting; +using SpinnerStates = + details::Setting, details::ProgressBarOption::spinner_states>; +using HideBarWhenComplete = + details::BooleanSetting; +using FontStyles = + details::Setting, details::ProgressBarOption::font_styles>; +using MinProgress = details::IntegerSetting; +using MaxProgress = details::IntegerSetting; +using ProgressType = details::Setting; +using Stream = details::Setting; +} // namespace option +} // namespace indicators + +// #include //! +//! termcolor +//! ~~~~~~~~~ +//! +//! termcolor is a header-only c++ library for printing colored messages +//! to the terminal. Written just for fun with a help of the Force. +//! +//! :copyright: (c) 2013 by Ihor Kalnytskyi +//! :license: BSD, see LICENSE for details +//! + +#ifndef TERMCOLOR_HPP_ +#define TERMCOLOR_HPP_ + +#include +#include + +// Detect target's platform and set some macros in order to wrap platform +// specific code this library depends on. +#if defined(_WIN32) || defined(_WIN64) +# define TERMCOLOR_TARGET_WINDOWS +#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) +# define TERMCOLOR_TARGET_POSIX +#endif + +// If implementation has not been explicitly set, try to choose one based on +// target platform. +#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP) +# if defined(TERMCOLOR_TARGET_POSIX) +# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# elif defined(TERMCOLOR_TARGET_WINDOWS) +# define TERMCOLOR_USE_WINDOWS_API +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# endif +#endif + +// These headers provide isatty()/fileno() functions, which are used for +// testing whether a standard stream refers to the terminal. +#if defined(TERMCOLOR_TARGET_POSIX) +# include +#elif defined(TERMCOLOR_TARGET_WINDOWS) +# include +# include +#endif + + +namespace termcolor +{ + // Forward declaration of the `_internal` namespace. + // All comments are below. + namespace _internal + { + inline int colorize_index(); + inline FILE* get_standard_stream(const std::ostream& stream); + inline bool is_colorized(std::ostream& stream); + inline bool is_atty(const std::ostream& stream); + + #if defined(TERMCOLOR_TARGET_WINDOWS) + inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1); + #endif + } + + inline + std::ostream& colorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index()) = 1L; + return stream; + } + + inline + std::ostream& nocolorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index()) = 0L; + return stream; + } + + inline + std::ostream& reset(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[00m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, -1); + #endif + } + return stream; + } + + inline + std::ostream& bold(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[1m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& dark(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[2m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& italic(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[3m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& underline(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[4m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE); + #endif + } + return stream; + } + + inline + std::ostream& blink(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[5m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& reverse(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[7m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& concealed(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[8m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& crossed(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[9m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[12]; + std::snprintf(command, sizeof(command), "\033[38;5;%dm", code); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& on_color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[12]; + std::snprintf(command, sizeof(command), "\033[48;5;%dm", code); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[20]; + std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& on_color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[20]; + std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[30m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[31m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[32m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[33m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[34m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[35m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[36m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[37m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + ); + #endif + } + return stream; + } + + + inline + std::ostream& bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[90m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 | FOREGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[91m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[92m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[93m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[94m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[95m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[96m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[97m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + + inline + std::ostream& on_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[40m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[41m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[42m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& on_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[43m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[44m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& on_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[45m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _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_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[46m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& on_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[47m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED + ); + #endif + } + + return stream; + } + + + inline + std::ostream& on_bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[100m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 | BACKGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[101m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[102m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[103m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[104m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[105m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[106m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[107m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + + return stream; + } + + + + //! Since C++ hasn't a way to hide something in the header from + //! the outer access, I have to introduce this namespace which + //! is used for internal purpose and should't be access from + //! the user code. + namespace _internal + { + // An index to be used to access a private storage of I/O streams. See + // colorize / nocolorize I/O manipulators for details. Due to the fact + // that static variables ain't shared between translation units, inline + // function with local static variable is used to do the trick and share + // the variable value between translation units. + inline int colorize_index() + { + static int colorize_index = std::ios_base::xalloc(); + return colorize_index; + } + + //! 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; + + return nullptr; + } + + // Say whether a given stream should be colorized or not. It's always + // true for ATTY streams and may be true for streams marked with + // colorize flag. + inline + bool is_colorized(std::ostream& stream) + { + return is_atty(stream) || static_cast(stream.iword(colorize_index())); + } + + //! Test whether a given `std::ostream` object refers to + //! a terminal. + inline + bool is_atty(const std::ostream& stream) + { + FILE* std_stream = get_standard_stream(stream); + + // Unfortunately, fileno() ends with segmentation fault + // if invalid file descriptor is passed. So we need to + // 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; + + #if defined(TERMCOLOR_TARGET_POSIX) + return ::isatty(fileno(std_stream)); + #elif defined(TERMCOLOR_TARGET_WINDOWS) + return ::_isatty(_fileno(std_stream)); + #else + return false; + #endif + } + + #if defined(TERMCOLOR_TARGET_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(foreground); + } + + if (background != -1) + { + info.wAttributes &= ~(info.wAttributes & 0xF0); + info.wAttributes |= static_cast(background); + } + + SetConsoleTextAttribute(hTerminal, info.wAttributes); + } + #endif // TERMCOLOR_TARGET_WINDOWS + + } // namespace _internal + +} // namespace termcolor + + +#undef TERMCOLOR_TARGET_POSIX +#undef TERMCOLOR_TARGET_WINDOWS + +#if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION) +# undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# undef TERMCOLOR_USE_WINDOWS_API +#endif + +#endif // TERMCOLOR_HPP_ + + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace indicators { +namespace details { + +inline void set_stream_color(std::ostream &os, Color color) { + switch (color) { + case Color::grey: + os << termcolor::grey; + break; + case Color::red: + os << termcolor::red; + break; + case Color::green: + os << termcolor::green; + break; + case Color::yellow: + os << termcolor::yellow; + break; + case Color::blue: + os << termcolor::blue; + break; + case Color::magenta: + os << termcolor::magenta; + break; + case Color::cyan: + os << termcolor::cyan; + break; + case Color::white: + os << termcolor::white; + break; + default: + assert(false); + } +} + +inline void set_font_style(std::ostream &os, FontStyle style) { + switch (style) { + case FontStyle::bold: + os << termcolor::bold; + break; + case FontStyle::dark: + os << termcolor::dark; + break; + case FontStyle::italic: + os << termcolor::italic; + break; + case FontStyle::underline: + os << termcolor::underline; + break; + case FontStyle::blink: + os << termcolor::blink; + break; + case FontStyle::reverse: + os << termcolor::reverse; + break; + case FontStyle::concealed: + os << termcolor::concealed; + break; + case FontStyle::crossed: + os << termcolor::crossed; + break; + default: + break; + } +} + +inline std::ostream &write_duration(std::ostream &os, std::chrono::nanoseconds ns) { + using namespace std; + using namespace std::chrono; + using days = duration>; + char fill = os.fill(); + os.fill('0'); + auto d = duration_cast(ns); + ns -= d; + auto h = duration_cast(ns); + ns -= h; + auto m = duration_cast(ns); + ns -= m; + auto s = duration_cast(ns); + if (d.count() > 0) + os << setw(2) << d.count() << "d:"; + if (h.count() > 0) + os << setw(2) << h.count() << "h:"; + os << setw(2) << m.count() << "m:" << setw(2) << s.count() << 's'; + os.fill(fill); + return os; +} + +class BlockProgressScaleWriter { +public: + BlockProgressScaleWriter(std::ostream &os, size_t bar_width) : os(os), bar_width(bar_width) {} + + std::ostream &write(float progress) { + std::string fill_text{"█"}; + std::vector lead_characters{" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉"}; + auto value = std::min(1.0f, std::max(0.0f, progress / 100.0f)); + auto whole_width = std::floor(value * bar_width); + auto remainder_width = fmod((value * bar_width), 1.0f); + auto part_width = std::floor(remainder_width * lead_characters.size()); + std::string lead_text = lead_characters[size_t(part_width)]; + if ((bar_width - whole_width - 1) < 0) + lead_text = ""; + for (size_t i = 0; i < whole_width; ++i) + os << fill_text; + os << lead_text; + for (size_t i = 0; i < (bar_width - whole_width - 1); ++i) + os << " "; + return os; + } + +private: + std::ostream &os; + size_t bar_width = 0; +}; + +class ProgressScaleWriter { +public: + ProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill, + const std::string &lead, const std::string &remainder) + : os(os), bar_width(bar_width), fill(fill), lead(lead), remainder(remainder) {} + + std::ostream &write(float progress) { + auto pos = static_cast(progress * bar_width / 100.0); + for (size_t i = 0, current_display_width = 0; i < bar_width;) { + std::string next; + + if (i < pos) { + next = fill; + current_display_width = unicode::display_width(fill); + } else if (i == pos) { + next = lead; + current_display_width = unicode::display_width(lead); + } else { + next = remainder; + current_display_width = unicode::display_width(remainder); + } + + i += current_display_width; + + if (i > bar_width) { + // `next` is larger than the allowed bar width + // fill with empty space instead + os << std::string((bar_width - (i - current_display_width)), ' '); + break; + } + + os << next; + } + return os; + } + +private: + std::ostream &os; + size_t bar_width = 0; + std::string fill; + std::string lead; + std::string remainder; +}; + +class IndeterminateProgressScaleWriter { +public: + IndeterminateProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill, + const std::string &lead) + : os(os), bar_width(bar_width), fill(fill), lead(lead) {} + + std::ostream &write(size_t progress) { + for (size_t i = 0; i < bar_width;) { + std::string next; + size_t current_display_width = 0; + + if (i < progress) { + next = fill; + current_display_width = unicode::display_width(fill); + } else if (i == progress) { + next = lead; + current_display_width = unicode::display_width(lead); + } else { + next = fill; + current_display_width = unicode::display_width(fill); + } + + i += current_display_width; + + if (i > bar_width) { + // `next` is larger than the allowed bar width + // fill with empty space instead + os << std::string((bar_width - (i - current_display_width)), ' '); + break; + } + + os << next; + } + return os; + } + +private: + std::ostream &os; + size_t bar_width = 0; + std::string fill; + std::string lead; +}; + +} // namespace details +} // namespace indicators +#pragma once + +// #include + + +// #include +// #include +// #include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace indicators { +namespace details { + +inline void set_stream_color(std::ostream &os, Color color) { + switch (color) { + case Color::grey: + os << termcolor::grey; + break; + case Color::red: + os << termcolor::red; + break; + case Color::green: + os << termcolor::green; + break; + case Color::yellow: + os << termcolor::yellow; break; case Color::blue: os << termcolor::blue; @@ -1532,9 +3171,6 @@ class IndeterminateProgressScaleWriter { } // namespace details } // namespace indicators -#pragma once - -// #include #include #include @@ -1543,6 +3179,48 @@ class IndeterminateProgressScaleWriter { // #include // #include // #include + +#include + + +#if defined(_WIN32) +#include + +namespace indicators { + +static inline std::pair terminal_size() { + CONSOLE_SCREEN_BUFFER_INFO csbi; + int cols, rows; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + cols = csbi.srWindow.Right - csbi.srWindow.Left + 1; + rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + return {static_cast(rows), static_cast(cols)}; +} + +static inline size_t terminal_width() { return terminal_size().second; } + +} // namespace indicators + +#else + +#include //ioctl() and TIOCGWINSZ +#include // for STDOUT_FILENO + +namespace indicators { + +static inline std::pair terminal_size() { + struct winsize size{}; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &size); + return {static_cast(size.ws_row), static_cast(size.ws_col)}; +} + +static inline size_t terminal_width() { return terminal_size().second; } + +} // namespace indicators + +#endif + + #include #include #include @@ -2419,6 +4097,52 @@ class IndeterminateProgressBar { // #include // #include + + +#if defined(_MSC_VER) +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#include +#include +#else +#include +#endif + +namespace indicators { + +#ifdef _MSC_VER + +static inline void move(int x, int y) { + auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (!hStdout) + return; + + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo(hStdout, &csbiInfo); + + COORD cursor; + + cursor.X = csbiInfo.dwCursorPosition.X + x; + cursor.Y = csbiInfo.dwCursorPosition.Y + y; + SetConsoleCursorPosition(hStdout, cursor); +} + +static inline void move_up(int lines) { move(0, -lines); } +static inline void move_down(int lines) { move(0, -lines); } +static inline void move_right(int cols) { move(cols, 0); } +static inline void move_left(int cols) { move(-cols, 0); } + +#else + +static inline void move_up(int lines) { std::cout << "\033[" << lines << "A"; } +static inline void move_down(int lines) { std::cout << "\033[" << lines << "B"; } +static inline void move_right(int cols) { std::cout << "\033[" << cols << "C"; } +static inline void move_left(int cols) { std::cout << "\033[" << cols << "D"; } + +#endif + +} // namespace indicators // #include namespace indicators { diff --git a/utils/amalgamate/amalgamate.py b/utils/amalgamate/amalgamate.py index a3e3df5..f68b79d 100644 --- a/utils/amalgamate/amalgamate.py +++ b/utils/amalgamate/amalgamate.py @@ -62,7 +62,7 @@ def find_included_file(self, file_path, source_dir): return None def __init__(self, args): - with open(args.config, 'r') as f: + with open(args.config, 'r', encoding="utf8") as f: config = json.loads(f.read()) for key in config: setattr(self, key, config[key]) @@ -77,7 +77,7 @@ def generate(self): amalgamation = "" if self.prologue: - with open(self.prologue, 'r') as f: + with open(self.prologue, 'r', encoding="utf8") as f: amalgamation += datetime.datetime.now().strftime(f.read()) if self.verbose: @@ -94,7 +94,7 @@ def generate(self): t = TranslationUnit(file_path, self, True) amalgamation += t.content - with open(self.target, 'w') as f: + with open(self.target, 'w', encoding="utf8") as f: f.write(amalgamation) print("...done!\n") @@ -262,7 +262,7 @@ def __init__(self, file_path, amalgamation, is_root): actual_path = self.amalgamation.actual_path(file_path) if not os.path.isfile(actual_path): raise IOError("File not found: \"{0}\"".format(file_path)) - with open(actual_path, 'r') as f: + with open(actual_path, 'r', encoding="utf8") as f: self.content = f.read() self._process()