Skip to content

Commit b28a3da

Browse files
committed
Merge pull request #253 from RcppCore/feature/attributes-export-rng
Add rng parameter to Rcpp::export to prevent inclusion of RNGScope in generated code
2 parents 458e053 + d8b7582 commit b28a3da

File tree

5 files changed

+75
-10
lines changed

5 files changed

+75
-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: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,17 @@ 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";
115+
const char * const kParamValueFALSE = "FALSE";
116+
const char * const kParamValueTRUE = "TRUE";
111117

112118
// Type info
113119
class Type {
@@ -244,10 +250,30 @@ namespace attributes {
244250
}
245251

246252
std::string exportedName() const {
247-
if (!params().empty())
253+
254+
// check for explicit name parameter
255+
if (hasParameter(kExportName))
256+
{
257+
return paramNamed(kExportName).value();
258+
}
259+
// otherwise un-named parameter in the first slot
260+
else if (!params().empty() && params()[0].value().empty())
261+
{
248262
return params()[0].name();
249-
else
263+
}
264+
// otherwise the actual function name
265+
{
250266
return function().name();
267+
}
268+
}
269+
270+
bool rng() const {
271+
Param rngParam = paramNamed(kExportRng);
272+
if (!rngParam.empty())
273+
return rngParam.value() == kParamValueTrue ||
274+
rngParam.value() == kParamValueTRUE;
275+
else
276+
return true;
251277
}
252278

253279
const std::vector<std::string>& roxygen() const { return roxygen_; }
@@ -740,6 +766,7 @@ namespace attributes {
740766
}
741767
else {
742768
name_ = paramText;
769+
trimWhitespace(&name_);
743770
stripQuotes(&name_);
744771
}
745772
}
@@ -984,6 +1011,37 @@ namespace attributes {
9841011
function = parseFunction(lineNumber + 1);
9851012
else
9861013
rcppExportWarning("No function found", lineNumber);
1014+
1015+
// validate parameters
1016+
for (std::size_t i=0; i<params.size(); i++) {
1017+
1018+
std::string name = params[i].name();
1019+
std::string value = params[i].value();
1020+
1021+
// un-named parameter that isn't the first parameter
1022+
if (value.empty() && (i > 0)) {
1023+
rcppExportWarning("No value specified for parameter '" +
1024+
name + "'",
1025+
lineNumber);
1026+
}
1027+
// parameter that isn't name or rng
1028+
else if (!value.empty() &&
1029+
(name != kExportName) &&
1030+
(name != kExportRng)) {
1031+
rcppExportWarning("Unrecognized parameter '" + name + "'",
1032+
lineNumber);
1033+
}
1034+
// rng that isn't true or false
1035+
else if (name == kExportRng) {
1036+
if (value != kParamValueFalse &&
1037+
value != kParamValueTrue &&
1038+
value != kParamValueFALSE &&
1039+
value != kParamValueTRUE) {
1040+
rcppExportWarning("rng value must be true or false",
1041+
lineNumber);
1042+
}
1043+
}
1044+
}
9871045
}
9881046

9891047
// validate interfaces parameter
@@ -1014,7 +1072,7 @@ namespace attributes {
10141072
std::vector<Param> SourceFileAttributesParser::parseParameters(
10151073
const std::string& input) {
10161074

1017-
const std::string delimiters(" ,");
1075+
const std::string delimiters(",");
10181076

10191077
std::vector<Param> params;
10201078
std::string::size_type current;
@@ -1694,7 +1752,8 @@ namespace attributes {
16941752
ostr() << " }" << std::endl;
16951753
ostr() << " RObject __result;" << std::endl;
16961754
ostr() << " {" << std::endl;
1697-
ostr() << " RNGScope __rngScope;" << std::endl;
1755+
if (it->rng())
1756+
ostr() << " RNGScope __rngScope;" << std::endl;
16981757
ostr() << " __result = " << ptrName << "(";
16991758

17001759
const std::vector<Argument>& args = function.arguments();
@@ -2226,7 +2285,7 @@ namespace attributes {
22262285
ostr << "BEGIN_RCPP" << std::endl;
22272286
if (!function.type().isVoid())
22282287
ostr << " Rcpp::RObject __result;" << std::endl;
2229-
if (!cppInterface)
2288+
if (!cppInterface && attribute.rng())
22302289
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
22312290
for (size_t i = 0; i<arguments.size(); i++) {
22322291
const Argument& argument = arguments[i];
@@ -2268,7 +2327,8 @@ namespace attributes {
22682327
<< std::endl;
22692328
ostr << " SEXP __result;" << std::endl;
22702329
ostr << " {" << std::endl;
2271-
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
2330+
if (attribute.rng())
2331+
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
22722332
ostr << " __result = PROTECT(" << funcName
22732333
<< kTrySuffix << "(";
22742334
for (size_t i = 0; i<arguments.size(); i++) {

0 commit comments

Comments
 (0)