add support for architectures with broken std::exception_ptr std::exception_ptr is...
authorThomas Krennwallner <tkren@kr.tuwien.ac.at>
Wed, 14 Dec 2016 07:37:15 +0000 (08:37 +0100)
committerThomas Krennwallner <tkren@kr.tuwien.ac.at>
Tue, 20 Dec 2016 04:10:36 +0000 (04:10 +0000)
Forwarded: not-needed

===================================================================

Gbp-Pq: Name gringo-broken-std-exception_ptr.patch

libgringo/gringo/control.hh
libgringo/src/control.cc

index 6338d6f0e45670881654a0403944ad1e5827e975..197eb1ed133c31513a31934a9f1633982537c0d8 100644 (file)
@@ -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<std::string> 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
 
index 67c66918785c9ee12d8e51b115798497d3102151..384f3cb20394a29d58f8afb338d8b7778a291246 100644 (file)
@@ -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<std::thread::id, TLData> g_tLData;
-    std::exception_ptr &tLlastException() {
+    clingo_exception_holder_t &tLlastException() {
         std::lock_guard<std::mutex> 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>(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<GroundCallback&, std::exception_ptr>;
+    using Data = std::pair<GroundCallback&, clingo_exception_holder_t>;
     Data data(cb, nullptr);
     handleCError(clingo_control_ground(*impl_, reinterpret_cast<clingo_part_t const *>(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<ModelCallback&, std::exception_ptr>;
+    using Data = std::pair<ModelCallback&, clingo_exception_holder_t>;
     Data data(mh, nullptr);
     handleCError(clingo_control_solve(*impl_, [](clingo_model_t *m, void *data, bool *ret) -> bool {
         auto &d = *static_cast<Data*>(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<StatementCallback &, std::exception_ptr>;
+    using Data = std::pair<StatementCallback &, clingo_exception_holder_t>;
     Data data(cb, nullptr);
     handleCError(clingo_parse_program(program, [](clingo_ast_statement_t const *stm, void *data) -> bool {
         auto &d = *static_cast<Data*>(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;
 }