aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/archive.cxx7
-rw-r--r--bpkg/auth.cxx6
-rw-r--r--bpkg/checksum.cxx9
-rw-r--r--bpkg/database.cxx3
-rw-r--r--bpkg/diagnostics246
-rw-r--r--bpkg/diagnostics.cxx32
-rw-r--r--bpkg/fetch.cxx11
-rw-r--r--bpkg/manifest-utility.cxx3
-rw-r--r--bpkg/pkg-verify.cxx5
-rw-r--r--bpkg/rep-create.cxx6
-rw-r--r--bpkg/types12
-rw-r--r--bpkg/utility45
-rw-r--r--bpkg/utility.cxx9
13 files changed, 85 insertions, 309 deletions
diff --git a/bpkg/archive.cxx b/bpkg/archive.cxx
index 89bb0ed..ee3feab 100644
--- a/bpkg/archive.cxx
+++ b/bpkg/archive.cxx
@@ -125,12 +125,11 @@ namespace bpkg
// archive name. So print the error message whatever the child exit status
// is.
//
- error << "unable to extract " << f << " from " << a;
- throw failed ();
+ fail << "unable to extract " << f << " from " << a << endf;
}
catch (const process_error& e)
{
- error << "unable to extract " << f << " from " << a << ": " << e.what ();
- throw failed ();
+ fail << "unable to extract " << f << " from " << a << ": " << e.what ()
+ << endf;
}
}
diff --git a/bpkg/auth.cxx b/bpkg/auth.cxx
index 4ea0e4b..8cb1ed4 100644
--- a/bpkg/auth.cxx
+++ b/bpkg/auth.cxx
@@ -420,10 +420,8 @@ namespace bpkg
// parsing diagnostics since we were probably parsing garbage.
//
if (pr.wait ())
- {
- error << "invalid certificate for " << repo << ": " << e.what ();
- throw failed ();
- }
+ fail << "invalid certificate for " << repo << ": " << e.what ()
+ << endf;
// Fall through.
}
diff --git a/bpkg/checksum.cxx b/bpkg/checksum.cxx
index 1254749..3d90edc 100644
--- a/bpkg/checksum.cxx
+++ b/bpkg/checksum.cxx
@@ -384,10 +384,8 @@ namespace bpkg
// While it is reasonable to assuming the child process issued diagnostics,
// issue something just in case.
//
- error << "unable to calculate SHA256 sum using '" << sha256_path << "'" <<
- info << "re-run with -v for more information";
-
- throw failed ();
+ fail << "unable to calculate SHA256 sum using '" << sha256_path << "'" <<
+ info << "re-run with -v for more information" << endf;
}
struct memstreambuf: streambuf
@@ -425,8 +423,7 @@ namespace bpkg
}
catch (const io_error& e)
{
- error << "unable read " << f << ": " << e.what ();
- throw failed ();
+ fail << "unable read " << f << ": " << e.what () << endf;
}
}
}
diff --git a/bpkg/database.cxx b/bpkg/database.cxx
index 418265c..c5b17a8 100644
--- a/bpkg/database.cxx
+++ b/bpkg/database.cxx
@@ -98,8 +98,7 @@ namespace bpkg
}
catch (const database_exception& e)
{
- error << f << ": " << e.message ();
- throw failed ();
+ fail << f << ": " << e.message () << endf;
}
}
}
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
diff --git a/bpkg/diagnostics.cxx b/bpkg/diagnostics.cxx
index 9d1f96d..82ebb8c 100644
--- a/bpkg/diagnostics.cxx
+++ b/bpkg/diagnostics.cxx
@@ -48,29 +48,6 @@ namespace bpkg
//
uint16_t verb;
- // Diagnostic facility, base infrastructure.
- //
- ostream* diag_stream = &cerr;
-
- diag_record::
- ~diag_record () noexcept(false)
- {
- // Don't flush the record if this destructor was called as part of
- // the stack unwinding. Right now this means we cannot use this
- // mechanism in destructors, which is not a big deal, except for
- // one place: exception_guard. So for now we are going to have
- // this ugly special check which we will be able to get rid of
- // once C++17 uncaught_exceptions() becomes available.
- //
- if (!empty_ && (!uncaught_exception () || exception_unwinding_dtor))
- {
- *diag_stream << os_.str () << endl;
-
- if (epilogue_ != nullptr)
- epilogue_ (*this); // Can throw.
- }
- }
-
// Diagnostic facility, project specifics.
//
@@ -120,8 +97,9 @@ namespace bpkg
}
const basic_mark error ("error");
- const basic_mark warn ("warning");
- const basic_mark info ("info");
- const basic_mark text (nullptr);
- const fail_mark<failed> fail;
+ const basic_mark warn ("warning");
+ const basic_mark info ("info");
+ const basic_mark text (nullptr);
+ const fail_mark fail ("error");
+ const fail_end endf;
}
diff --git a/bpkg/fetch.cxx b/bpkg/fetch.cxx
index 47f4f9b..4ad476b 100644
--- a/bpkg/fetch.cxx
+++ b/bpkg/fetch.cxx
@@ -632,9 +632,8 @@ namespace bpkg
// While it is reasonable to assuming the child process issued
// diagnostics, some may not mention the URL.
//
- error << "unable to fetch " << url <<
- info << "re-run with -v for more information";
- throw failed ();
+ fail << "unable to fetch " << url <<
+ info << "re-run with -v for more information" << endf;
}
static path
@@ -682,14 +681,12 @@ namespace bpkg
}
catch (const manifest_parsing& e)
{
- error (e.name, e.line, e.column) << e.description;
+ fail (e.name, e.line, e.column) << e.description << endf;
}
catch (const io_error& e)
{
- error << "unable to read from " << f << ": " << e.what ();
+ fail << "unable to read from " << f << ": " << e.what () << endf;
}
-
- throw failed ();
}
static const path repositories ("repositories");
diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx
index 41215cf..95b0089 100644
--- a/bpkg/manifest-utility.cxx
+++ b/bpkg/manifest-utility.cxx
@@ -78,7 +78,6 @@ namespace bpkg
}
catch (const invalid_argument& e)
{
- error << "invalid repository location '" << s << "': " << e.what ();
- throw failed ();
+ fail << "invalid repository location '" << s << "': " << e.what () << endf;
}
}
diff --git a/bpkg/pkg-verify.cxx b/bpkg/pkg-verify.cxx
index 9097dab..c26f8e9 100644
--- a/bpkg/pkg-verify.cxx
+++ b/bpkg/pkg-verify.cxx
@@ -106,9 +106,8 @@ namespace bpkg
{
// Note: this is not an "invalid package" case, so no diag check.
//
- error << "unable to extract manifest file from " << af << ": "
- << e.what ();
- throw failed ();
+ fail << "unable to extract manifest file from " << af << ": "
+ << e.what () << endf;
}
package_manifest
diff --git a/bpkg/rep-create.cxx b/bpkg/rep-create.cxx
index ac58936..43f052c 100644
--- a/bpkg/rep-create.cxx
+++ b/bpkg/rep-create.cxx
@@ -167,8 +167,7 @@ namespace bpkg
}
catch (const system_error& e)
{
- error << "unable to scan directory " << d << ": " << e.what ();
- throw failed ();
+ fail << "unable to scan directory " << d << ": " << e.what () << endf;
}
int
@@ -278,7 +277,6 @@ namespace bpkg
}
catch (const invalid_path& e)
{
- error << "invalid path: '" << e.path << "'";
- throw failed ();
+ fail << "invalid path: '" << e.path << "'" << endf;
}
}
diff --git a/bpkg/types b/bpkg/types
index 8bff6bb..e20acfb 100644
--- a/bpkg/types
+++ b/bpkg/types
@@ -82,11 +82,21 @@ namespace bpkg
using paths = std::vector<path>;
using dir_paths = std::vector<dir_path>;
+}
+// In order to be found (via ADL) these have to be either in std:: or in
+// butl::. The latter is bad idea since libbutl includes the default
+// implementation.
+//
+namespace std
+{
// Custom path printing (with trailing slash for directories).
//
inline ostream&
- operator<< (ostream& os, const path& p) {return os << p.representation ();}
+ operator<< (ostream& os, const ::butl::path& p)
+ {
+ return os << p.representation ();
+ }
}
#endif // BPKG_TYPES
diff --git a/bpkg/utility b/bpkg/utility
index b7dbf36..950a36a 100644
--- a/bpkg/utility
+++ b/bpkg/utility
@@ -11,7 +11,7 @@
#include <cassert> // assert()
#include <iterator> // make_move_iterator()
-#include <butl/utility> // casecmp(), reverse_iterate()
+#include <butl/utility> // casecmp(), reverse_iterate(), etc
#include <exception> // uncaught_exception()
@@ -35,6 +35,9 @@ namespace bpkg
using butl::casecmp;
using butl::reverse_iterate;
+ using butl::exception_guard;
+ using butl::make_exception_guard;
+
// Widely-used paths.
//
extern const dir_path bpkg_dir; // .bpkg/
@@ -112,46 +115,6 @@ namespace bpkg
bool quiet = false,
const strings& pvars = strings (),
const strings& cvars = strings ());
-
- // Call a function if there is an exception.
- //
-
- // True means we are in the body of a destructor that is being
- // called as part of the exception stack unwindining. Used to
- // compensate for the deficiencies of uncaught_exception() until
- // C++17 uncaught_exceptions() becomes available.
- //
- // @@ MT: will have to be TLS.
- //
- extern bool exception_unwinding_dtor;
-
- template <typename F>
- struct exception_guard;
-
- template <typename F>
- inline exception_guard<F>
- make_exception_guard (F f)
- {
- return exception_guard<F> (std::move (f));
- }
-
- template <typename F>
- struct exception_guard
- {
- exception_guard (F f): f_ (std::move (f)) {}
- ~exception_guard ()
- {
- if (std::uncaught_exception ())
- {
- exception_unwinding_dtor = true;
- f_ ();
- exception_unwinding_dtor = false;
- }
- }
-
- private:
- F f_;
- };
}
#endif // BPKG_UTILITY
diff --git a/bpkg/utility.cxx b/bpkg/utility.cxx
index 206b358..98b5125 100644
--- a/bpkg/utility.cxx
+++ b/bpkg/utility.cxx
@@ -68,8 +68,7 @@ namespace bpkg
}
catch (const system_error& e)
{
- error << "unable to stat path " << f << ": " << e.what ();
- throw failed ();
+ fail << "unable to stat path " << f << ": " << e.what () << endf;
}
}
@@ -82,8 +81,7 @@ namespace bpkg
}
catch (const system_error& e)
{
- error << "unable to stat path " << d << ": " << e.what ();
- throw failed ();
+ fail << "unable to stat path " << d << ": " << e.what () << endf;
}
}
@@ -96,8 +94,7 @@ namespace bpkg
}
catch (const system_error& e)
{
- error << "unable to scan directory " << d << ": " << e.what ();
- throw failed ();
+ fail << "unable to scan directory " << d << ": " << e.what () << endf;
}
}