[rkward-cvs] rkward/rkward/rbackend rembedinternal.cpp,1.30,1.31
Thomas Friedrichsmeier
tfry at users.sourceforge.net
Tue Nov 8 13:13:18 UTC 2005
Update of /cvsroot/rkward/rkward/rkward/rbackend
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4222/rkward/rbackend
Modified Files:
rembedinternal.cpp
Log Message:
Workaround for cases where Rf_PrintValue would cause an R error->longjmp->crash
Index: rembedinternal.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rembedinternal.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** rembedinternal.cpp 4 Nov 2005 13:30:58 -0000 1.30
--- rembedinternal.cpp 8 Nov 2005 13:13:16 -0000 1.31
***************
*** 48,51 ****
--- 48,52 ----
extern int R_CollectWarnings;
extern int R_interrupts_pending;
+ extern Rboolean R_Visible;
}
***************
*** 412,417 ****
}
- UNPROTECT(1); /* pr */
-
if (r_error) {
*error = REmbedInternal::OtherError;
--- 413,416 ----
***************
*** 429,448 ****
}
return exp;
}
void REmbedInternal::runCommandInternal (const char *command, RKWardRError *error, bool print_result) {
if (!print_result) {
runCommandInternalBase (command, error);
} else {
- extern Rboolean R_Visible;
R_Visible = (Rboolean) 1;
SEXP exp;
PROTECT (exp = runCommandInternalBase (command, error));
if (R_Visible) {
! if (*error == NoError) Rf_PrintValue (exp);
}
! UNPROTECT (1);
/* See the comment in the corresponding code in runCommandInternalBase. And yes, apparently, we need this at both places! */
--- 428,479 ----
}
+ // SET_SYMVALUE(R_LastvalueSymbol, exp);
+ UNPROTECT(1); /* pr */
+
return exp;
}
+ /* Basically a safe version of Rf_PrintValue, as yes, Rf_PrintValue may lead to an error and long_jump->crash!
+ For example in help (function, htmlhelp=TRUE), when no HTML-help is installed!
+ SEXP exp should be PROTECTed prior to calling this function.
+ //TODO: I don't think it's meant to be this way. Maybe nag the R-devels about it one day. */
+ void tryPrintValue (SEXP exp, REmbedInternal::RKWardRError *error) {
+ int ierror = 0;
+ SEXP tryprint, e;
+
+ // Basically, we call 'print (expression)' (but inside a tryEval)
+ tryprint = Rf_findFun (Rf_install ("print"), R_GlobalEnv);
+ PROTECT (tryprint);
+ e = allocVector (LANGSXP, 2);
+ PROTECT (e);
+ SETCAR (e, tryprint);
+ SETCAR (CDR (e), exp);
+ R_tryEval (e, R_GlobalEnv, &ierror);
+ UNPROTECT (2); /* e, tryprint */
+
+ if (ierror) {
+ *error = REmbedInternal::OtherError;
+ } else {
+ *error = REmbedInternal::NoError;
+ }
+ }
+
void REmbedInternal::runCommandInternal (const char *command, RKWardRError *error, bool print_result) {
if (!print_result) {
runCommandInternalBase (command, error);
} else {
R_Visible = (Rboolean) 1;
SEXP exp;
PROTECT (exp = runCommandInternalBase (command, error));
+ /* char dummy[100];
+ sprintf (dummy, "type: %d", TYPEOF (exp));
+ Rprintf (dummy, 100); */
if (R_Visible) {
! if (*error == NoError) {
! tryPrintValue (exp, error);
! }
}
! UNPROTECT (1); /* exp */
/* See the comment in the corresponding code in runCommandInternalBase. And yes, apparently, we need this at both places! */
***************
*** 452,456 ****
Rf_PrintWarnings ();
}
! }
}
--- 483,487 ----
Rf_PrintWarnings ();
}
! }
}
More information about the rkward-tracker
mailing list