aboutsummaryrefslogtreecommitdiff
path: root/bpkg/diagnostics.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/diagnostics.hxx')
-rw-r--r--bpkg/diagnostics.hxx65
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 ();
}) {}
};