| /* |
| * Created by Phil on 25/2/2012. |
| * Copyright 2012 Two Blue Cubes Ltd. All rights reserved. |
| * |
| * Distributed under the Boost Software License, Version 1.0. (See accompanying |
| * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| */ |
| #ifndef TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED |
| #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED |
| |
| #include "catch_console_colour.hpp" |
| |
| namespace Catch { |
| namespace { |
| |
| struct IColourImpl { |
| virtual ~IColourImpl() {} |
| virtual void use( Colour::Code _colourCode ) = 0; |
| }; |
| |
| struct NoColourImpl : IColourImpl { |
| void use( Colour::Code ) {} |
| |
| static IColourImpl* instance() { |
| static NoColourImpl s_instance; |
| return &s_instance; |
| } |
| }; |
| |
| } // anon namespace |
| } // namespace Catch |
| |
| #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) |
| # ifdef CATCH_PLATFORM_WINDOWS |
| # define CATCH_CONFIG_COLOUR_WINDOWS |
| # else |
| # define CATCH_CONFIG_COLOUR_ANSI |
| # endif |
| #endif |
| |
| |
| #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// |
| |
| #ifndef NOMINMAX |
| #define NOMINMAX |
| #endif |
| |
| #ifdef __AFXDLL |
| #include <AfxWin.h> |
| #else |
| #include <windows.h> |
| #endif |
| |
| namespace Catch { |
| namespace { |
| |
| class Win32ColourImpl : public IColourImpl { |
| public: |
| Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) |
| { |
| CONSOLE_SCREEN_BUFFER_INFO csbiInfo; |
| GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); |
| originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); |
| originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); |
| } |
| |
| virtual void use( Colour::Code _colourCode ) { |
| switch( _colourCode ) { |
| case Colour::None: return setTextAttribute( originalForegroundAttributes ); |
| case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); |
| case Colour::Red: return setTextAttribute( FOREGROUND_RED ); |
| case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); |
| case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); |
| case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); |
| case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); |
| case Colour::Grey: return setTextAttribute( 0 ); |
| |
| case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); |
| case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); |
| case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); |
| case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); |
| |
| case Colour::Bright: throw std::logic_error( "not a colour" ); |
| } |
| } |
| |
| private: |
| void setTextAttribute( WORD _textAttribute ) { |
| SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); |
| } |
| HANDLE stdoutHandle; |
| WORD originalForegroundAttributes; |
| WORD originalBackgroundAttributes; |
| }; |
| |
| IColourImpl* platformColourInstance() { |
| static Win32ColourImpl s_instance; |
| |
| Ptr<IConfig const> config = getCurrentContext().getConfig(); |
| UseColour::YesOrNo colourMode = config |
| ? config->useColour() |
| : UseColour::Auto; |
| if( colourMode == UseColour::Auto ) |
| colourMode = !isDebuggerActive() |
| ? UseColour::Yes |
| : UseColour::No; |
| return colourMode == UseColour::Yes |
| ? &s_instance |
| : NoColourImpl::instance(); |
| } |
| |
| } // end anon namespace |
| } // end namespace Catch |
| |
| #elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// |
| |
| #include <unistd.h> |
| |
| namespace Catch { |
| namespace { |
| |
| // use POSIX/ ANSI console terminal codes |
| // Thanks to Adam Strzelecki for original contribution |
| // (http://github.com/nanoant) |
| // https://github.com/philsquared/Catch/pull/131 |
| class PosixColourImpl : public IColourImpl { |
| public: |
| virtual void use( Colour::Code _colourCode ) { |
| switch( _colourCode ) { |
| case Colour::None: |
| case Colour::White: return setColour( "[0m" ); |
| case Colour::Red: return setColour( "[0;31m" ); |
| case Colour::Green: return setColour( "[0;32m" ); |
| case Colour::Blue: return setColour( "[0:34m" ); |
| case Colour::Cyan: return setColour( "[0;36m" ); |
| case Colour::Yellow: return setColour( "[0;33m" ); |
| case Colour::Grey: return setColour( "[1;30m" ); |
| |
| case Colour::LightGrey: return setColour( "[0;37m" ); |
| case Colour::BrightRed: return setColour( "[1;31m" ); |
| case Colour::BrightGreen: return setColour( "[1;32m" ); |
| case Colour::BrightWhite: return setColour( "[1;37m" ); |
| |
| case Colour::Bright: throw std::logic_error( "not a colour" ); |
| } |
| } |
| static IColourImpl* instance() { |
| static PosixColourImpl s_instance; |
| return &s_instance; |
| } |
| |
| private: |
| void setColour( const char* _escapeCode ) { |
| Catch::cout() << '\033' << _escapeCode; |
| } |
| }; |
| |
| IColourImpl* platformColourInstance() { |
| Ptr<IConfig const> config = getCurrentContext().getConfig(); |
| UseColour::YesOrNo colourMode = config |
| ? config->useColour() |
| : UseColour::Auto; |
| if( colourMode == UseColour::Auto ) |
| colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) |
| ? UseColour::Yes |
| : UseColour::No; |
| return colourMode == UseColour::Yes |
| ? PosixColourImpl::instance() |
| : NoColourImpl::instance(); |
| } |
| |
| } // end anon namespace |
| } // end namespace Catch |
| |
| #else // not Windows or ANSI /////////////////////////////////////////////// |
| |
| namespace Catch { |
| |
| static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } |
| |
| } // end namespace Catch |
| |
| #endif // Windows/ ANSI/ None |
| |
| namespace Catch { |
| |
| Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } |
| Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; } |
| Colour::~Colour(){ if( !m_moved ) use( None ); } |
| |
| void Colour::use( Code _colourCode ) { |
| static IColourImpl* impl = platformColourInstance(); |
| impl->use( _colourCode ); |
| } |
| |
| } // end namespace Catch |
| |
| #endif // TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED |