From fdc21950905d64b2ca1df5a0b2622022beffe922 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 11 Dec 2014 09:45:26 +0200 Subject: Improve diagnostics and error handling g++-4.9 -std=c++14 -g -I.. -o bd bd.cxx target.cxx native.cxx rule.cxx cxx/rule.cxx cxx/target.cxx process.cxx timestamp.cxx path.cxx --- build/bd.cxx | 88 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 30 deletions(-) (limited to 'build/bd.cxx') diff --git a/build/bd.cxx b/build/bd.cxx index faae4c4..c592d64 100644 --- a/build/bd.cxx +++ b/build/bd.cxx @@ -5,7 +5,6 @@ #include // tzset() #include -#include // exit #include #include #include @@ -14,6 +13,7 @@ #include #include #include +#include using namespace std; @@ -38,7 +38,21 @@ namespace build { const rule& ru (rs.first->second); - if (recipe re = ru.match (t)) + recipe re; + + { + auto g ( + make_exception_guard ( + [] (target& t) + { + cerr << "info: while matching a rule for target " << t << endl; + }, + t)); + + re = ru.match (t); + } + + if (re) { t.recipe (re); break; @@ -83,21 +97,23 @@ namespace build } } - try - { - t.state ((ts = t.recipe () (t))); - assert (ts != target_state::unknown); - return ts; - } - catch (const process_error& e) + const recipe& r (t.recipe ()); + { - // Take care of failed children. In a multi-threaded program that - // fork()'ed but did not exec(), it is unwise to try to do any kind - // of cleanup (like unwinding the stack and running destructors). - // - assert (e.child ()); - exit (1); + auto g ( + make_exception_guard ( + [] (target& t) + { + cerr << "info: while building target " << t << endl; + }, + t)); + + ts = r (t); } + + assert (ts != target_state::unknown); + t.state (ts); + return ts; } } @@ -140,24 +156,36 @@ main (int argc, char* argv[]) // // - if (!match (bd)) - return 1; // Diagnostics has already been issued. - - switch (update (bd)) + try { - case target_state::uptodate: + if (!match (bd)) + return 1; // Diagnostics has already been issued. + + switch (update (bd)) { - cerr << "info: target " << bd << " is up to date" << endl; + case target_state::uptodate: + { + cerr << "info: target " << bd << " is up to date" << endl; + break; + } + case target_state::updated: break; + case target_state::failed: + { + cerr << "error: failed to update target " << bd << endl; + return 1; + } + case target_state::unknown: + assert (false); } - case target_state::updated: - break; - case target_state::failed: - { - cerr << "error: failed to update target " << bd << endl; - return 1; - } - case target_state::unknown: - assert (false); + } + catch (const error&) + { + return 1; // Diagnostics has already been issued. + } + catch (const std::exception& e) + { + cerr << "error: " << e.what () << endl; + return 1; } } -- cgit v1.1