From 5fc5b6fc2d6aad2e07dc8f7825d26dadc6e26830 Mon Sep 17 00:00:00 2001 From: Thomas Krennwallner Date: Wed, 14 Dec 2016 08:37:15 +0100 Subject: [PATCH] add support for architectures with broken std::exception_ptr std::exception_ptr is currently not supported on armel, see libstdc++ bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58938 Forwarded: not-needed =================================================================== Gbp-Pq: Name gringo-broken-std-exception_ptr.patch --- libgringo/gringo/control.hh | 22 ++++++++++++++++++++- libgringo/src/control.cc | 39 ++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/libgringo/gringo/control.hh b/libgringo/gringo/control.hh index 6338d6f..197eb1e 100644 --- a/libgringo/gringo/control.hh +++ b/libgringo/gringo/control.hh @@ -270,11 +270,31 @@ void inline clingo_expect(bool expr) { if (!expr) { throw std::runtime_error("unexpected"); } } -void handleCError(bool ret, std::exception_ptr *exc = nullptr); +#ifndef BROKEN_STD_EXCEPTION_PTR +typedef std::exception_ptr clingo_exception_holder_t; void handleCXXError(); +#else +typedef std::shared_ptr clingo_exception_holder_t; +void handleCXXError(const char *what, clingo_error_t err); +#endif + +void handleCError(bool ret, clingo_exception_holder_t *exc = nullptr); #define GRINGO_CLINGO_TRY try + +#ifndef BROKEN_STD_EXCEPTION_PTR #define GRINGO_CLINGO_CATCH catch (...) { Gringo::handleCXXError(); return false; } return true +#else +#define GRINGO_CLINGO_CATCH \ + catch (Gringo::GringoError const &e) { Gringo::handleCXXError(e.what(), clingo_error_runtime); return false; } \ + catch (Gringo::ClingoError const &e) { return false; } \ + catch (Gringo::MessageLimitError const &e) { Gringo::handleCXXError(e.what(), clingo_error_runtime); return false; } \ + catch (std::bad_alloc const &e) { Gringo::handleCXXError(e.what(), clingo_error_bad_alloc); return false; } \ + catch (std::runtime_error const &e) { Gringo::handleCXXError(e.what(), clingo_error_runtime); return false; } \ + catch (std::logic_error const &e) { Gringo::handleCXXError(e.what(), clingo_error_logic); return false; } \ + catch (...) { Gringo::handleCXXError("", clingo_error_unknown); return false; } \ + return true +#endif // }}}1 diff --git a/libgringo/src/control.cc b/libgringo/src/control.cc index 67c6691..384f3cb 100644 --- a/libgringo/src/control.cc +++ b/libgringo/src/control.cc @@ -72,18 +72,18 @@ void print(char *ret, size_t n, F f) { } #ifndef GRINGO_NO_THREAD_LOCAL - thread_local std::exception_ptr g_lastException; + thread_local clingo_exception_holder_t g_lastException; thread_local std::string g_lastMessage; thread_local clingo_error_t g_lastCode; #else struct TLData { - std::exception_ptr lastException; + clingo_exception_holder_t lastException; std::string lastMessage; clingo_error_t lastCode; }; std::mutex g_tLMut; std::unordered_map g_tLData; - std::exception_ptr &tLlastException() { + clingo_exception_holder_t &tLlastException() { std::lock_guard lock(g_tLMut); return g_tLData[std::this_thread::get_id()].lastException; } @@ -102,9 +102,13 @@ void print(char *ret, size_t n, F f) { } // namespace -void handleCError(bool ret, std::exception_ptr *exc) { +void handleCError(bool ret, clingo_exception_holder_t *exc) { if (!ret) { +#ifndef BROKEN_STD_EXCEPTION_PTR if (exc && *exc) { std::rethrow_exception(*exc); } +#else + if (exc && *exc) { throw std::runtime_error(**exc); } +#endif char const *msg = clingo_error_message(); if (!msg) { msg = "no message"; } switch (static_cast(clingo_error_code())) { @@ -117,6 +121,7 @@ void handleCError(bool ret, std::exception_ptr *exc) { } } +#ifndef BROKEN_STD_EXCEPTION_PTR void handleCXXError() { try { throw; } catch (Gringo::GringoError const &) { g_lastException = std::current_exception(); g_lastCode = clingo_error_runtime; return; } @@ -130,6 +135,12 @@ void handleCXXError() { catch (std::logic_error const &) { g_lastException = std::current_exception(); g_lastCode = clingo_error_logic; return; } g_lastCode = clingo_error_unknown; } +#else +void handleCXXError(const char *what, clingo_error_t err) { + g_lastException = clingo_exception_holder_t(new std::string(what)); + g_lastCode = err; +} +#endif // }}}1 @@ -261,7 +272,12 @@ SymbolType Symbol::type() const { } #define CLINGO_CALLBACK_TRY try + +#ifndef BROKEN_STD_EXCEPTION_PTR #define CLINGO_CALLBACK_CATCH(ref) catch (...){ (ref) = std::current_exception(); return false; } return true +#else +#define CLINGO_CALLBACK_CATCH(ref) catch (std::exception &e){ (ref) = clingo_exception_holder_t(new std::string(e.what())); return false; } return true +#endif std::string Symbol::to_string() const { return ::to_string(clingo_symbol_to_string_size, clingo_symbol_to_string, sym_); @@ -1588,7 +1604,7 @@ void Control::add(char const *name, StringSpan params, char const *part) { } void Control::ground(PartSpan parts, GroundCallback cb) { - using Data = std::pair; + using Data = std::pair; Data data(cb, nullptr); handleCError(clingo_control_ground(*impl_, reinterpret_cast(parts.begin()), parts.size(), [](clingo_location_t loc, char const *name, clingo_symbol_t const *args, size_t n, void *data, clingo_symbol_callback_t *cb, void *cbdata) -> bool { @@ -1612,7 +1628,7 @@ clingo_control_t *Control::to_c() const { return *impl_; } SolveResult Control::solve(ModelCallback mh, SymbolicLiteralSpan assumptions) { clingo_solve_result_bitset_t ret; - using Data = std::pair; + using Data = std::pair; Data data(mh, nullptr); handleCError(clingo_control_solve(*impl_, [](clingo_model_t *m, void *data, bool *ret) -> bool { auto &d = *static_cast(data); @@ -2590,7 +2606,7 @@ std::ostream &operator<<(std::ostream &out, Statement const &x) { } // namespace AST void parse_program(char const *program, StatementCallback cb, Logger logger, unsigned message_limit) { - using Data = std::pair; + using Data = std::pair; Data data(cb, nullptr); handleCError(clingo_parse_program(program, [](clingo_ast_statement_t const *stm, void *data) -> bool { auto &d = *static_cast(data); @@ -2612,17 +2628,26 @@ void parse_program(char const *program, StatementCallback cb, Logger logger, uns extern "C" void clingo_set_error(clingo_error_t code, char const *message) { g_lastCode = code; +#ifndef BROKEN_STD_EXCEPTION_PTR try { g_lastException = std::make_exception_ptr(std::runtime_error(message)); } +#else + try { g_lastException = clingo_exception_holder_t(new std::string(message)); } +#endif catch (...) { g_lastException = nullptr; } } extern "C" char const *clingo_error_message() { if (g_lastException) { +#ifndef BROKEN_STD_EXCEPTION_PTR try { std::rethrow_exception(g_lastException); } catch (std::bad_alloc const &) { return "bad_alloc"; } catch (std::exception const &e) { g_lastMessage = e.what(); return g_lastMessage.c_str(); } +#else + g_lastMessage = *g_lastException; + return g_lastMessage.c_str(); +#endif } return nullptr; } -- 2.30.2