From 2319d01e262b705716e19474865f555f3ca81a7d Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 1 May 2017 13:50:13 +0300 Subject: Add hxx extension for headers and lib prefix for library dirs --- bpkg/diagnostics.hxx | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 bpkg/diagnostics.hxx (limited to 'bpkg/diagnostics.hxx') diff --git a/bpkg/diagnostics.hxx b/bpkg/diagnostics.hxx new file mode 100644 index 0000000..64eecd9 --- /dev/null +++ b/bpkg/diagnostics.hxx @@ -0,0 +1,240 @@ +// file : bpkg/diagnostics.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BPKG_DIAGNOSTICS_HXX +#define BPKG_DIAGNOSTICS_HXX + +#include + +#include + +#include +#include + +namespace bpkg +{ + 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 {}; + + // Print process commmand line. If the number of elements is specified + // (or the second version is used), then it will print the piped multi- + // process command line, if present. In this case, the expected format + // is as follows: + // + // name1 arg arg ... nullptr + // name2 arg arg ... nullptr + // ... + // nameN arg arg ... nullptr nullptr + // + void + print_process (diag_record&, const char* const args[], size_t n = 0); + + void + print_process (const char* const args[], size_t n = 0); + + inline void + print_process (diag_record& dr, const cstrings& args) + { + print_process (dr, args.data (), args.size ()); + } + + inline void + print_process (const cstrings& args) + { + print_process (args.data (), args.size ()); + } + + // Verbosity level. Update documentation for --verbose if changing. + // + // 0 - disabled + // 1 - high-level information messages + // 2 - essential underlying commands that are being executed + // 3 - all underlying commands that are being executed + // 4 - information that could be helpful to the user + // 5 - information that could be helpful to the developer + // 6 - even more detailed information + // + // While uint8 is more than enough, use uint16 for the ease of printing. + // + extern uint16_t verb; + + template inline void l1 (const F& f) {if (verb >= 1) f ();} + template inline void l2 (const F& f) {if (verb >= 2) f ();} + template inline void l3 (const F& f) {if (verb >= 3) f ();} + template inline void l4 (const F& f) {if (verb >= 4) f ();} + template inline void l5 (const F& f) {if (verb >= 5) f ();} + template inline void l6 (const F& f) {if (verb >= 6) f ();} + + // 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) + : type_ (type), name_ (name) {} + + void + operator() (const diag_record& r) const; + + private: + const char* type_; + const char* name_; + }; + + class location + { + public: + location () {} + location (string f, uint64_t l, uint64_t c) + : file (move (f)), line (l), column (c) {} + + string file; + uint64_t line; + uint64_t column; + }; + + struct location_prologue_base + { + location_prologue_base (const char* type, + const char* name, + const location& l) + : type_ (type), name_ (name), loc_ (l) {} + + void + operator() (const diag_record& r) const; + + private: + const char* type_; + const char* name_; + const location loc_; + }; + + struct basic_mark_base + { + using simple_prologue = butl::diag_prologue; + using location_prologue = butl::diag_prologue; + + explicit + basic_mark_base (const char* type, + const char* name = nullptr, + const void* data = nullptr, + diag_epilogue* epilogue = nullptr) + : type_ (type), name_ (name), data_ (data), epilogue_ (epilogue) {} + + simple_prologue + operator() () const + { + return simple_prologue (epilogue_, type_, name_); + } + + location_prologue + operator() (const location& l) const + { + return location_prologue (epilogue_, type_, name_, l); + } + + template + location_prologue + operator() (const L& l) const + { + return location_prologue ( + epilogue_, type_, name_, get_location (l, data_)); + } + + template + location_prologue + operator() (F&& f, L&& l, C&& c) const + { + return location_prologue ( + epilogue_, + type_, + name_, + location (forward (f), forward (l), forward (c))); + } + + protected: + const char* type_; + const char* name_; + const void* data_; + diag_epilogue* const epilogue_; + }; + using basic_mark = butl::diag_mark; + + extern const basic_mark error; + extern const basic_mark warn; + extern const basic_mark info; + extern const basic_mark text; + + // trace + // + // Also implement the ODB tracer interface so that we can use it to trace + // database statement execution. + // + struct trace_mark_base: basic_mark_base, odb::tracer + { + explicit + trace_mark_base (const char* name, const void* data = nullptr) + : basic_mark_base ("trace", name, data) {} + + // odb::tracer interface. + // + virtual void + prepare (odb::connection&, const odb::statement&); + + virtual void + execute (odb::connection&, const char* statement); + + virtual void + deallocate (odb::connection&, const odb::statement&); + }; + using trace_mark = butl::diag_mark; + using tracer = trace_mark; + + // fail + // + struct fail_mark_base: basic_mark_base + { + explicit + fail_mark_base (const char* type, + const void* data = nullptr) + : basic_mark_base (type, + nullptr, + data, + [](const diag_record& r) + { + r.flush (); + throw failed (); + }) {} + }; + + using fail_mark = butl::diag_mark; + + 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; + + extern const fail_mark fail; + extern const fail_end endf; +} + +#endif // BPKG_DIAGNOSTICS_HXX -- cgit v1.1