diff --git a/include/catch_runner.hpp b/include/catch_runner.hpp index 0f768773..8f18267a 100644 --- a/include/catch_runner.hpp +++ b/include/catch_runner.hpp @@ -26,7 +26,7 @@ namespace Catch { : m_configWrapper( configWrapper ), m_config( configWrapper.data() ) { - resolveStream(); + openStream(); makeReporter(); } @@ -78,13 +78,10 @@ namespace Catch { } private: - void resolveStream() { - if( !m_config.stream.empty() ) { - if( m_config.stream[0] == '%' ) - m_configWrapper.useStream( m_config.stream.substr( 1 ) ); - else - m_configWrapper.setFilename( m_config.stream ); - } + void openStream() { + if( !m_config.stream.empty() ) + m_configWrapper.useStream( m_config.stream ); + // Open output file, if specified if( !m_config.outputFilename.empty() ) { m_ofs.open( m_config.outputFilename.c_str() ); diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp index ca6c4eb2..cc1248b4 100644 --- a/include/internal/catch_config.hpp +++ b/include/internal/catch_config.hpp @@ -11,6 +11,7 @@ #include "catch_test_spec.h" #include "catch_context.h" #include "catch_interfaces_config.h" +#include "catch_stream.hpp" #include #include @@ -79,19 +80,17 @@ namespace Catch { public: Config() - : m_streambuf( NULL ), - m_os( std::cout.rdbuf() ) + : m_os( std::cout.rdbuf() ) {} Config( const ConfigData& data ) : m_data( data ), - m_streambuf( NULL ), m_os( std::cout.rdbuf() ) {} virtual ~Config() { m_os.rdbuf( std::cout.rdbuf() ); - delete m_streambuf; + m_stream.release(); } void setFilename( const std::string& filename ) { @@ -131,10 +130,10 @@ namespace Catch { } void useStream( const std::string& streamName ) { - std::streambuf* newBuf = createStreamBuf( streamName ); - setStreamBuf( newBuf ); - delete m_streambuf; - m_streambuf = newBuf; + Stream stream = createStream( streamName ); + setStreamBuf( stream.streamBuf ); + m_stream.release(); + m_stream = stream; } void addTestSpec( const std::string& testSpec ) { @@ -166,7 +165,7 @@ namespace Catch { ConfigData m_data; // !TBD Move these out of here - std::streambuf* m_streambuf; + Stream m_stream; mutable std::ostream m_os; }; diff --git a/include/internal/catch_context.h b/include/internal/catch_context.h index 7ddd1f53..62b867ef 100644 --- a/include/internal/catch_context.h +++ b/include/internal/catch_context.h @@ -17,6 +17,7 @@ namespace Catch { class TestCaseInfo; + class Stream; struct IResultCapture; struct IRunner; struct IGeneratorsForTest; @@ -49,7 +50,7 @@ namespace Catch { IContext& getCurrentContext(); IMutableContext& getCurrentMutableContext(); void cleanUpContext(); - std::streambuf* createStreamBuf( const std::string& streamName ); + Stream createStream( const std::string& streamName ); } diff --git a/include/internal/catch_context_impl.hpp b/include/internal/catch_context_impl.hpp index 0121d4e7..a2210eaf 100644 --- a/include/internal/catch_context_impl.hpp +++ b/include/internal/catch_context_impl.hpp @@ -92,10 +92,10 @@ namespace Catch { return getCurrentMutableContext(); } - std::streambuf* createStreamBuf( const std::string& streamName ) { - if( streamName == "stdout" ) return std::cout.rdbuf(); - if( streamName == "stderr" ) return std::cerr.rdbuf(); - if( streamName == "debug" ) return new StreamBufImpl; + Stream createStream( const std::string& streamName ) { + if( streamName == "stdout" ) return Stream( std::cout.rdbuf(), false ); + if( streamName == "stderr" ) return Stream( std::cerr.rdbuf(), false ); + if( streamName == "debug" ) return Stream( new StreamBufImpl, true ); throw std::domain_error( "Unknown stream: " + streamName ); } diff --git a/include/internal/catch_stream.hpp b/include/internal/catch_stream.hpp index 653713a3..ee0890b8 100644 --- a/include/internal/catch_stream.hpp +++ b/include/internal/catch_stream.hpp @@ -58,6 +58,30 @@ namespace Catch { writeToDebugConsole( str ); } }; + + class Stream { + public: + Stream() + : streamBuf( NULL ), isOwned( false ) + {} + + Stream( std::streambuf* _streamBuf, bool _isOwned ) + : streamBuf( _streamBuf ), isOwned( _isOwned ) + {} + + void release() { + if( isOwned ) { + delete streamBuf; + streamBuf = NULL; + isOwned = false; + } + } + + std::streambuf* streamBuf; + + private: + bool isOwned; + }; } #endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED