From 6c33fb4dcebd5464d89ca3fb98bdf23847d81fbf Mon Sep 17 00:00:00 2001 From: tastytea Date: Tue, 25 May 2021 10:43:32 +0200 Subject: [PATCH] Squashed 'dist/termcolor/' content from commit 9a832a1 git-subtree-dir: dist/termcolor git-subtree-split: 9a832a1756c67074331f257f3896656318440ba2 --- .gitignore | 3 + .mailmap | 1 + .travis.yml | 156 ++++ CMakeLists.txt | 55 ++ LICENSE | 31 + README.rst | 236 ++++++ cmake/config.cmake.in | 4 + docs/_static/example.png | Bin 0 -> 81639 bytes docs/conf.py | 36 + docs/index.rst | 11 + examples/cmake-external/CMakeLists.txt | 23 + examples/cmake-external/example.cpp | 10 + examples/cmake-fetch/CMakeLists.txt | 17 + examples/cmake-fetch/example.cpp | 10 + examples/cmake-package/CMakeLists.txt | 7 + examples/cmake-package/example.cpp | 10 + examples/cmake-submodule/CMakeLists.txt | 7 + examples/cmake-submodule/example.cpp | 10 + include/termcolor/termcolor.hpp | 911 ++++++++++++++++++++++++ test/test.cpp | 151 ++++ 20 files changed, 1689 insertions(+) create mode 100644 .gitignore create mode 100644 .mailmap create mode 100644 .travis.yml create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.rst create mode 100644 cmake/config.cmake.in create mode 100644 docs/_static/example.png create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 examples/cmake-external/CMakeLists.txt create mode 100644 examples/cmake-external/example.cpp create mode 100644 examples/cmake-fetch/CMakeLists.txt create mode 100644 examples/cmake-fetch/example.cpp create mode 100644 examples/cmake-package/CMakeLists.txt create mode 100644 examples/cmake-package/example.cpp create mode 100644 examples/cmake-submodule/CMakeLists.txt create mode 100644 examples/cmake-submodule/example.cpp create mode 100644 include/termcolor/termcolor.hpp create mode 100644 test/test.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b843012 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +build/ +docs/_build diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..ace13db --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ +Ihor Kalnytskyi diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6d5ec2d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,156 @@ +language: cpp + +script: + - eval "CXX=${COMPILER} CXXFLAGS=-std=c++11" + - cmake -DTERMCOLOR_TESTS=ON . + - cmake --build . + - ./test_termcolor + +jobs: + include: + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: g++-5 + env: COMPILER="g++-5" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: g++-6 + env: COMPILER="g++-6" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: g++-7 + env: COMPILER="g++-7" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-3.8 + packages: clang-3.8 + env: COMPILER="clang++-3.8" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-3.9 + packages: clang-3.9 + env: COMPILER="clang++-3.9" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-4.0 + packages: clang-4.0 + env: COMPILER="clang++-4.0" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-5.0 + packages: clang-5.0 + env: COMPILER="clang++-5.0" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-6.0 + packages: clang-6.0 + env: COMPILER="clang++-6.0" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-7 + packages: clang-7 + env: COMPILER="clang++-7" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-8 + packages: clang-8 + env: COMPILER="clang++-8" + + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main + key_url: https://apt.llvm.org/llvm-snapshot.gpg.key + packages: clang-9 + env: COMPILER="clang++-9" + + - os: osx + osx_image: xcode10 + + - os: osx + osx_image: xcode11 + + - os: windows + script: + - cmake -DTERMCOLOR_TESTS=ON . + - cmake --build . + - ./Debug/test_termcolor.exe + + - os: windows + script: + - cmake -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DTERMCOLOR_TESTS=ON -G "MinGW Makefiles" . + - cmake --build . + - ./test_termcolor + + - script: + - mkdir -p /tmp/termcolor && cd "$_" + - cmake $TRAVIS_BUILD_DIR + - sudo make install + + - mkdir -p /tmp/example && cd "$_" + - cmake $TRAVIS_BUILD_DIR/examples/cmake-package + - make && ./example + name: cmake package + + - script: + - sudo pip install cmake + - mkdir -p /tmp/example && cd "$_" + - /usr/local/bin/cmake $TRAVIS_BUILD_DIR/examples/cmake-fetch + - make && ./example + name: cmake fetch + + - script: + - mkdir -p /tmp/example && cd "$_" + - cmake $TRAVIS_BUILD_DIR/examples/cmake-submodule + - make && ./example + name: cmake submodule + + - script: + - mkdir -p /tmp/example && cd "$_" + - cmake $TRAVIS_BUILD_DIR/examples/cmake-external + - make && ./example + name: cmake external + +notifications: + email: false diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..905040f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.0) +project(termcolor) + +# +# target +# + +add_library(${PROJECT_NAME} INTERFACE) +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + +target_include_directories(${PROJECT_NAME} INTERFACE + $ + $) +target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_11) + +# +# tests +# + +option(TERMCOLOR_TESTS "Build termcolor tests." OFF) + +if(TERMCOLOR_TESTS) + add_executable(test_${PROJECT_NAME} test/test.cpp) + target_link_libraries( + test_${PROJECT_NAME} ${PROJECT_NAME}::${PROJECT_NAME}) +endif() + +# +# install +# + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + cmake/config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/generated/${PROJECT_NAME}-config.cmake + INSTALL_DESTINATION lib/cmake/${PROJECT_NAME}) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/${PROJECT_NAME}-config.cmake + DESTINATION lib/cmake/${PROJECT_NAME}) + +install( + DIRECTORY include/ + DESTINATION include) + +install( + TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}-targets + INCLUDES DESTINATION include) + +install( + EXPORT ${PROJECT_NAME}-targets + NAMESPACE ${PROJECT_NAME}:: + DESTINATION lib/cmake/${PROJECT_NAME}) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e2a9f53 --- /dev/null +++ b/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2013, Ihor Kalnytskyi. +All rights reserved. + +Redistribution and use in source and binary forms of the software as well +as documentation, with or without modification, are permitted provided +that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +* The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..2c62175 --- /dev/null +++ b/README.rst @@ -0,0 +1,236 @@ +Termcolor +========= + +.. image:: docs/_static/example.png + :alt: termcolor in action + :align: left + +.. -*- inclusion-marker-for-sphinx-docs -*- + +Termcolor_ is a header-only C++ library for printing colored messages to the +terminal. Written just for fun with a help of `the Force`_. Termcolor uses +`ANSI color formatting`_, so you can use it on every system that is used such +terminals (most \*nix systems, including Linux and Mac OS). + +.. note:: + + On Windows, `Windows API`_ is used instead of escape codes but some + limitations are applied (not everything is supported). That's why it's + recommended to enter `virtual terminal processing`_ mode and set + ``TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES`` macro to trick termcolor to use + ANSI color codes. + + .. _virtual terminal processing: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences + +It's licensed under the BSD (3-clause) License. That basically means: do +whatever you want as long as copyright sticks around. + +.. _Termcolor: https://github.com/ikalnytskyi/termcolor +.. _the Force: https://starwars.wikia.com/wiki/The_Force +.. _ANSI color formatting: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors +.. _Windows API: https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute + + +Installation +------------ + +* Add ``termcolor.hpp`` (grab it from ``include/termcolor/termcolor.hpp``) to + the project and use stream manipulators from the ``termcolor`` namespace. + +* You can also use vcpkg_ to install the library: + + .. code:: sh + + $ vcpkg install termcolor + + .. _vcpkg: https://github.com/microsoft/vcpkg + +* Or if you are on macOS, you can use Homebrew_ for that purpose: + + .. code:: sh + + $ brew install termcolor + + .. _Homebrew: https://brew.sh/ + +* For up-to-date information about existing packages, refer to the the following + picture: + + .. image:: https://repology.org/badge/vertical-allrepos/termcolor.svg + :target: https://repology.org/project/termcolor/versions + :alt: Packaging Status + + +How to use? +----------- + +It's very easy to use. The idea is built upon C++ stream manipulators. +Typical «Hello World» application looks like this: + +.. code:: c++ + + #include + #include + + int main(int /*argc*/, char** /*argv*/) + { + std::cout << termcolor::red << "Hello, "; // 16 colors + std::cout << termcolor::color<100> << "Colorful "; // 256 colors + std::cout << termcolor::color<211, 54, 130> << "World!"; // true colors + std::cout << std::endl; + return 0; + } + +The application above prints a string using different colors. There is one +caveat though. You must not forget to reset colors, otherwise they will be +applied to other prints as well. + +.. code:: c++ + + std::cout << termcolor::red << "Hello, Colorful World!" << std::endl; + std::cout << "I'm RED too!" << std::endl; + +Correct version of the code above should look like this: + +.. code:: c++ + + std::cout << termcolor::red << "Hello, Colorful World!" << termcolor::reset << std::endl; + std::cout << termcolor::reset << "Here I'm!" << std::endl; + +By default, Termcolor ignores any colors for non-tty streams (e.g. +``std::stringstream``), so the following snippet + +.. code:: c++ + + std::stringstream ss; + ss << termcolor::red << "unicorn"; + std::cout << ss.str(); + +will print «unicorn» using default color, not red. In order to change this +behaviour one can use ``termcolor::colorize`` manipulator that enforce colors +no matter what. + + +What manipulators are supported? +-------------------------------- + +The manipulators are divided into four groups: + +* *foreground*, which changes text color; +* *background*, which changes text background color; +* *attributes*, which changes some text style (bold, underline, etc); +* *control*, which changes termcolor's behaviour. + +Also, there are color manipulators for `16 colors`_, `256 colors`_ and +`true colors`_ palettes. + +.. note:: + + While ``termcolor`` supports true color, it's required for the terminal + emulator you use to run your software to support true color too. So please + ensure it's supported before filing an issue. + +.. _16 colors: https://en.wikipedia.org/wiki/Color_depth#4-bit_color +.. _256 colors: https://en.wikipedia.org/wiki/Color_depth#8-bit_color +.. _true colors: https://en.wikipedia.org/wiki/Color_depth#True_color_(24-bit) + + +Foreground manipulators +....................... + +16 colors +````````` + +#. ``termcolor::grey`` +#. ``termcolor::red`` +#. ``termcolor::green`` +#. ``termcolor::yellow`` +#. ``termcolor::blue`` +#. ``termcolor::magenta`` +#. ``termcolor::cyan`` +#. ``termcolor::white`` +#. ``termcolor::bright_grey`` +#. ``termcolor::bright_red`` +#. ``termcolor::bright_green`` +#. ``termcolor::bright_yellow`` +#. ``termcolor::bright_blue`` +#. ``termcolor::bright_magenta`` +#. ``termcolor::bright_cyan`` +#. ``termcolor::bright_white`` + +256 colors +`````````` + +#. ``termcolor::color<256_COLOR_CODE>`` + +true colors +``````````` + +#. ``termcolor::color`` + + +Background manipulators +....................... + +16 colors +````````` + +#. ``termcolor::on_grey`` +#. ``termcolor::on_red`` +#. ``termcolor::on_green`` +#. ``termcolor::on_yellow`` +#. ``termcolor::on_blue`` +#. ``termcolor::on_magenta`` +#. ``termcolor::on_cyan`` +#. ``termcolor::on_white`` +#. ``termcolor::on_bright_grey`` +#. ``termcolor::on_bright_red`` +#. ``termcolor::on_bright_green`` +#. ``termcolor::on_bright_yellow`` +#. ``termcolor::on_bright_blue`` +#. ``termcolor::on_bright_magenta`` +#. ``termcolor::on_bright_cyan`` +#. ``termcolor::on_bright_white`` + +256 colors +`````````` + +#. ``termcolor::on_color<256_COLOR_CODE>`` + + +true colors +``````````` + +#. ``termcolor::on_color`` + + +Attribute manipulators +...................... + +(Windows API does not support these manipulators except for ``underline``) + +#. ``termcolor::bold`` +#. ``termcolor::dark`` +#. ``termcolor::italic`` +#. ``termcolor::underline`` +#. ``termcolor::blink`` +#. ``termcolor::reverse`` +#. ``termcolor::concealed`` +#. ``termcolor::crossed`` + +Control manipulators +.................... + +(Windows API does not support these manipulators) + +#. ``termcolor::colorize`` +#. ``termcolor::nocolorize`` + + +Caveats +------- + +#. On Windows, due to internal usage of ````, global namespace could + be polluted with `min`/`max` macros. If such effect is desireable, please + consider using ``#define NOMINMAX`` before ``#include ``. + diff --git a/cmake/config.cmake.in b/cmake/config.cmake.in new file mode 100644 index 0000000..a3086e8 --- /dev/null +++ b/cmake/config.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@CMAKE_PROJECT_NAME@-targets.cmake") +check_required_components("@CMAKE_PROJECT_NAME@") diff --git a/docs/_static/example.png b/docs/_static/example.png new file mode 100644 index 0000000000000000000000000000000000000000..9643c696c281cd2cea3193c315f03b1ad55cb95a GIT binary patch literal 81639 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

