diff --git a/bin/autcross.cc b/bin/autcross.cc index 8a1394ddb..437759429 100644 --- a/bin/autcross.cc +++ b/bin/autcross.cc @@ -153,6 +153,8 @@ static output_file* bogus_output = nullptr; static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; switch (key) { case 'F': @@ -214,6 +216,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/autfilt.cc b/bin/autfilt.cc index f8cbf7dc4..e0f8279b2 100644 --- a/bin/autfilt.cc +++ b/bin/autfilt.cc @@ -688,6 +688,8 @@ product_or(spot::twa_graph_ptr left, spot::twa_graph_ptr right) static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -1154,6 +1156,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/common_aoutput.cc b/bin/common_aoutput.cc index 9e8976da9..8ec651fbc 100644 --- a/bin/common_aoutput.cc +++ b/bin/common_aoutput.cc @@ -24,6 +24,7 @@ #include "common_aoutput.hh" #include "common_post.hh" #include "common_cout.hh" +#include "common_setup.hh" #include #include @@ -304,6 +305,8 @@ const struct argp aoutput_o_format_argp = { o_options, int parse_opt_aoutput(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -358,6 +361,7 @@ int parse_opt_aoutput(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/common_color.cc b/bin/common_color.cc index 7b6330356..5c49e2021 100644 --- a/bin/common_color.cc +++ b/bin/common_color.cc @@ -1,6 +1,6 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2017 Laboratoire de Recherche et Développement de -// l'Epita (LRDE). +// Copyright (C) 2017, 2019 Laboratoire de Recherche et Développement +// de l'Epita (LRDE). // // This file is part of Spot, a model checking library. // @@ -19,6 +19,7 @@ #include "common_sys.hh" #include "common_color.hh" +#include "common_setup.hh" #include #include @@ -77,6 +78,8 @@ static const argp_option options_color[] = static int parse_opt_color(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -91,6 +94,7 @@ parse_opt_color(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/common_finput.cc b/bin/common_finput.cc index f19e64a6b..67e5a4353 100644 --- a/bin/common_finput.cc +++ b/bin/common_finput.cc @@ -1,6 +1,6 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2012-2017 Laboratoire de Recherche -// et Développement de l'Epita (LRDE). +// Copyright (C) 2012-2017, 2019 Laboratoire de Recherche et +// Développement de l'Epita (LRDE). // // This file is part of Spot, a model checking library. // @@ -62,6 +62,8 @@ const struct argp finput_argp_headless = { options + 1, parse_opt_finput, int parse_opt_finput(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -80,6 +82,7 @@ parse_opt_finput(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/common_hoaread.cc b/bin/common_hoaread.cc index 809796b0c..919378da4 100644 --- a/bin/common_hoaread.cc +++ b/bin/common_hoaread.cc @@ -1,6 +1,6 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2015 Laboratoire de Recherche et Développement de -// l'Epita (LRDE). +// Copyright (C) 2015, 2019 Laboratoire de Recherche et Développement +// de l'Epita (LRDE). // // This file is part of Spot, a model checking library. // @@ -18,6 +18,7 @@ // along with this program. If not, see . #include "common_hoaread.hh" +#include "common_setup.hh" #include "argmatch.h" #include "error.h" @@ -72,6 +73,8 @@ static bool parse_bool(const char* opt, const char* arg) static int parse_opt_hoaread(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -81,6 +84,7 @@ parse_opt_hoaread(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/common_output.cc b/bin/common_output.cc index 092a9329f..e9c61a513 100644 --- a/bin/common_output.cc +++ b/bin/common_output.cc @@ -20,6 +20,7 @@ #include "common_sys.hh" #include "common_output.hh" #include "common_aoutput.hh" +#include "common_setup.hh" #include #include #include @@ -304,6 +305,8 @@ static std::map> outputfiles; int parse_opt_output(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -344,6 +347,7 @@ parse_opt_output(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/common_post.cc b/bin/common_post.cc index ef97b0a26..e6ebfd29b 100644 --- a/bin/common_post.cc +++ b/bin/common_post.cc @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2012-2016, 2018 Laboratoire de Recherche et +// Copyright (C) 2012-2016, 2018-2019 Laboratoire de Recherche et // Développement de l'Epita (LRDE). // // This file is part of Spot, a model checking library. @@ -20,6 +20,7 @@ #include "common_post.hh" #include "common_r.hh" #include "common_aoutput.hh" +#include "common_setup.hh" #include "error.h" #include "argmatch.h" @@ -154,6 +155,8 @@ static const argp_option options_disabled[] = static int parse_opt_post(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -253,6 +256,7 @@ parse_opt_post(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/common_setup.cc b/bin/common_setup.cc index 99b4eb202..dab5df571 100644 --- a/bin/common_setup.cc +++ b/bin/common_setup.cc @@ -150,6 +150,8 @@ static const argp_option options_hidden[] = static int parse_opt_misc(int key, char*, struct argp_state* state) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -170,6 +172,7 @@ parse_opt_misc(int key, char*, struct argp_state* state) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } @@ -181,6 +184,18 @@ const struct argp misc_argp_hidden = { options_hidden, parse_opt_misc, nullptr, nullptr, nullptr, nullptr, nullptr }; +[[noreturn]] void handle_any_exception() +{ + try + { + throw; + } + catch (const std::exception& e) + { + error(2, 0, "%s", e.what()); + } + SPOT_UNREACHABLE(); +} int protected_main(char** progname, std::function mainfun) { @@ -189,13 +204,9 @@ int protected_main(char** progname, std::function mainfun) setup(progname); return mainfun(); } - catch (const std::runtime_error& e) + catch (...) { - error(2, 0, "%s", e.what()); - } - catch (const std::invalid_argument& e) - { - error(2, 0, "%s", e.what()); + handle_any_exception(); } SPOT_UNREACHABLE(); return 2; diff --git a/bin/common_setup.hh b/bin/common_setup.hh index 41f4a71a2..e2fce84e0 100644 --- a/bin/common_setup.hh +++ b/bin/common_setup.hh @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2012, 2013, 2018 Laboratoire de Recherche et +// Copyright (C) 2012, 2013, 2018, 2019 Laboratoire de Recherche et // Développement de l'Epita (LRDE). // // This file is part of Spot, a model checking library. @@ -31,3 +31,8 @@ extern const struct argp misc_argp_hidden; // Call setup(progname) then Run mainfun() and handle exceptions. int protected_main(char** progname, std::function mainfun); + +// Diagnose exceptions. +[[noreturn]] void handle_any_exception(); +#define BEGIN_EXCEPTION_PROTECT try { (void)0; +#define END_EXCEPTION_PROTECT } catch (...) { handle_any_exception(); } diff --git a/bin/common_trans.cc b/bin/common_trans.cc index bac0c15ba..e3df2316b 100644 --- a/bin/common_trans.cc +++ b/bin/common_trans.cc @@ -18,6 +18,7 @@ // along with this program. If not, see . #include "common_trans.hh" +#include "common_setup.hh" #include #include #include @@ -902,6 +903,8 @@ bool opt_relabel = false; static int parse_opt_trans(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; switch (key) { case 't': @@ -930,6 +933,7 @@ static int parse_opt_trans(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/dstar2tgba.cc b/bin/dstar2tgba.cc index 1abe45f23..3bf5b9393 100644 --- a/bin/dstar2tgba.cc +++ b/bin/dstar2tgba.cc @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2013-2018 Laboratoire de Recherche et Développement +// Copyright (C) 2013-2019 Laboratoire de Recherche et Développement // de l'Epita (LRDE). // // This file is part of Spot, a model checking library. @@ -83,6 +83,8 @@ static spot::option_map extra_options; static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -102,6 +104,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/genaut.cc b/bin/genaut.cc index 9e8f1939e..eb2163cab 100644 --- a/bin/genaut.cc +++ b/bin/genaut.cc @@ -97,11 +97,14 @@ enqueue_job(int pattern, const char* range_str) static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; if (key >= gen::AUT_BEGIN && key < gen::AUT_END) { enqueue_job(key, arg); return 0; } + END_EXCEPTION_PROTECT; return ARGP_ERR_UNKNOWN; } diff --git a/bin/genltl.cc b/bin/genltl.cc index c9f8374bd..6c632de7a 100644 --- a/bin/genltl.cc +++ b/bin/genltl.cc @@ -261,6 +261,8 @@ enqueue_job(int pattern, const char* range_str = nullptr) static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; if (key >= gen::LTL_BEGIN && key < gen::LTL_END) { enqueue_job(key, arg); @@ -278,6 +280,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/ltl2tgba.cc b/bin/ltl2tgba.cc index 332b0a81b..e24e7e856 100644 --- a/bin/ltl2tgba.cc +++ b/bin/ltl2tgba.cc @@ -85,6 +85,8 @@ static spot::postprocessor::output_pref unambig = 0; static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -112,6 +114,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/ltl2tgta.cc b/bin/ltl2tgta.cc index 198b9ccfe..8663f5513 100644 --- a/bin/ltl2tgta.cc +++ b/bin/ltl2tgta.cc @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2012-2018 Laboratoire de Recherche et Développement +// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement // de l'Epita (LRDE). // // This file is part of Spot, a model checking library. @@ -109,6 +109,8 @@ bool opt_with_artificial_livelock = false; static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -154,6 +156,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/ltlcross.cc b/bin/ltlcross.cc index edb5caa41..efafe7b31 100644 --- a/bin/ltlcross.cc +++ b/bin/ltlcross.cc @@ -440,6 +440,8 @@ std::vector formulas; static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -556,6 +558,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/ltldo.cc b/bin/ltldo.cc index 374d61c78..f3e68c34b 100644 --- a/bin/ltldo.cc +++ b/bin/ltldo.cc @@ -164,6 +164,8 @@ const struct argp_child children[] = static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; switch (key) { case OPT_ERRORS: @@ -197,6 +199,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/ltlfilt.cc b/bin/ltlfilt.cc index 72ca8bc3e..d16684ef8 100644 --- a/bin/ltlfilt.cc +++ b/bin/ltlfilt.cc @@ -345,6 +345,8 @@ parse_formula_arg(const std::string& input) static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -545,6 +547,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/ltlgrind.cc b/bin/ltlgrind.cc index 2e141e863..393656b00 100644 --- a/bin/ltlgrind.cc +++ b/bin/ltlgrind.cc @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2014, 2015, 2016, 2017, 2018 Laboratoire de Recherche et +// Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019 Laboratoire de Recherche et // Développement de l'Epita (LRDE). // // This file is part of Spot, a model checking library. @@ -131,6 +131,8 @@ namespace static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; switch (key) { case 'm': @@ -177,6 +179,7 @@ parse_opt(int key, char* arg, struct argp_state*) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/ltlsynt.cc b/bin/ltlsynt.cc index 99e7410eb..8377b79d6 100644 --- a/bin/ltlsynt.cc +++ b/bin/ltlsynt.cc @@ -412,6 +412,8 @@ namespace static int parse_opt(int key, char* arg, struct argp_state*) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; switch (key) { case OPT_INPUT: @@ -452,6 +454,7 @@ parse_opt(int key, char* arg, struct argp_state*) verbose = true; break; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/randaut.cc b/bin/randaut.cc index 76e17085a..8a14ae740 100644 --- a/bin/randaut.cc +++ b/bin/randaut.cc @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2012, 2013, 2014, 2015, 2016, 2018 Laboratoire de Recherche et +// Copyright (C) 2012-2016, 2018-2019 Laboratoire de Recherche et // Développement de l'Epita (LRDE). // // This file is part of Spot, a model checking library. @@ -182,6 +182,8 @@ looks_like_a_range(const char* str) static int parse_opt(int key, char* arg, struct argp_state* as) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -264,6 +266,7 @@ parse_opt(int key, char* arg, struct argp_state* as) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; } diff --git a/bin/randltl.cc b/bin/randltl.cc index 47bfdb3bf..cded77171 100644 --- a/bin/randltl.cc +++ b/bin/randltl.cc @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2012, 2013, 2014, 2015, 2016, 2018 Laboratoire de Recherche +// Copyright (C) 2012-2016, 2018-2019 Laboratoire de Recherche // et Développement de l'Epita (LRDE). // // This file is part of Spot, a model checking library. @@ -159,6 +159,8 @@ static bool ap_count_given = false; static int parse_opt(int key, char* arg, struct argp_state* as) { + // Called from C code, so should not raise any exception. + BEGIN_EXCEPTION_PROTECT; // This switch is alphabetically-ordered. switch (key) { @@ -231,6 +233,7 @@ parse_opt(int key, char* arg, struct argp_state* as) default: return ARGP_ERR_UNKNOWN; } + END_EXCEPTION_PROTECT; return 0; }