diff --git a/dist/termcolor/.gitignore b/dist/termcolor/.gitignore new file mode 100644 index 0000000..b843012 --- /dev/null +++ b/dist/termcolor/.gitignore @@ -0,0 +1,3 @@ +*.o +build/ +docs/_build diff --git a/dist/termcolor/.mailmap b/dist/termcolor/.mailmap new file mode 100644 index 0000000..ace13db --- /dev/null +++ b/dist/termcolor/.mailmap @@ -0,0 +1 @@ +Ihor Kalnytskyi diff --git a/dist/termcolor/.travis.yml b/dist/termcolor/.travis.yml new file mode 100644 index 0000000..6d5ec2d --- /dev/null +++ b/dist/termcolor/.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/dist/termcolor/CMakeLists.txt b/dist/termcolor/CMakeLists.txt new file mode 100644 index 0000000..905040f --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/LICENSE b/dist/termcolor/LICENSE new file mode 100644 index 0000000..e2a9f53 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/README.rst b/dist/termcolor/README.rst new file mode 100644 index 0000000..2c62175 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/cmake/config.cmake.in b/dist/termcolor/cmake/config.cmake.in new file mode 100644 index 0000000..a3086e8 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/docs/_static/example.png b/dist/termcolor/docs/_static/example.png new file mode 100644 index 0000000..9643c69 Binary files /dev/null and b/dist/termcolor/docs/_static/example.png differ diff --git a/dist/termcolor/docs/conf.py b/dist/termcolor/docs/conf.py new file mode 100644 index 0000000..2b3167f --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/docs/index.rst b/dist/termcolor/docs/index.rst new file mode 100644 index 0000000..7664f61 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-external/CMakeLists.txt b/dist/termcolor/examples/cmake-external/CMakeLists.txt new file mode 100644 index 0000000..525b2a8 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-external/example.cpp b/dist/termcolor/examples/cmake-external/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-fetch/CMakeLists.txt b/dist/termcolor/examples/cmake-fetch/CMakeLists.txt new file mode 100644 index 0000000..545184f --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-fetch/example.cpp b/dist/termcolor/examples/cmake-fetch/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-package/CMakeLists.txt b/dist/termcolor/examples/cmake-package/CMakeLists.txt new file mode 100644 index 0000000..3f78a57 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-package/example.cpp b/dist/termcolor/examples/cmake-package/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-submodule/CMakeLists.txt b/dist/termcolor/examples/cmake-submodule/CMakeLists.txt new file mode 100644 index 0000000..5673372 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/examples/cmake-submodule/example.cpp b/dist/termcolor/examples/cmake-submodule/example.cpp new file mode 100644 index 0000000..65ee2a3 --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/include/termcolor/termcolor.hpp b/dist/termcolor/include/termcolor/termcolor.hpp new file mode 100644 index 0000000..ca684ef --- /dev/null +++ b/dist/termcolor/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/dist/termcolor/test/test.cpp b/dist/termcolor/test/test.cpp new file mode 100644 index 0000000..8d9bc30 --- /dev/null +++ b/dist/termcolor/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; +}