diff options
Diffstat (limited to 'openssl/diagnostics.hxx')
-rw-r--r-- | openssl/diagnostics.hxx | 115 |
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 |