Option to remove usage of iostream, std::cout and std::cerr completely. (#741)
* Option to remove usage of std::cout and std::cerr completely.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
* Correct copy/paste without updating tags.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
* Fix spelling.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
---------
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
diff --git a/doc/markdown/configuration.md b/doc/markdown/configuration.md
index 3bc1424..130c25d 100644
--- a/doc/markdown/configuration.md
+++ b/doc/markdown/configuration.md
@@ -37,6 +37,8 @@
- [**```DOCTEST_CONFIG_ASSERTS_RETURN_VALUES```**](#doctest_config_asserts_return_values)
- [**```DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED```**](#doctest_config_evaluate_asserts_even_when_disabled)
- [**```DOCTEST_CONFIG_NO_CONTRADICTING_INLINE```**](#doctest_config_no_contradicting_inline)
+- [**```DOCTEST_CONFIG_NO_IOSTREAM```**](#doctest_config_no_iostream)
+- [**```DOCTEST_CONFIG_HANDLE_EXCEPTION```**](#doctest_config_handle_exception)
For most people the only configuration needed is telling **doctest** which source file should host all the implementation code:
@@ -301,6 +303,17 @@
However, this is known to cause some issues with a few compilers with hard to suppress warnings. This flag disables the use of the no-inline attribute in order to suppress the warning if your build requires that.
+### **```DOCTEST_CONFIG_NO_IOSTREAM```**
+
+This option disables any inclusion of `<iostream>`, `std::cout` and `std::cerr`. This implies that the `cout` context field must be supplied. If
+```DOCTEST_CONFIG_NO_EXCEPTIONS``` is defined, then the unhandled exception is not printed to `std::cerr`.
+[```DOCTEST_CONFIG_HANDLE_EXCEPTION```](#doctest_config_handle_exception) can be defined to handle this case.
+
+### **```DOCTEST_CONFIG_HANDLE_EXCEPTION```**
+
+This macro function can be defined to handle exceptions instead of just printing them
+to `std::cerr`.
+
---------------
[Home](readme.md#reference)
diff --git a/doctest/parts/doctest.cpp b/doctest/parts/doctest.cpp
index 5ee79f7..1357200 100644
--- a/doctest/parts/doctest.cpp
+++ b/doctest/parts/doctest.cpp
@@ -71,7 +71,9 @@
#include <utility>
#include <fstream>
#include <sstream>
+#ifdef DOCTEST_CONFIG_INCLUDE_IOSTREAM
#include <iostream>
+#endif
#include <algorithm>
#include <iomanip>
#include <vector>
@@ -193,8 +195,14 @@
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
throw e;
#else // DOCTEST_CONFIG_NO_EXCEPTIONS
+#ifdef DOCTEST_CONFIG_HANDLE_EXCEPTION
+ DOCTEST_CONFIG_HANDLE_EXCEPTION(e);
+#else
+#ifdef DOCTEST_CONFIG_INCLUDE_IOSTREAM
std::cerr << "doctest will terminate because it needed to throw an exception.\n"
<< "The message was: " << e.what() << '\n';
+#endif // DOCTEST_CONFIG_INCLUDE_IOSTREAM
+#endif // DOCTEST_CONFIG_HANDLE_EXCEPTION
std::terminate();
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
}
@@ -269,7 +277,7 @@
namespace timer_large_integer
{
-
+
#if defined(DOCTEST_PLATFORM_WINDOWS)
using type = ULONGLONG;
#else // DOCTEST_PLATFORM_WINDOWS
@@ -1905,7 +1913,7 @@
m_string = tlssPop();
logged = true;
}
-
+
DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this);
const bool isWarn = m_severity & assertType::is_warn;
@@ -1974,7 +1982,11 @@
mutable XmlWriter* m_writer = nullptr;
};
+#ifdef DOCTEST_CONFIG_INCLUDE_IOSTREAM
XmlWriter( std::ostream& os = std::cout );
+#else
+ XmlWriter( std::ostream& os );
+#endif
~XmlWriter();
XmlWriter( XmlWriter const& ) = delete;
@@ -2456,7 +2468,7 @@
test_case_start_impl(in);
xml.ensureTagClosed();
}
-
+
void test_case_reenter(const TestCaseData&) override {}
void test_case_end(const CurrentTestCaseStats& st) override {
@@ -3178,7 +3190,7 @@
subcasesStack.clear();
currentSubcaseLevel = 0;
}
-
+
void test_case_reenter(const TestCaseData&) override {
subcasesStack.clear();
}
@@ -3695,8 +3707,12 @@
fstr.open(p->out.c_str(), std::fstream::out);
p->cout = &fstr;
} else {
+#ifdef DOCTEST_CONFIG_INCLUDE_IOSTREAM
// stdout by default
p->cout = &std::cout;
+#else
+ return EXIT_FAILURE;
+#endif
}
}
@@ -3861,7 +3877,7 @@
DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc);
p->timer.start();
-
+
bool run_test = true;
do {
@@ -3902,7 +3918,7 @@
run_test = false;
p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts;
}
-
+
if(!p->nextSubcaseStack.empty() && run_test)
DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc);
if(p->nextSubcaseStack.empty())
diff --git a/doctest/parts/doctest_fwd.h b/doctest/parts/doctest_fwd.h
index 8c4b044..098f9d7 100644
--- a/doctest/parts/doctest_fwd.h
+++ b/doctest/parts/doctest_fwd.h
@@ -396,6 +396,11 @@
#endif
#endif // DOCTEST_NO_SANITIZE_INTEGER
+// Should std::cout/std::cerr ever be used by doctest?
+#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM
+#define DOCTEST_CONFIG_INCLUDE_IOSTREAM
+#endif
+
// =================================================================================================
// == FEATURE DETECTION END ========================================================================
// =================================================================================================