00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Rcpp.h>
00023 #include <typeinfo>
00024 #include <exception>
00025 #include <exception_defines.h>
00026 #include <cxxabi.h>
00027
00028
00029 void forward_uncaught_exceptions_to_r(){
00030
00031 std::string exception_class ;
00032 bool has_exception_class = false;
00033 std::string exception_what ;
00034
00035
00036
00037 std::type_info *t = abi::__cxa_current_exception_type();
00038 if (t){
00039 has_exception_class = true ;
00040 const char *name = t->name() ;
00041
00042
00043 {
00044 int status = -1;
00045 char *dem = 0;
00046 dem = abi::__cxa_demangle(name, 0, 0, &status);
00047 if( status == 0){
00048 exception_class = dem ;
00049 free(dem);
00050 } else{
00051 exception_class = name ;
00052 }
00053 }
00054 }
00055
00056
00057
00058 try {
00059 __throw_exception_again;
00060 #ifdef __EXCEPTIONS
00061 } catch (std::exception &exc) {
00062 exception_what = exc.what() ;
00063 #endif
00064 } catch (...) {
00065 exception_what = "unrecognized exception" ;
00066 }
00067
00068 Rf_eval(
00069 Rf_lang3(
00070 Rf_install("cpp_exception"),
00071 Rf_mkString(exception_what.c_str()),
00072 has_exception_class ? Rf_mkString(exception_class.c_str()) : R_NilValue
00073 ), R_FindNamespace(Rf_mkString("Rcpp"))
00074 ) ;
00075 }
00076
00077 SEXP initUncaughtExceptionHandler(){
00078 void (*old_terminate)() = std::set_terminate(forward_uncaught_exceptions_to_r);
00079 return R_NilValue ;
00080 }
00081