@@ -103,11 +103,17 @@ namespace attributes {
103
103
104
104
// Known attribute names & parameters
105
105
const char * const kExportAttribute = " export" ;
106
+ const char * const kExportName = " name" ;
107
+ const char * const kExportRng = " rng" ;
106
108
const char * const kDependsAttribute = " depends" ;
107
109
const char * const kPluginsAttribute = " plugins" ;
108
110
const char * const kInterfacesAttribute = " interfaces" ;
109
111
const char * const kInterfaceR = " r" ;
110
112
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" ;
111
117
112
118
// Type info
113
119
class Type {
@@ -244,10 +250,30 @@ namespace attributes {
244
250
}
245
251
246
252
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
+ {
248
262
return params ()[0 ].name ();
249
- else
263
+ }
264
+ // otherwise the actual function name
265
+ {
250
266
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 ;
251
277
}
252
278
253
279
const std::vector<std::string>& roxygen () const { return roxygen_; }
@@ -740,6 +766,7 @@ namespace attributes {
740
766
}
741
767
else {
742
768
name_ = paramText;
769
+ trimWhitespace (&name_);
743
770
stripQuotes (&name_);
744
771
}
745
772
}
@@ -984,6 +1011,37 @@ namespace attributes {
984
1011
function = parseFunction (lineNumber + 1 );
985
1012
else
986
1013
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
+ }
987
1045
}
988
1046
989
1047
// validate interfaces parameter
@@ -1014,7 +1072,7 @@ namespace attributes {
1014
1072
std::vector<Param> SourceFileAttributesParser::parseParameters (
1015
1073
const std::string& input) {
1016
1074
1017
- const std::string delimiters (" ," );
1075
+ const std::string delimiters (" ," );
1018
1076
1019
1077
std::vector<Param> params;
1020
1078
std::string::size_type current;
@@ -1694,7 +1752,8 @@ namespace attributes {
1694
1752
ostr () << " }" << std::endl;
1695
1753
ostr () << " RObject __result;" << std::endl;
1696
1754
ostr () << " {" << std::endl;
1697
- ostr () << " RNGScope __rngScope;" << std::endl;
1755
+ if (it->rng ())
1756
+ ostr () << " RNGScope __rngScope;" << std::endl;
1698
1757
ostr () << " __result = " << ptrName << " (" ;
1699
1758
1700
1759
const std::vector<Argument>& args = function.arguments ();
@@ -2226,7 +2285,7 @@ namespace attributes {
2226
2285
ostr << " BEGIN_RCPP" << std::endl;
2227
2286
if (!function.type ().isVoid ())
2228
2287
ostr << " Rcpp::RObject __result;" << std::endl;
2229
- if (!cppInterface)
2288
+ if (!cppInterface && attribute. rng () )
2230
2289
ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
2231
2290
for (size_t i = 0 ; i<arguments.size (); i++) {
2232
2291
const Argument& argument = arguments[i];
@@ -2268,7 +2327,8 @@ namespace attributes {
2268
2327
<< std::endl;
2269
2328
ostr << " SEXP __result;" << std::endl;
2270
2329
ostr << " {" << std::endl;
2271
- ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
2330
+ if (attribute.rng ())
2331
+ ostr << " Rcpp::RNGScope __rngScope;" << std::endl;
2272
2332
ostr << " __result = PROTECT(" << funcName
2273
2333
<< kTrySuffix << " (" ;
2274
2334
for (size_t i = 0 ; i<arguments.size (); i++) {
0 commit comments