aboutsummaryrefslogtreecommitdiff
path: root/bpkg/diagnostics
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/diagnostics')
-rw-r--r--bpkg/diagnostics246
1 files changed, 44 insertions, 202 deletions
diff --git a/bpkg/diagnostics b/bpkg/diagnostics
index cbf4509..79c87aa 100644
--- a/bpkg/diagnostics
+++ b/bpkg/diagnostics
@@ -5,16 +5,16 @@
#ifndef BPKG_DIAGNOSTICS
#define BPKG_DIAGNOSTICS
-#include <sstream>
-
#include <odb/tracer.hxx>
+#include <butl/diagnostics>
+
#include <bpkg/types>
#include <bpkg/utility>
namespace bpkg
{
- struct diag_record;
+ using butl::diag_record;
// Throw this exception to terminate the process. The handler should
// assume that the diagnostics has already been issued.
@@ -70,153 +70,10 @@ 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 ();}
- // Diagnostic facility, base infrastructure (potentially reusable).
+ // Diagnostic facility, base infrastructure.
//
- extern ostream* diag_stream;
-
- template <typename> struct diag_prologue;
- template <typename> struct diag_mark;
-
- typedef void (*diag_epilogue) (const diag_record&);
-
- struct diag_record
- {
- template <typename T>
- friend const diag_record&
- operator<< (const diag_record& r, const T& x)
- {
- r.os_ << x;
- return r;
- }
-
- diag_record (): empty_ (true), epilogue_ (nullptr) {}
-
- template <typename B>
- explicit
- diag_record (const diag_prologue<B>& p)
- : empty_ (true), epilogue_ (nullptr) {*this << p;}
-
- template <typename B>
- explicit
- diag_record (const diag_mark<B>& m)
- : empty_ (true), epilogue_ (nullptr) {*this << m;}
-
- ~diag_record () noexcept(false);
-
- void
- append (diag_epilogue e) const
- {
- if (e != nullptr)
- {
- assert (epilogue_ == nullptr); // No multiple epilogues support.
- epilogue_ = e;
- }
-
- if (empty_)
- empty_ = false;
- else
- os_ << "\n ";
- }
-
- // Move constructible-only type.
- //
- /*
- @@ libstdc++ doesn't yet have the ostringstream move support.
-
- diag_record (diag_record&& r)
- : os_ (move (r.os_))
- {
- empty_ = r.empty_;
- r.empty_ = true;
-
- epilogue_ = r.epilogue_;
- r.epilogue_ = nullptr;
- }
- */
-
- diag_record (diag_record&& r)
- {
- empty_ = r.empty_;
- epilogue_ = r.epilogue_;
-
- if (!empty_)
- {
- os_ << r.os_.str ();
- r.empty_ = true;
- r.epilogue_ = nullptr;
- }
- }
-
- diag_record& operator= (diag_record&&) = delete;
-
- diag_record (const diag_record&) = delete;
- diag_record& operator= (const diag_record&) = delete;
-
- public:
- mutable std::ostringstream os_;
-
- private:
- mutable bool empty_;
- mutable diag_epilogue epilogue_;
- };
-
- template <typename B>
- struct diag_prologue: B
- {
- diag_prologue (diag_epilogue e = nullptr): B (), epilogue_ (e) {}
-
- template <typename... A>
- diag_prologue (A&&... a)
- : B (forward<A> (a)...), epilogue_ (nullptr) {}
-
- template <typename... A>
- diag_prologue (diag_epilogue e, A&&... a)
- : B (forward<A> (a)...), epilogue_ (e) {}
-
- template <typename T>
- diag_record
- operator<< (const T& x) const
- {
- diag_record r;
- r.append (epilogue_);
- B::operator() (r);
- r << x;
- return r;
- }
-
- friend const diag_record&
- operator<< (const diag_record& r, const diag_prologue& p)
- {
- r.append (p.epilogue_);
- p (r);
- return r;
- }
-
- private:
- diag_epilogue epilogue_;
- };
-
- template <typename B>
- struct diag_mark: B
- {
- diag_mark (): B () {}
-
- template <typename... A>
- diag_mark (A&&... a): B (forward<A> (a)...) {}
-
- template <typename T>
- diag_record
- operator<< (const T& x) const
- {
- return B::operator() () << x;
- }
-
- friend const diag_record&
- operator<< (const diag_record& r, const diag_mark& m)
- {
- return r << m ();
- }
- };
+ using butl::diag_stream;
+ using butl::diag_epilogue;
// Diagnostic facility, project specifics.
//
@@ -233,7 +90,6 @@ namespace bpkg
const char* type_;
const char* name_;
};
- typedef diag_prologue<simple_prologue_base> simple_prologue;
class location
{
@@ -262,33 +118,37 @@ namespace bpkg
const char* name_;
const location loc_;
};
- typedef diag_prologue<location_prologue_base> location_prologue;
struct basic_mark_base
{
+ using simple_prologue = butl::diag_prologue<simple_prologue_base>;
+ using location_prologue = butl::diag_prologue<location_prologue_base>;
+
explicit
basic_mark_base (const char* type,
const char* name = nullptr,
- const void* data = nullptr)
- : type_ (type), name_ (name), data_ (data) {}
+ const void* data = nullptr,
+ diag_epilogue* epilogue = nullptr)
+ : type_ (type), name_ (name), data_ (data), epilogue_ (epilogue) {}
simple_prologue
operator() () const
{
- return simple_prologue (type_, name_);
+ return simple_prologue (epilogue_, type_, name_);
}
location_prologue
operator() (const location& l) const
{
- return location_prologue (type_, name_, l);
+ return location_prologue (epilogue_, type_, name_, l);
}
template <typename L>
location_prologue
operator() (const L& l) const
{
- return location_prologue (type_, name_, get_location (l, data_));
+ return location_prologue (
+ epilogue_, type_, name_, get_location (l, data_));
}
template <typename F, typename L, typename C>
@@ -296,6 +156,7 @@ namespace bpkg
operator() (F&& f, L&& l, C&& c) const
{
return location_prologue (
+ epilogue_,
type_,
name_,
location (forward<F> (f), forward<L> (l), forward<C> (c)));
@@ -305,8 +166,9 @@ namespace bpkg
const char* type_;
const char* name_;
const void* data_;
+ diag_epilogue* const epilogue_;
};
- typedef diag_mark<basic_mark_base> basic_mark;
+ using basic_mark = butl::diag_mark<basic_mark_base>;
extern const basic_mark error;
extern const basic_mark warn;
@@ -315,8 +177,8 @@ namespace bpkg
// trace
//
- // Also implement the ODB tracer interface so that we can use
- // it to trace database statement execution.
+ // 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
{
@@ -335,60 +197,40 @@ namespace bpkg
virtual void
deallocate (odb::connection&, const odb::statement&);
};
- typedef diag_mark<trace_mark_base> trace_mark;
-
- typedef trace_mark tracer;
+ using trace_mark = butl::diag_mark<trace_mark_base>;
+ using tracer = trace_mark;
// fail
//
- template <typename E>
- struct fail_mark_base
+ struct fail_mark_base: basic_mark_base
{
explicit
- fail_mark_base (const void* data = nullptr): data_ (data) {}
-
- simple_prologue
- operator() () const
- {
- return simple_prologue (&epilogue, "error", nullptr);
- }
-
- location_prologue
- operator() (const location& l) const
- {
- return location_prologue (&epilogue, "error", nullptr, l);
- }
+ fail_mark_base (const char* type,
+ const void* data = nullptr)
+ : basic_mark_base (type,
+ nullptr,
+ data,
+ [](const diag_record&) {throw failed ();}) {}
+ };
- template <typename L>
- location_prologue
- operator() (const L& l) const
- {
- return location_prologue (
- &epilogue, "error", nullptr, get_location (l, data_));
- }
+ using fail_mark = butl::diag_mark<fail_mark_base>;
- template <typename F, typename L, typename C>
- location_prologue
- operator() (F&& f, L&& l, C&& c) const
+ struct fail_end_base
+ {
+ [[noreturn]] void
+ operator() (const diag_record& r) const
{
- return location_prologue (
- &epilogue,
- "error",
- nullptr,
- location (forward<F> (f), forward<L> (l), forward<C> (c)));
+ // If we just throw then the record's destructor will see an active
+ // exception and will not flush the record.
+ //
+ r.flush ();
+ throw failed ();
}
-
- static void
- epilogue (const diag_record&) {throw E ();}
-
- private:
- const void* data_;
};
+ using fail_end = butl::diag_noreturn_end<fail_end_base>;
- template <typename E>
- using fail_mark = diag_mark<fail_mark_base<E>>;
-
- extern const fail_mark<failed> fail;
+ extern const fail_mark fail;
+ extern const fail_end endf;
}
#endif // BPKG_DIAGNOSTICS