00001 #ifndef Exc_Ruby__Ruby_Exceptions__hpp_
00002 #define Exc_Ruby__Ruby_Exceptions__hpp_
00003
00009 #include <ruby.h>
00010 #undef TYPE
00011
00012 #include <stdexcept>
00013 #include "detail/ruby_hacks.hpp"
00014
00015 namespace Exc_Ruby
00016 {
00017
00019
00028 struct Ruby_Exception
00029 {
00031 Ruby_Exception(VALUE e) : ex(e) { }
00032
00035 Ruby_Exception(VALUE exc, char const * fmt, ...);
00036
00038 VALUE ex;
00039 };
00040
00042
00046 struct Ruby_Jump_Tag
00047 {
00049 Ruby_Jump_Tag(int t) : tag(t) { }
00050
00052 int tag;
00053 };
00054
00058
00059
00060
00061
00062
00063 #define RUBY_TRY \
00064 VALUE Exc_Ruby__ruby_exc = Qnil; \
00065 int Exc_Ruby__ruby_jump_tag = 0; \
00066 \
00067 goto start_of_RUBY_TRY; \
00068 \
00069 Exc_Ruby__ruby_exception: \
00070 rb_exc_raise(Exc_Ruby__ruby_exc); \
00071 Exc_Ruby__ruby_jump_tag: \
00072 rb_jump_tag(Exc_Ruby__ruby_jump_tag); \
00073 \
00074 start_of_RUBY_TRY: \
00075 try
00076
00082 #define RUBY_RETHROW(ex) \
00083 Exc_Ruby__ruby_exc = ex; \
00084 goto Exc_Ruby__ruby_exception;
00085
00089 #define RUBY_CATCH \
00090 catch(::Exc_Ruby::Ruby_Exception const & ex) \
00091 { \
00092 RUBY_RETHROW(ex.ex); \
00093 } \
00094 catch(::Exc_Ruby::Ruby_Jump_Tag const & ex) \
00095 { \
00096 Exc_Ruby__ruby_jump_tag = ex.tag; \
00097 goto Exc_Ruby__ruby_jump_tag; \
00098 } \
00099 catch(std::bad_alloc const & ex) \
00100 { \
00101 \
00102 \
00103 \
00104 RUBY_RETHROW(rb_exc_new2(rb_eNoMemError, ex.what())); \
00105 } \
00106 catch(std::exception const & ex) \
00107 { \
00108 \
00109 RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, ex.what())); \
00110 } \
00111 catch(...) \
00112 { \
00113 RUBY_RETHROW(rb_exc_new2(rb_eRuntimeError, "unknown C++ exception thrown")); \
00114 } \
00115
00116 }
00117
00118 #include "ruby_exceptions.ipp"
00119
00120 #endif // Exc_Ruby__Ruby_Exceptions__hpp_
00121