Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2015-02-12 JJ Allaire <jj@rstudio.org>

* DESCRIPTION: bump version
* src/attributes.cpp: Add rng parameter to Rcpp::export to
prevent inclusion of RNGScope in generated code.

2015-02-06 Kevin Ushey <kevinushey@gmail.com>

* inst/include/Rcpp/vector/Subsetter.h: compare CHARSXP pointers
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: Rcpp
Title: Seamless R and C++ Integration
Version: 0.11.4.4
Version: 0.11.4.5
Date: 2015-02-03
Author: Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey,
Douglas Bates, and John Chambers
Expand Down
3 changes: 0 additions & 3 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,6 @@ Attributes

o Add unit tests

o Add random = false parameter to Rcpp::export once we support parsing
key/value pairs in attribute parameters

o Detect useDynLib .registration = TRUE and in that case emit .Call
wrappers as symbols rather than strings w/ PACKAGE =

Expand Down
2 changes: 2 additions & 0 deletions inst/NEWS.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
\item Simplify generated attributes code for \code{RNGScope} (use
\code{RObject} and it's destructor rather than \code{SEXP}
protect/unprotect).
\item Add rng parameter to Rcpp::export to prevent inclusion of
RNGScope in generated code.
}
}
}
Expand Down
72 changes: 66 additions & 6 deletions src/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,17 @@ namespace attributes {

// Known attribute names & parameters
const char * const kExportAttribute = "export";
const char * const kExportName = "name";
const char * const kExportRng = "rng";
const char * const kDependsAttribute = "depends";
const char * const kPluginsAttribute = "plugins";
const char * const kInterfacesAttribute = "interfaces";
const char * const kInterfaceR = "r";
const char * const kInterfaceCpp = "cpp";
const char * const kParamValueFalse = "false";
const char * const kParamValueTrue = "true";
const char * const kParamValueFALSE = "FALSE";
const char * const kParamValueTRUE = "TRUE";

// Type info
class Type {
Expand Down Expand Up @@ -244,10 +250,30 @@ namespace attributes {
}

std::string exportedName() const {
if (!params().empty())

// check for explicit name parameter
if (hasParameter(kExportName))
{
return paramNamed(kExportName).value();
}
// otherwise un-named parameter in the first slot
else if (!params().empty() && params()[0].value().empty())
{
return params()[0].name();
else
}
// otherwise the actual function name
{
return function().name();
}
}

bool rng() const {
Param rngParam = paramNamed(kExportRng);
if (!rngParam.empty())
return rngParam.value() == kParamValueTrue ||
rngParam.value() == kParamValueTRUE;
else
return true;
}

const std::vector<std::string>& roxygen() const { return roxygen_; }
Expand Down Expand Up @@ -740,6 +766,7 @@ namespace attributes {
}
else {
name_ = paramText;
trimWhitespace(&name_);
stripQuotes(&name_);
}
}
Expand Down Expand Up @@ -984,6 +1011,37 @@ namespace attributes {
function = parseFunction(lineNumber + 1);
else
rcppExportWarning("No function found", lineNumber);

// validate parameters
for (std::size_t i=0; i<params.size(); i++) {

std::string name = params[i].name();
std::string value = params[i].value();

// un-named parameter that isn't the first parameter
if (value.empty() && (i > 0)) {
rcppExportWarning("No value specified for parameter '" +
name + "'",
lineNumber);
}
// parameter that isn't name or rng
else if (!value.empty() &&
(name != kExportName) &&
(name != kExportRng)) {
rcppExportWarning("Unrecognized parameter '" + name + "'",
lineNumber);
}
// rng that isn't true or false
else if (name == kExportRng) {
if (value != kParamValueFalse &&
value != kParamValueTrue &&
value != kParamValueFALSE &&
value != kParamValueTRUE) {
rcppExportWarning("rng value must be true or false",
lineNumber);
}
}
}
}

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

const std::string delimiters(" ,");
const std::string delimiters(",");

std::vector<Param> params;
std::string::size_type current;
Expand Down Expand Up @@ -1694,7 +1752,8 @@ namespace attributes {
ostr() << " }" << std::endl;
ostr() << " RObject __result;" << std::endl;
ostr() << " {" << std::endl;
ostr() << " RNGScope __rngScope;" << std::endl;
if (it->rng())
ostr() << " RNGScope __rngScope;" << std::endl;
ostr() << " __result = " << ptrName << "(";

const std::vector<Argument>& args = function.arguments();
Expand Down Expand Up @@ -2226,7 +2285,7 @@ namespace attributes {
ostr << "BEGIN_RCPP" << std::endl;
if (!function.type().isVoid())
ostr << " Rcpp::RObject __result;" << std::endl;
if (!cppInterface)
if (!cppInterface && attribute.rng())
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
for (size_t i = 0; i<arguments.size(); i++) {
const Argument& argument = arguments[i];
Expand Down Expand Up @@ -2268,7 +2327,8 @@ namespace attributes {
<< std::endl;
ostr << " SEXP __result;" << std::endl;
ostr << " {" << std::endl;
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
if (attribute.rng())
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
ostr << " __result = PROTECT(" << funcName
<< kTrySuffix << "(";
for (size_t i = 0; i<arguments.size(); i++) {
Expand Down