fixes valgrind memory leaks that occured when error/RF_error was called within a block containing implicit dtors; seems that R uses setjmp/longjmp to handle errors which produces undefined behavior under g++ see http://stackoverflow.com/questions/1376085/c-safe-to-use-longjmp-and-setjmp

git-svn-id: svn://136.177.114.72/svn_GW/IPhreeqc/trunk@8843 1feff8c3-07ed-0310-ac33-dd36852eb9cd
This commit is contained in:
Scott R Charlton 2014-07-15 03:36:38 +00:00
parent d3537fae99
commit 167b08bfbb

59
R/R.cpp
View File

@ -14,6 +14,10 @@ public:
static IPhreeqc instance; static IPhreeqc instance;
return instance; return instance;
} }
static std::string& err_str() {
static std::string instance;
return instance;
}
}; };
@ -33,9 +37,7 @@ accumLine(SEXP line)
if (STRING_ELT(line, 0) != NA_STRING) { if (STRING_ELT(line, 0) != NA_STRING) {
str_in = CHAR(STRING_ELT(line, 0)); str_in = CHAR(STRING_ELT(line, 0));
if (R::singleton().AccumulateLine(str_in) != VR_OK) { if (R::singleton().AccumulateLine(str_in) != VR_OK) {
std::ostringstream oss; error(R::singleton().GetErrorString());
oss << R::singleton().GetErrorString();
error(oss.str().c_str());
} }
} }
@ -53,15 +55,13 @@ accumLineLst(SEXP line)
} }
int n = length(line); int n = length(line);
std::ostringstream oss; //std::ostringstream oss;
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
if (STRING_ELT(line, i) != NA_STRING) { if (STRING_ELT(line, i) != NA_STRING) {
str_in = CHAR(STRING_ELT(line, 0)); str_in = CHAR(STRING_ELT(line, 0));
if (R::singleton().AccumulateLine(str_in) != VR_OK) { if (R::singleton().AccumulateLine(str_in) != VR_OK) {
std::ostringstream err; error(R::singleton().GetErrorString());
err << R::singleton().GetErrorString();
error(err.str().c_str());
} }
} }
} }
@ -733,9 +733,7 @@ loadDB(SEXP filename)
name = CHAR(STRING_ELT(filename, 0)); name = CHAR(STRING_ELT(filename, 0));
if (R::singleton().LoadDatabase(name) != VR_OK) { if (R::singleton().LoadDatabase(name) != VR_OK) {
std::ostringstream err; error(R::singleton().GetErrorString());
err << R::singleton().GetErrorString();
error(err.str().c_str());
} }
return(R_NilValue); return(R_NilValue);
@ -750,20 +748,21 @@ loadDBLst(SEXP input)
} }
int n = length(input); int n = length(input);
std::ostringstream oss; std::ostringstream *poss = new std::ostringstream();
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
if (STRING_ELT(input, i) != NA_STRING) { if (STRING_ELT(input, i) != NA_STRING) {
oss << CHAR(STRING_ELT(input, i)) << "\n"; (*poss) << CHAR(STRING_ELT(input, i)) << "\n";
} }
} }
if (R::singleton().LoadDatabaseString(oss.str().c_str()) != VR_OK) { if (R::singleton().LoadDatabaseString((*poss).str().c_str()) != VR_OK) {
std::ostringstream err; // all dtors must be called before error
err << R::singleton().GetErrorString(); delete poss;
error(err.str().c_str()); error(R::singleton().GetErrorString());
} }
delete poss;
return(R_NilValue); return(R_NilValue);
} }
@ -780,9 +779,7 @@ loadDBStr(SEXP input)
string = CHAR(STRING_ELT(input, 0)); string = CHAR(STRING_ELT(input, 0));
if (R::singleton().LoadDatabaseString(string) != VR_OK) { if (R::singleton().LoadDatabaseString(string) != VR_OK) {
std::ostringstream err; error(R::singleton().GetErrorString());
err << R::singleton().GetErrorString();
error(err.str().c_str());
} }
return(R_NilValue); return(R_NilValue);
@ -792,9 +789,7 @@ SEXP
runAccum(void) runAccum(void)
{ {
if (R::singleton().RunAccumulated() != VR_OK) { if (R::singleton().RunAccumulated() != VR_OK) {
std::ostringstream oss; error(R::singleton().GetErrorString());
oss << R::singleton().GetErrorString();
error(oss.str().c_str());
} }
return(R_NilValue); return(R_NilValue);
} }
@ -811,9 +806,7 @@ runFile(SEXP filename)
name = CHAR(STRING_ELT(filename, 0)); name = CHAR(STRING_ELT(filename, 0));
if (R::singleton().RunFile(name) != VR_OK) { if (R::singleton().RunFile(name) != VR_OK) {
std::ostringstream oss; error(R::singleton().GetErrorString());
oss << R::singleton().GetErrorString();
error(oss.str().c_str());
} }
return(R_NilValue); return(R_NilValue);
@ -831,9 +824,7 @@ runString(SEXP input)
in = CHAR(STRING_ELT(input, 0)); in = CHAR(STRING_ELT(input, 0));
if (R::singleton().RunString(in) != VR_OK) { if (R::singleton().RunString(in) != VR_OK) {
std::ostringstream oss; error(R::singleton().GetErrorString());
oss << R::singleton().GetErrorString();
error(oss.str().c_str());
} }
return(R_NilValue); return(R_NilValue);
@ -848,20 +839,20 @@ runStringLst(SEXP input)
} }
int n = length(input); int n = length(input);
std::ostringstream oss; std::ostringstream *poss = new std::ostringstream();
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
if (STRING_ELT(input, i) != NA_STRING) { if (STRING_ELT(input, i) != NA_STRING) {
oss << CHAR(STRING_ELT(input, i)) << "\n"; (*poss) << CHAR(STRING_ELT(input, i)) << "\n";
} }
} }
if (R::singleton().RunString(oss.str().c_str()) != VR_OK) { if (R::singleton().RunString((*poss).str().c_str()) != VR_OK) {
std::ostringstream err; delete poss;
err << R::singleton().GetErrorString(); error(R::singleton().GetErrorString());
error(err.str().c_str());
} }
delete poss;
return(R_NilValue); return(R_NilValue);
} }