mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Capture std::clog writes and combine them with std::cerr writes (#989)
This also introduces Catch::clog() method to allow embedded targets to override std::clog usage with their own stream (presumably null-sink), similarly to how Catch::cout() and Catch::cerr() are used. Fixes #989
This commit is contained in:
		| @@ -22,6 +22,7 @@ | ||||
| #include "catch_result_builder.h" | ||||
| #include "catch_fatal_condition.hpp" | ||||
|  | ||||
|  | ||||
| #include <set> | ||||
| #include <string> | ||||
|  | ||||
| @@ -50,6 +51,29 @@ namespace Catch { | ||||
|         std::string& m_targetString; | ||||
|     }; | ||||
|  | ||||
|     // StdErr has two constituent streams in C++, std::cerr and std::clog | ||||
|     // This means that we need to redirect 2 streams into 1 to keep proper | ||||
|     // order of writes and cannot use StreamRedirect on its own | ||||
|     class StdErrRedirect { | ||||
|     public: | ||||
|         StdErrRedirect(std::string& targetString) | ||||
|         :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()), | ||||
|         m_targetString(targetString){ | ||||
|             cerr().rdbuf(m_oss.rdbuf()); | ||||
|             clog().rdbuf(m_oss.rdbuf()); | ||||
|         } | ||||
|         ~StdErrRedirect() { | ||||
|             m_targetString += m_oss.str(); | ||||
|             cerr().rdbuf(m_cerrBuf); | ||||
|             clog().rdbuf(m_clogBuf); | ||||
|         } | ||||
|     private: | ||||
|         std::streambuf* m_cerrBuf; | ||||
|         std::streambuf* m_clogBuf; | ||||
|         std::ostringstream m_oss; | ||||
|         std::string& m_targetString; | ||||
|     }; | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|     class RunContext : public IResultCapture, public IRunner { | ||||
| @@ -305,7 +329,7 @@ namespace Catch { | ||||
|                 timer.start(); | ||||
|                 if( m_reporter->getPreferences().shouldRedirectStdOut ) { | ||||
|                     StreamRedirect coutRedir( Catch::cout(), redirectedCout ); | ||||
|                     StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); | ||||
|                     StdErrRedirect errRedir( redirectedCerr ); | ||||
|                     invokeActiveTestCase(); | ||||
|                 } | ||||
|                 else { | ||||
|   | ||||
| @@ -21,6 +21,7 @@ namespace Catch { | ||||
|  | ||||
|     std::ostream& cout(); | ||||
|     std::ostream& cerr(); | ||||
|     std::ostream& clog(); | ||||
|  | ||||
|  | ||||
|     struct IStream { | ||||
|   | ||||
| @@ -103,6 +103,9 @@ namespace Catch { | ||||
|     std::ostream& cerr() { | ||||
|         return std::cerr; | ||||
|     } | ||||
|     std::ostream& clog() { | ||||
|         return std::clog; | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Martin Hořeňovský
					Martin Hořeňovský