aboutsummaryrefslogtreecommitdiff
path: root/openssl/diagnostics.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/diagnostics.hxx')
-rw-r--r--openssl/diagnostics.hxx115
1 files changed, 115 insertions, 0 deletions
diff --git a/openssl/diagnostics.hxx b/openssl/diagnostics.hxx
new file mode 100644
index 0000000..3b51c4d
--- /dev/null
+++ b/openssl/diagnostics.hxx
@@ -0,0 +1,115 @@
+// file : openssl/diagnostics.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef OPENSSL_DIAGNOSTICS_HXX
+#define OPENSSL_DIAGNOSTICS_HXX
+
+#include <libbutl/diagnostics.mxx>
+
+#include <openssl/types.hxx> // Note: not <openssl/utility.hxx>.
+
+namespace openssl
+{
+ using butl::diag_record;
+
+ // Throw this exception to terminate the process. The handler should
+ // assume that the diagnostics has already been issued.
+ //
+ class failed: public std::exception {};
+
+ // Diagnostic facility, base infrastructure.
+ //
+ using butl::diag_stream;
+ using butl::diag_epilogue;
+
+ // Diagnostic facility, project specifics.
+ //
+ struct simple_prologue_base
+ {
+ explicit
+ simple_prologue_base (const char* type, const char* name, const char* data)
+ : type_ (type), name_ (name), data_ (data) {}
+
+ void
+ operator() (const diag_record& r) const;
+
+ private:
+ const char* type_;
+ const char* name_;
+ const char* data_;
+ };
+
+ struct basic_mark_base
+ {
+ using simple_prologue = butl::diag_prologue<simple_prologue_base>;
+
+ // If data if not NULL, then we print it as (data) after name. For
+ // example:
+ //
+ // error: main(foo): bar
+ //
+ explicit
+ basic_mark_base (const char* type,
+ const char* name = nullptr,
+ const char* data = nullptr,
+ diag_epilogue* epilogue = nullptr)
+ : type_ (type), name_ (name), data_ (data), epilogue_ (epilogue) {}
+
+ simple_prologue
+ operator() () const
+ {
+ return simple_prologue (epilogue_, type_, name_, data_);
+ }
+
+ public:
+ const char* type_;
+ const char* name_;
+ const char* data_;
+
+ diag_epilogue* const epilogue_;
+ };
+ using basic_mark = butl::diag_mark<basic_mark_base>;
+
+ extern basic_mark error;
+ extern basic_mark warn;
+ extern basic_mark info;
+ extern basic_mark text;
+
+ // fail
+ //
+ struct fail_mark_base: basic_mark_base
+ {
+ explicit
+ fail_mark_base (const char* type, const char* data = nullptr)
+ : basic_mark_base (type,
+ nullptr,
+ data,
+ [](const diag_record& r)
+ {
+ r.flush ();
+ throw failed ();
+ }) {}
+ };
+
+ using fail_mark = butl::diag_mark<fail_mark_base>;
+
+ struct fail_end_base
+ {
+ [[noreturn]] void
+ operator() (const diag_record& r) const
+ {
+ // If we just throw then the record's destructor will see an active
+ // exception and will not flush the record.
+ //
+ r.flush ();
+ throw failed ();
+ }
+ };
+ using fail_end = butl::diag_noreturn_end<fail_end_base>;
+
+ extern fail_mark fail;
+ extern const fail_end endf;
+}
+
+#endif // OPENSSL_DIAGNOSTICS_HXX