Refactored colour handling

* POSIX colour impl is now compiled for all platforms.
* Deciding whether a colour impl should be picked is now stream
  dependent, and thus incompatible implementations can be removed
  immediately, rather than checking when the colour is being used.
This commit is contained in:
Martin Hořeňovský 2022-03-14 15:04:55 +01:00
parent c1c72c7e05
commit 0e176c318b
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
2 changed files with 33 additions and 25 deletions

View File

@ -93,16 +93,15 @@ namespace {
originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
} }
static bool useColourOnPlatform() { return true; } static bool useColourOnPlatform(IStream const& stream) {
// Win32 text colour APIs can only be used on console streams
// We cannot check that the output hasn't been redirected,
// so we just check that the original stream is console stream.
return stream.isStdout();
}
private: private:
void use( Colour::Code _colourCode ) const override { void use( Colour::Code _colourCode ) const override {
// Early exit if we are not writing to the console, because
// Win32 API can only change colour of the console.
if ( !m_stream->isStdout() ) {
return;
}
switch( _colourCode ) { switch( _colourCode ) {
case Colour::None: return setTextAttribute( originalForegroundAttributes ); case Colour::None: return setTextAttribute( originalForegroundAttributes );
case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
@ -138,9 +137,13 @@ namespace {
} // end anon namespace } // end anon namespace
} // end namespace Catch } // end namespace Catch
#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// #endif // Windows/ ANSI/ None
#include <unistd.h>
#if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC )
# define CATCH_INTERNAL_HAS_ISATTY
# include <unistd.h>
#endif
namespace Catch { namespace Catch {
namespace { namespace {
@ -153,18 +156,25 @@ namespace {
public: public:
PosixColourImpl( IStream const* stream ): ColourImpl( stream ) {} PosixColourImpl( IStream const* stream ): ColourImpl( stream ) {}
static bool useColourOnPlatform() { static bool useColourOnPlatform(IStream const& stream) {
// This is kinda messy due to trying to support a bunch of
// different platforms at once.
// The basic idea is that if we are asked to do autodetection (as
// opposed to being told to use posixy colours outright), then we
// only want to use the colours if we are writing to console.
// However, console might be redirected, so we make an attempt at
// checking for that on platforms where we know how to do that.
bool useColour = stream.isStdout();
#if defined( CATCH_INTERNAL_HAS_ISATTY ) && \
!( defined( __DJGPP__ ) && defined( __STRICT_ANSI__ ) )
ErrnoGuard _; // for isatty ErrnoGuard _; // for isatty
return useColour = useColour && isatty( STDOUT_FILENO );
# endif
# if defined( CATCH_PLATFORM_MAC ) || defined( CATCH_PLATFORM_IPHONE ) # if defined( CATCH_PLATFORM_MAC ) || defined( CATCH_PLATFORM_IPHONE )
!isDebuggerActive() && useColour = useColour && !isDebuggerActive();
# endif # endif
# if !( defined( __DJGPP__ ) && defined( __STRICT_ANSI__ ) )
isatty( STDOUT_FILENO ) return useColour;
# else
false
# endif
;
} }
private: private:
@ -201,8 +211,6 @@ namespace {
} // end anon namespace } // end anon namespace
} // end namespace Catch } // end namespace Catch
#endif // Windows/ ANSI/ None
namespace Catch { namespace Catch {
Detail::unique_ptr<ColourImpl> makeColourImpl(IConfig const* config, IStream const* stream) { Detail::unique_ptr<ColourImpl> makeColourImpl(IConfig const* config, IStream const* stream) {
@ -220,11 +228,11 @@ namespace Catch {
if ( colourMode == UseColour::Auto ) { if ( colourMode == UseColour::Auto ) {
createPlatformInstance = createPlatformInstance =
#if defined( CATCH_CONFIG_COLOUR_ANSI ) #if defined( CATCH_CONFIG_COLOUR_ANSI )
PosixColourImpl::useColourOnPlatform() PosixColourImpl::useColourOnPlatform( *stream )
#elif defined( CATCH_CONFIG_COLOUR_WINDOWS ) #elif defined( CATCH_CONFIG_COLOUR_WINDOWS )
Win32ColourImpl::useColourOnPlatform() Win32ColourImpl::useColourOnPlatform( *stream )
#else #else
NoColourImpl::useColourOnPlatform() false
#endif #endif
; ;
} }

View File

@ -661,8 +661,8 @@ void ConsoleReporter::printSummaryRow(StringRef label, std::vector<SummaryColumn
<< "- none -"; << "- none -";
} }
} else if (value != "0") { } else if (value != "0") {
m_stream << m_colour->startColour( Colour::LightGrey ) << " | " m_stream << m_colour->startColour( Colour::LightGrey ) << " | ";
<< m_colour->startColour( col.colour ) << value << ' ' m_stream << m_colour->startColour( col.colour ) << value << ' '
<< col.label; << col.label;
} }
} }