1 // 231-Cfg-OutputStreams.cpp 2 // Show how to replace the streams with a simple custom made streambuf. 3 4 // Note that this reimplementation _does not_ follow `std::cerr` 5 // semantic, because it buffers the output. For most uses however, 6 // there is no important difference between having `std::cerr` buffered 7 // or unbuffered. 8 9 #define CATCH_CONFIG_NOSTDOUT 10 #define CATCH_CONFIG_MAIN 11 #include <catch2/catch.hpp> 12 13 14 class out_buff : public std::stringbuf { 15 std::FILE* m_stream; 16 public: out_buff(std::FILE * stream)17 out_buff(std::FILE* stream):m_stream(stream) {} 18 ~out_buff(); sync()19 int sync() override { 20 int ret = 0; 21 for (unsigned char c : str()) { 22 if (putc(c, m_stream) == EOF) { 23 ret = -1; 24 break; 25 } 26 } 27 // Reset the buffer to avoid printing it multiple times 28 str(""); 29 return ret; 30 } 31 }; 32 ~out_buff()33out_buff::~out_buff() { pubsync(); } 34 35 #if defined(__clang__) 36 #pragma clang diagnostic ignored "-Wexit-time-destructors" // static variables in cout/cerr/clog 37 #endif 38 39 namespace Catch { cout()40 std::ostream& cout() { 41 static std::ostream ret(new out_buff(stdout)); 42 return ret; 43 } clog()44 std::ostream& clog() { 45 static std::ostream ret(new out_buff(stderr)); 46 return ret; 47 } cerr()48 std::ostream& cerr() { 49 return clog(); 50 } 51 } 52 53 54 TEST_CASE("This binary uses putc to write out output", "[compilation-only]") { 55 SUCCEED("Nothing to test."); 56 } 57