Skip to content

Commit f481d79

Browse files
committed
add rng parameter to Rcpp::export to prevent inclusion of RNGScope in generated code
1 parent 458e053 commit f481d79

File tree

5 files changed

+69
-10
lines changed

5 files changed

+69
-10
lines changed

ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2015-02-12 JJ Allaire <[email protected]>
2+
3+
* DESCRIPTION: bump version
4+
* src/attributes.cpp: Add rng parameter to Rcpp::export to
5+
prevent inclusion of RNGScope in generated code.
6+
17
2015-02-06 Kevin Ushey <[email protected]>
28

39
* inst/include/Rcpp/vector/Subsetter.h: compare CHARSXP pointers

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: Rcpp
22
Title: Seamless R and C++ Integration
3-
Version: 0.11.4.4
3+
Version: 0.11.4.5
44
Date: 2015-02-03
55
Author: Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey,
66
Douglas Bates, and John Chambers

TODO

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ Attributes
8484

8585
o Add unit tests
8686

87-
o Add random = false parameter to Rcpp::export once we support parsing
88-
key/value pairs in attribute parameters
89-
9087
o Detect useDynLib .registration = TRUE and in that case emit .Call
9188
wrappers as symbols rather than strings w/ PACKAGE =
9289

inst/NEWS.Rd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
\item Simplify generated attributes code for \code{RNGScope} (use
2424
\code{RObject} and it's destructor rather than \code{SEXP}
2525
protect/unprotect).
26+
\item Add rng parameter to Rcpp::export to prevent inclusion of
27+
RNGScope in generated code.
2628
}
2729
}
2830
}

src/attributes.cpp

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,15 @@ namespace attributes {
103103

104104
// Known attribute names & parameters
105105
const char * const kExportAttribute = "export";
106+
const char * const kExportName = "name";
107+
const char * const kExportRng = "rng";
106108
const char * const kDependsAttribute = "depends";
107109
const char * const kPluginsAttribute = "plugins";
108110
const char * const kInterfacesAttribute = "interfaces";
109111
const char * const kInterfaceR = "r";
110112
const char * const kInterfaceCpp = "cpp";
113+
const char * const kParamValueFalse = "false";
114+
const char * const kParamValueTrue = "true";
111115

112116
// Type info
113117
class Type {
@@ -244,10 +248,29 @@ namespace attributes {
244248
}
245249

246250
std::string exportedName() const {
247-
if (!params().empty())
251+
252+
// check for explicit name parameter
253+
if (hasParameter(kExportName))
254+
{
255+
return paramNamed(kExportName).value();
256+
}
257+
// otherwise un-named parameter in the first slot
258+
else if (!params().empty() && params()[0].value().empty())
259+
{
248260
return params()[0].name();
249-
else
261+
}
262+
// otherwise the actual function name
263+
{
250264
return function().name();
265+
}
266+
}
267+
268+
bool rng() const {
269+
Param rngParam = paramNamed(kExportRng);
270+
if (!rngParam.empty())
271+
return rngParam.value() != kParamValueFalse;
272+
else
273+
return true;
251274
}
252275

253276
const std::vector<std::string>& roxygen() const { return roxygen_; }
@@ -740,6 +763,7 @@ namespace attributes {
740763
}
741764
else {
742765
name_ = paramText;
766+
trimWhitespace(&name_);
743767
stripQuotes(&name_);
744768
}
745769
}
@@ -984,6 +1008,34 @@ namespace attributes {
9841008
function = parseFunction(lineNumber + 1);
9851009
else
9861010
rcppExportWarning("No function found", lineNumber);
1011+
1012+
// validate parameters
1013+
for (std::size_t i=0; i<params.size(); i++) {
1014+
1015+
std::string name = params[i].name();
1016+
std::string value = params[i].value();
1017+
1018+
// un-named parameter that isn't the first parameter
1019+
if (value.empty() && (i > 0)) {
1020+
rcppExportWarning("No value specified for parameter '" +
1021+
name + "'",
1022+
lineNumber);
1023+
}
1024+
// parameter that isn't name or rng
1025+
else if (!value.empty() &&
1026+
(name != kExportName) &&
1027+
(name != kExportRng)) {
1028+
rcppExportWarning("Unrecognized parameter '" + name + "'",
1029+
lineNumber);
1030+
}
1031+
// rng that isn't true or false
1032+
else if (name == kExportRng) {
1033+
if (value != kParamValueFalse && value != kParamValueTrue) {
1034+
rcppExportWarning("rng value must be true or false",
1035+
lineNumber);
1036+
}
1037+
}
1038+
}
9871039
}
9881040

9891041
// validate interfaces parameter
@@ -1014,7 +1066,7 @@ namespace attributes {
10141066
std::vector<Param> SourceFileAttributesParser::parseParameters(
10151067
const std::string& input) {
10161068

1017-
const std::string delimiters(" ,");
1069+
const std::string delimiters(",");
10181070

10191071
std::vector<Param> params;
10201072
std::string::size_type current;
@@ -1694,7 +1746,8 @@ namespace attributes {
16941746
ostr() << " }" << std::endl;
16951747
ostr() << " RObject __result;" << std::endl;
16961748
ostr() << " {" << std::endl;
1697-
ostr() << " RNGScope __rngScope;" << std::endl;
1749+
if (it->rng())
1750+
ostr() << " RNGScope __rngScope;" << std::endl;
16981751
ostr() << " __result = " << ptrName << "(";
16991752

17001753
const std::vector<Argument>& args = function.arguments();
@@ -2226,7 +2279,7 @@ namespace attributes {
22262279
ostr << "BEGIN_RCPP" << std::endl;
22272280
if (!function.type().isVoid())
22282281
ostr << " Rcpp::RObject __result;" << std::endl;
2229-
if (!cppInterface)
2282+
if (!cppInterface && attribute.rng())
22302283
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
22312284
for (size_t i = 0; i<arguments.size(); i++) {
22322285
const Argument& argument = arguments[i];
@@ -2268,7 +2321,8 @@ namespace attributes {
22682321
<< std::endl;
22692322
ostr << " SEXP __result;" << std::endl;
22702323
ostr << " {" << std::endl;
2271-
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
2324+
if (attribute.rng())
2325+
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
22722326
ostr << " __result = PROTECT(" << funcName
22732327
<< kTrySuffix << "(";
22742328
for (size_t i = 0; i<arguments.size(); i++) {

0 commit comments

Comments
 (0)