0#iI7 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 Ai~s-t literal 0 HcmV?d00001 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..2b3167f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +""" +termcolor's documentation settings +""" +from __future__ import unicode_literals + +import os + + +# project information +project = 'termcolor' +copyright = '2013, Ihor Kalnytskyi' +version = '0.1' +release = '0.1' + +# sphinx settings +extensions = [] +templates_path = ['_templates'] +source_suffix = '.rst' +master_doc = 'index' +exclude_patterns = ['_build'] +pygments_style = 'sphinx' +highlight_language = 'c++' + +# html output settings +html_theme = 'default' +html_static_path = ['_static'] + +# Unfortunately, Sphinx doesn't support code highlighting for standard +# reStructuredText `code` directive. So let's register 'code' directive +# as alias for Sphinx's own implementation. +# +# https://github.com/sphinx-doc/sphinx/issues/2155 +from docutils.parsers.rst import directives +from sphinx.directives.code import CodeBlock +directives.register_directive('code', CodeBlock) diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..7664f61 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,11 @@ +:orphan: + +Welcome to Termcolor C++ library +================================ + +.. image:: _static/example.png + :alt: termcolor in action + :align: center + +.. include:: ../README.rst + :start-after: -*- inclusion-marker-for-sphinx-docs -*- diff --git a/examples/cmake-external/CMakeLists.txt b/examples/cmake-external/CMakeLists.txt new file mode 100644 index 0000000..525b2a8 --- /dev/null +++ b/examples/cmake-external/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.0) +project(example) + +include(ExternalProject) + +ExternalProject_Add(termcolor_project + GIT_REPOSITORY git://github.com/ikalnytskyi/termcolor.git + GIT_TAG origin/master + + # Termcolor is a header-only library which means we need to + # neither configure nor build nor install it. Thus, noop + # the hooks. + CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "") +ExternalProject_Get_Property(termcolor_project SOURCE_DIR) + +set(CMAKE_CXX_STANDARD 11) + +include_directories(${SOURCE_DIR}/include) +add_library(termcolor INTERFACE IMPORTED) +add_dependencies(termcolor termcolor_project) + +add_executable(${CMAKE_PROJECT_NAME} example.cpp) +target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor) diff --git a/examples/cmake-external/example.cpp b/examples/cmake-external/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/examples/cmake-external/example.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main(int /* argc */, char** /* argv */) { + std::cout + << termcolor::yellow << "Warm welcome to " + << termcolor::blue << termcolor::underline << "TERMCOLOR" + << termcolor::reset << std::endl; + return 0; +} diff --git a/examples/cmake-fetch/CMakeLists.txt b/examples/cmake-fetch/CMakeLists.txt new file mode 100644 index 0000000..545184f --- /dev/null +++ b/examples/cmake-fetch/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.11) +project(example) + +include(FetchContent) + +FetchContent_Declare(termcolor + GIT_REPOSITORY git://github.com/ikalnytskyi/termcolor.git + GIT_TAG origin/master) +FetchContent_GetProperties(termcolor) + +if(NOT termcolor_POPULATED) + FetchContent_Populate(termcolor) + add_subdirectory(${termcolor_SOURCE_DIR} ${termcolor_BINARY_DIR} EXCLUDE_FROM_ALL) +endif() + +add_executable(${CMAKE_PROJECT_NAME} example.cpp) +target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor) diff --git a/examples/cmake-fetch/example.cpp b/examples/cmake-fetch/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/examples/cmake-fetch/example.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main(int /* argc */, char** /* argv */) { + std::cout + << termcolor::yellow << "Warm welcome to " + << termcolor::blue << termcolor::underline << "TERMCOLOR" + << termcolor::reset << std::endl; + return 0; +} diff --git a/examples/cmake-package/CMakeLists.txt b/examples/cmake-package/CMakeLists.txt new file mode 100644 index 0000000..3f78a57 --- /dev/null +++ b/examples/cmake-package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.0) +project(example) + +find_package(termcolor REQUIRED) + +add_executable(${CMAKE_PROJECT_NAME} example.cpp) +target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor::termcolor) diff --git a/examples/cmake-package/example.cpp b/examples/cmake-package/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/examples/cmake-package/example.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main(int /* argc */, char** /* argv */) { + std::cout + << termcolor::yellow << "Warm welcome to " + << termcolor::blue << termcolor::underline << "TERMCOLOR" + << termcolor::reset << std::endl; + return 0; +} diff --git a/examples/cmake-submodule/CMakeLists.txt b/examples/cmake-submodule/CMakeLists.txt new file mode 100644 index 0000000..5673372 --- /dev/null +++ b/examples/cmake-submodule/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.0) +project(example) + +add_subdirectory(../.. ${CMAKE_CURRENT_BINARY_DIR}/termcolor EXCLUDE_FROM_ALL) + +add_executable(${CMAKE_PROJECT_NAME} example.cpp) +target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE termcolor::termcolor) diff --git a/examples/cmake-submodule/example.cpp b/examples/cmake-submodule/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/examples/cmake-submodule/example.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main(int /* argc */, char** /* argv */) { + std::cout + << termcolor::yellow << "Warm welcome to " + << termcolor::blue << termcolor::underline << "TERMCOLOR" + << termcolor::reset << std::endl; + return 0; +} diff --git a/include/termcolor/termcolor.hpp b/include/termcolor/termcolor.hpp new file mode 100644 index 0000000..ca684ef --- /dev/null +++ b/include/termcolor/termcolor.hpp @@ -0,0 +1,911 @@ +//! +//! 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_ diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 0000000..8d9bc30 --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,151 @@ +//! +//! termcolor's test +//! ~~~~~~~~~~~~~~~~ +//! +//! A simple file which used all the termcolor featured. +//! It isn't a usual automated test, it's an unsual visual test! :D +//! +//! :copyright: (c) 2013 by Ihor Kalnytskyi +//! :license: BSD, see LICENSE for details +//! + +#if defined(_WIN32) || defined(_WIN64) +# define NO_ANSI_ESCAPE_SEQUENCES +#endif + +// Cygwin's C++ libraries seem to be stricter than other unix platforms. +// Strict standard conformance must be disabled by passing -U__STRICT_ANSI__ +// (or equivalent option) to the compiler, or by #undef __STRICT_ANSI__ +// before including this header file, , or before any other header +// that includes in the inclusion chain whithin the compilation +// unit that includes "termcolor.hpp". Or by enabling compiler extensions, +// such as issuing -std=gnu11++ GNU compiler option. +// +// This is required in order to `fileno()` is seen whithin "termcolor.hpp" +// scope. Note that other unix-like platforms could enforce strict standard +// conformance in the future and will require a similar workaround. +#if defined(__CYGWIN__) +# undef __STRICT_ANSI__ +# include +# include +# define __STRICT_ANSI__ +#else +# include +# include +#endif +#include "termcolor/termcolor.hpp" + +using namespace termcolor; + + +int main(int /*argc*/, char** /*argv*/) +{ + // test truecolors + std::cout << color<181, 137, 0> << "#b58900" << reset << std::endl; + std::cout << on_color<211, 54, 130> << "#d33682" << reset << std::endl; + std::cout << std::endl; + + // test 256 colors + std::cout << color<123> << "No. 123" << reset << std::endl; + std::cout << on_color<234> << "No. 234" << reset << std::endl; + std::cout << std::endl; + + // test foreground colors + std::cout << grey << "grey message" << reset << std::endl; + std::cout << red << "red message" << reset << std::endl; + std::cout << green << "green message" << reset << std::endl; + std::cout << yellow << "yellow message" << reset << std::endl; + std::cout << blue << "blue message" << reset << std::endl; + std::cout << magenta << "magenta message" << reset << std::endl; + std::cout << cyan << "cyan message" << reset << std::endl; + std::cout << white << "white message" << reset << std::endl; + std::cout << "default message" << std::endl; + std::cout << std::endl; + + // test bright foreground colors + std::cout << bright_grey << "bright grey message" << reset << std::endl; + std::cout << bright_red << "bright red message" << reset << std::endl; + std::cout << bright_green << "bright green message" << reset << std::endl; + std::cout << bright_yellow << "bright yellow message" << reset << std::endl; + std::cout << bright_blue << "bright blue message" << reset << std::endl; + std::cout << bright_magenta << "bright magenta message" << reset << std::endl; + std::cout << bright_cyan << "bright cyan message" << reset << std::endl; + std::cout << bright_white << "bright white message" << reset << std::endl; + std::cout << "default message" << std::endl; + std::cout << std::endl; + + + // test background colors + std::cout << on_grey << "message on grey" << reset << std::endl; + std::cout << on_red << "message on red" << reset << std::endl; + std::cout << on_green << "message on green" << reset << std::endl; + std::cout << on_yellow << "message on yellow" << reset << std::endl; + std::cout << on_blue << "message on blue" << reset << std::endl; + std::cout << on_magenta << "message on magenta" << reset << std::endl; + std::cout << on_cyan << "message on cyan" << reset << std::endl; + std::cout << on_white << "message on white" << reset << std::endl; + std::cout << "default message" << std::endl; + std::cout << std::endl; + + // test bright background colors + std::cout << on_bright_grey << "message on bright grey" << reset << std::endl; + std::cout << on_bright_red << "message on bright red" << reset << std::endl; + std::cout << on_bright_green << "message on bright green" << reset << std::endl; + std::cout << on_bright_yellow << "message on bright yellow" << reset << std::endl; + std::cout << on_bright_blue << "message on bright blue" << reset << std::endl; + std::cout << on_bright_magenta << "message on bright magenta" << reset << std::endl; + std::cout << on_bright_cyan << "message on bright cyan" << reset << std::endl; + std::cout << on_bright_white << "message on bright white" << reset << std::endl; + std::cout << "default message" << std::endl; + std::cout << std::endl; + + // test foreground and backgrounds colors + std::cout << red << on_white << "red on white" << reset << std::endl; + std::cout << blue << on_yellow << "blue on yellow" << reset << std::endl; + std::cout << std::endl; + + // test bright foreground or bright background colors + std::cout << bright_red << on_white << "bright red on white" << reset << std::endl; + std::cout << blue << on_bright_yellow << "blue on bright yellow" << reset << std::endl; + std::cout << std::endl; + + // test bright foreground and bright background colors + std::cout << bright_red << on_bright_white << "bright red on bright white" << reset << std::endl; + std::cout << bright_blue << on_bright_yellow << "bright blue on bright yellow" << reset << std::endl; + std::cout << std::endl; + + // test unsual attributes + std::cout << bold << red << "bold red message" << reset << std::endl; + std::cout << dark << blue << "dark blue message" << reset << std::endl; + std::cout << italic << "italic message" << reset << std::endl; + std::cout << underline << "underlined message" << reset << std::endl; + std::cout << blink << "blinked message" << reset << std::endl; + std::cout << reverse << "reversed message" << reset << std::endl; + std::cout << concealed << "concealed message" << reset << std::endl; + std::cout << crossed << "crossed message" << reset << std::endl; + std::cout << "default message" << std::endl; + std::cout << std::endl; + + // test clog/cerr streams + std::clog << "formatted " << yellow << "std::clog" << reset << " message" << std::endl; + std::cerr << "formatted " << red << "std::cerr" << reset << " message" << std::endl; + std::cout << std::endl; + + // test ansi escape characters are skipped for streams + std::stringstream s1; + s1 << red << "term" << blue << on_yellow << "color"; + + if (s1.str() != "termcolor") + return 1; + +#ifndef NO_ANSI_ESCAPE_SEQUENCES + // test ansi escape characters are preserved for streams if asked + std::stringstream s2; + s2 << colorize << red << "term" << nocolorize << blue << "color"; + + if (s2.str() != "\033[31m" "termcolor") + return 2; +#endif // NO_ANSI_ESCAPE_SEQUENCES + + return 0; +}