diff options
Diffstat (limited to 'bpkg/diagnostics.hxx')
-rw-r--r-- | bpkg/diagnostics.hxx | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/bpkg/diagnostics.hxx b/bpkg/diagnostics.hxx index d11ab0b..a01d90c 100644 --- a/bpkg/diagnostics.hxx +++ b/bpkg/diagnostics.hxx @@ -8,7 +8,7 @@ #include <odb/tracer.hxx> -#include <libbutl/diagnostics.mxx> +#include <libbutl/diagnostics.hxx> #include <bpkg/types.hxx> // Note: not <bpkg/utility.hxx> @@ -16,10 +16,27 @@ namespace bpkg { using butl::diag_record; - // Throw this exception to terminate the process. The handler should - // assume that the diagnostics has already been issued. + // Throw this exception to terminate the process potentially with a custom + // exit code. The handler should assume that suitable diagnostics has + // already been issued. // - class failed: public std::exception {}; + class failed: public std::exception + { + public: + uint16_t code; + + explicit + failed (uint16_t c = 1): code (c) {} + }; + + // As above but needs to be used for recoverable errors which are likely to + // disappear on the command retry. + // + class recoverable: public failed + { + public: + recoverable (): failed (2) {} + }; // Print process commmand line. If the number of elements is specified // (or the second version is used), then it will print the piped multi- @@ -92,13 +109,46 @@ namespace bpkg template <typename F> inline void l5 (const F& f) {if (verb >= 5) f ();} template <typename F> inline void l6 (const F& f) {if (verb >= 6) f ();} + // Progress reporting. + // + using butl::diag_progress; + using butl::diag_progress_lock; + // Diagnostic facility, base infrastructure. // using butl::diag_stream; using butl::diag_epilogue; + using butl::diag_frame; // Diagnostic facility, project specifics. // + + // Note: diag frames are not applied to text/trace diagnostics. + // + template <typename F> + struct diag_frame_impl: diag_frame + { + explicit + diag_frame_impl (F f): diag_frame (&thunk), func_ (move (f)) {} + + private: + static void + thunk (const diag_frame& f, const butl::diag_record& r) + { + static_cast<const diag_frame_impl&> (f).func_ ( + const_cast<diag_record&> (static_cast<const diag_record&> (r))); + } + + const F func_; + }; + + template <typename F> + inline diag_frame_impl<F> + make_diag_frame (F f) + { + return diag_frame_impl<F> (move (f)); + } + struct simple_prologue_base { explicit @@ -162,7 +212,7 @@ namespace bpkg basic_mark_base (const char* type, const char* name = nullptr, const void* data = nullptr, - diag_epilogue* epilogue = nullptr) + diag_epilogue* epilogue = &diag_frame::apply) : type_ (type), name_ (name), data_ (data), epilogue_ (epilogue) {} simple_prologue @@ -264,9 +314,10 @@ namespace bpkg : basic_mark_base (type, nullptr, data, - [](const diag_record& r) + [](const diag_record& r, butl::diag_writer* w) { - r.flush (); + diag_frame::apply (r); + r.flush (w); throw failed (); }) {} }; |