Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorMartin Hořeňovský2017-08-09 15:28:40 +0200
committerMartin Hořeňovský2017-08-09 15:28:40 +0200
commit7e4038d8488596e850a11c8fe236b59bca605444 (patch)
tree4c4fdd5db9630ff68b5180bc00386f8e11709339 /include
parent92d714ee12714ab760eaaaf95d76237859a342d9 (diff)
downloadcatch3-7e4038d8488596e850a11c8fe236b59bca605444.tar.gz
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
Diffstat (limited to 'include')
-rw-r--r--include/internal/catch_run_context.hpp26
-rw-r--r--include/internal/catch_stream.h1
-rw-r--r--include/internal/catch_stream.hpp3
3 files changed, 29 insertions, 1 deletions
diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp
index 88c56603..8cd637c6 100644
--- a/include/internal/catch_run_context.hpp
+++ b/include/internal/catch_run_context.hpp
@@ -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 {
diff --git a/include/internal/catch_stream.h b/include/internal/catch_stream.h
index d8deebab..4323c318 100644
--- a/include/internal/catch_stream.h
+++ b/include/internal/catch_stream.h
@@ -21,6 +21,7 @@ namespace Catch {
std::ostream& cout();
std::ostream& cerr();
+ std::ostream& clog();
struct IStream {
diff --git a/include/internal/catch_stream.hpp b/include/internal/catch_stream.hpp
index 42f51e82..b8838d34 100644
--- a/include/internal/catch_stream.hpp
+++ b/include/internal/catch_stream.hpp
@@ -103,6 +103,9 @@ namespace Catch {
std::ostream& cerr() {
return std::cerr;
}
+ std::ostream& clog() {
+ return std::clog;
+ }
#endif
}