2323namespace Rcpp {
2424
2525 struct EvalCall {
26- SEXP expr_ ;
26+ SEXP expr ;
2727 SEXP env;
2828 SEXP result;
29+ std::vector<std::string> warnings;
2930 std::string error_message;
3031 };
3132
3233 inline void Rcpp_eval (void * data) {
3334
3435 EvalCall* evalCall = (EvalCall*)data;
35- SEXP expr_ = evalCall->expr_ ;
3636 SEXP env = evalCall->env ;
3737
38- Shield<SEXP> expr ( expr_ ) ;
38+ Shield<SEXP> expr (evalCall-> expr ) ;
3939
4040 reset_current_error () ;
4141
4242 Environment RCPP = Environment::Rcpp_namespace ();
43+ SEXP withCallingHandlersSym = ::Rf_install (" withCallingHandlers" );
4344 SEXP tryCatchSym = ::Rf_install (" tryCatch" );
4445 SEXP evalqSym = ::Rf_install (" evalq" );
4546 SEXP conditionMessageSym = ::Rf_install (" conditionMessage" );
4647 SEXP errorRecorderSym = ::Rf_install (" .rcpp_error_recorder" );
48+ SEXP warningRecorderSym = ::Rf_install (" .rcpp_warning_recorder" );
49+ SEXP collectWarningsSym = ::Rf_install (" .rcpp_collect_warnings" );
4750 SEXP errorSym = ::Rf_install (" error" );
51+ SEXP warningSym = ::Rf_install (" warning" );
4852
49- Shield<SEXP> call ( Rf_lang3 (
53+ // define the tryCatchCall
54+ Shield<SEXP> tryCatchCall ( Rf_lang3 (
5055 tryCatchSym,
5156 Rf_lang3 ( evalqSym, expr, env ),
5257 errorRecorderSym
5358 ) ) ;
54- SET_TAG ( CDDR (call), errorSym ) ;
55- /* call the tryCatch call */
59+ SET_TAG ( CDDR (tryCatchCall), errorSym ) ;
60+
61+ // encose it in withCallingHandlers
62+ Shield<SEXP> call ( Rf_lang3 (
63+ withCallingHandlersSym,
64+ tryCatchCall,
65+ warningRecorderSym
66+ ) ) ;
67+ SET_TAG ( CDDR (call), warningSym ) ;
68+
69+ // execute the call
5670 Shield<SEXP> res (::Rf_eval ( call, RCPP ) );
5771
72+ // collect warnings
73+ Shield<SEXP> warnings (::Rf_eval (Rf_lang1 (collectWarningsSym), RCPP));
74+ evalCall->warnings = Rcpp::as<std::vector<std::string> >(warnings);
75+
76+ // check for error
5877 if ( error_occured () ) {
5978 Shield<SEXP> current_error ( rcpp_get_current_error () ) ;
6079 Shield<SEXP> conditionMessageCall (::Rf_lang2 (conditionMessageSym, current_error)) ;
@@ -66,10 +85,21 @@ namespace Rcpp{
6685 }
6786
6887 inline SEXP Rcpp_eval (SEXP expr_, SEXP env) {
88+
89+ // create the call object
6990 EvalCall call;
70- call.expr_ = expr_;
91+ call.expr = expr_;
7192 call.env = env;
72- if (R_ToplevelExec (Rcpp_eval, (void *)&call)) {
93+
94+ // execute it
95+ Rboolean completed = R_ToplevelExec (Rcpp_eval, (void *)&call);
96+
97+ // print warnings
98+ for (size_t i = 0 ; i<call.warnings .size (); i++)
99+ Rf_warning (call.warnings [i].c_str ());
100+
101+ // handle error or result if it completed, else throw interrupt
102+ if (completed) {
73103 if (!call.error_message .empty ())
74104 throw eval_error (call.error_message );
75105 else
0 commit comments