1 // Copyright Daniel Wallin 2005. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4 
5 #define LUABIND_BUILDING
6 
7 #include <luabind/config.hpp>
8 #include <luabind/exception_handler.hpp>
9 #include <luabind/error.hpp>
10 #include <stdexcept>
11 
12 #ifndef LUABIND_NO_EXCEPTIONS
13 
14 namespace luabind { namespace detail {
15 
16 namespace
17 {
18   exception_handler_base* handler_chain = 0;
19 
push_exception_string(lua_State * L,char const * exception,char const * what)20   void push_exception_string(lua_State* L, char const* exception, char const* what)
21   {
22       lua_pushstring(L, exception);
23       lua_pushstring(L, ": '");
24       lua_pushstring(L, what);
25       lua_pushstring(L, "'");
26       lua_concat(L, 4);
27   }
28 }
29 
try_next(lua_State * L) const30 void exception_handler_base::try_next(lua_State* L) const
31 {
32     if (next)
33         next->handle(L);
34     else
35         throw;
36 }
37 
handle_exception_aux(lua_State * L)38 LUABIND_API void handle_exception_aux(lua_State* L)
39 {
40     try
41     {
42         if (handler_chain)
43             handler_chain->handle(L);
44         else
45             throw;
46     }
47     catch (error const&)
48     {}
49     catch (std::logic_error const& e)
50     {
51         push_exception_string(L, "std::logic_error", e.what());
52     }
53     catch (std::runtime_error const& e)
54     {
55         push_exception_string(L, "std::runtime_error", e.what());
56     }
57     catch (std::exception const& e)
58     {
59         push_exception_string(L, "std::exception", e.what());
60     }
61     catch (char const* str)
62     {
63         push_exception_string(L, "c-string", str);
64     }
65     catch (...)
66     {
67         lua_pushstring(L, "Unknown C++ exception");
68     }
69 }
70 
register_exception_handler(exception_handler_base * handler)71 LUABIND_API void register_exception_handler(exception_handler_base* handler)
72 {
73     if (!handler_chain) handler_chain = handler;
74     else
75     {
76         exception_handler_base* p = handler_chain;
77 
78         for (; p->next; p = p->next);
79 
80         handler->next = 0;
81         p->next = handler;
82     }
83 }
84 
85 }} // namespace luabind::detail
86 
87 #endif // LUABIND_NO_EXCEPTIONS
88