Rice  1.5.2
 All Classes Files Functions Variables Typedefs Friends Pages
ruby_try_catch.hpp
1 #ifndef Rice__ruby_try_catch__hpp_
2 #define Rice__ruby_try_catch__hpp_
3 
4 #include "Exception_Base_defn.hpp"
5 #include "Jump_Tag.hpp"
6 #include "detail/ruby.hpp"
7 #include <stdexcept>
8 
12 // Goto is used here to avoid having to use a second try/catch block (we
13 // can't rb_exc_raise directly out of the catch blocks below, since the
14 // exceptions will not get properly cleaned up).
15 // The labels are located before the try and not after it so the function can't
16 // "fall through" into the exception-handling code accidentally.
17 #define RUBY_TRY \
18  VALUE Rice__ruby_exc = Qnil; \
19  int Rice__ruby_jump_tag = 0; \
20  \
21  goto start_of_RUBY_TRY; \
22  \
23  Rice__ruby_exception: \
24  rb_exc_raise(Rice__ruby_exc); \
25  Rice__ruby_jump_tag: \
26  rb_jump_tag(Rice__ruby_jump_tag); \
27  \
28  start_of_RUBY_TRY: \
29  try
30 
36 #define RUBY_RETHROW(ex) \
37  Rice__ruby_exc = ex; \
38  goto Rice__ruby_exception;
39 
43 #define RUBY_CATCH \
44  catch(::Rice::Exception_Base const & ex) \
45  { \
46  RUBY_RETHROW(ex.value()); \
47  } \
48  catch(::Rice::Jump_Tag const & ex) \
49  { \
50  Rice__ruby_jump_tag = ex.tag; \
51  goto Rice__ruby_jump_tag; \
52  } \
53  catch(std::bad_alloc const & ex) \
54  { \
55  /* This won't work quite right if the rb_exc_new2 fails; not */ \
56  /* much we can do about that, since Ruby doesn't give us access */ \
57  /* to a pre-allocated NoMemoryError object */ \
58  RUBY_RETHROW(rb_exc_new2(rb_eNoMemError, ex.what())); \
59  } \
60  catch(std::invalid_argument const & ex) \
61  { \
62  /* This can raise a NoMemoryError in VERY rare circumstances */ \
63  RUBY_RETHROW(rb_exc_new2(rb_eArgError, ex.what())); \
64  } \
65  catch(std::domain_error const & ex) \
66  { \
67  /* This can raise a NoMemoryError in VERY rare circumstances */ \
68  RUBY_RETHROW(rb_exc_new2(rb_eFloatDomainError, ex.what())); \
69  } \
70  catch(std::out_of_range const & ex) \
71  { \
72  /* This can raise a NoMemoryError in VERY rare circumstances */ \
73  RUBY_RETHROW(rb_exc_new2(rb_eRangeError, ex.what())); \
74  } \
75  catch(std::exception const & ex) \
76  { \
77  /* This can raise a NoMemoryError in VERY rare circumstances */ \
78  RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, ex.what())); \
79  } \
80  catch(...) \
81  { \
82  RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, "unknown C++ exception thrown")); \
83  } \
84 
85 #endif // Rice__ruby_try_catch__hpp_
86