@@ -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