@@ -154,6 +154,7 @@ namespace attributes {
154154 const char * const kExportName = " name" ;
155155 const char * const kExportRng = " rng" ;
156156 const char * const kExportInvisible = " invisible" ;
157+ const char * const kExportSignature = " signature" ;
157158 const char * const kInitAttribute = " init" ;
158159 const char * const kDependsAttribute = " depends" ;
159160 const char * const kPluginsAttribute = " plugins" ;
@@ -164,6 +165,8 @@ namespace attributes {
164165 const char * const kParamValueTrue = " true" ;
165166 const char * const kParamValueFALSE = " FALSE" ;
166167 const char * const kParamValueTRUE = " TRUE" ;
168+ const char * const kParamBlockStart = " {;" ;
169+ const char * const kParamBlockEnd = " }" ;
167170
168171 // Type info
169172 class Type {
@@ -390,8 +393,19 @@ namespace attributes {
390393 else
391394 return false ;
392395 }
393-
396+
394397 const std::vector<std::string>& roxygen () const { return roxygen_; }
398+
399+ std::string customRSignature () const {
400+ Param sigParam = paramNamed (kExportSignature );
401+ std::string sig = sigParam.value ();
402+ trimWhitespace (&sig);
403+ if (sig.back () == ' }' )
404+ sig = sig.substr (0 , sig.size ()-1 );
405+ if (sig.front () == ' {' )
406+ sig.erase (0 ,1 );
407+ return sig;
408+ }
395409
396410 private:
397411 std::string name_;
@@ -1312,7 +1326,6 @@ namespace attributes {
13121326 Attribute SourceFileAttributesParser::parseAttribute (
13131327 const std::vector<std::string>& match,
13141328 int lineNumber) {
1315-
13161329 // Attribute name
13171330 std::string name = match[1 ];
13181331
@@ -1368,7 +1381,8 @@ namespace attributes {
13681381 else if (!value.empty () &&
13691382 (name != kExportName ) &&
13701383 (name != kExportRng ) &&
1371- (name != kExportInvisible )) {
1384+ (name != kExportInvisible ) &&
1385+ (name != kExportSignature )) {
13721386 rcppExportWarning (" Unrecognized parameter '" + name + " '" ,
13731387 lineNumber);
13741388 }
@@ -1422,19 +1436,22 @@ namespace attributes {
14221436 // Parse attribute parameters
14231437 std::vector<Param> SourceFileAttributesParser::parseParameters (
14241438 const std::string& input) {
1425-
1439+ std::string::size_type blockstart = input.find_first_of (kParamBlockStart );
1440+ std::string::size_type blockend = input.find_last_of (kParamBlockEnd );
1441+
14261442 const std::string delimiters (" ," );
1427-
14281443 std::vector<Param> params;
14291444 std::string::size_type current;
14301445 std::string::size_type next = -1 ;
14311446 do { // #nocov
14321447 next = input.find_first_not_of (delimiters, next + 1 );
14331448 if (next == std::string::npos)
14341449 break ; // #nocov
1435- next -= 1 ;
1436- current = next + 1 ;
1437- next = input.find_first_of (delimiters, current);
1450+ current = next;
1451+ do {
1452+ next = input.find_first_of (delimiters, next + 1 );
1453+ } while ((next >= blockstart) && (next <= blockend) &&
1454+ (next != std::string::npos));
14381455 params.push_back (Param (input.substr (current, next - current)));
14391456 } while (next != std::string::npos);
14401457
@@ -2443,7 +2460,12 @@ namespace attributes {
24432460
24442461 // build the parameter list
24452462 std::string args = generateRArgList (function);
2446-
2463+
2464+ // check if has a custom signature
2465+ if (attribute.hasParameter (kExportSignature )) {
2466+ args = attribute.customRSignature ();
2467+ }
2468+
24472469 // determine the function name
24482470 std::string name = attribute.exportedName ();
24492471
@@ -3352,11 +3374,19 @@ namespace {
33523374 if (!attribute.isExportedFunction ())
33533375 continue ;
33543376 const Function& function = attribute.function ();
3355-
3377+
3378+ // build the parameter list
3379+ std::string args = generateRArgList (function);
3380+
3381+ // check if has a custom signature
3382+ if (attribute.hasParameter (kExportSignature )) {
3383+ args = attribute.customRSignature ();
3384+ }
3385+
33563386 // export the function
33573387 ostr << attribute.exportedName ()
33583388 << " <- Rcpp:::sourceCppFunction("
3359- << " function(" << generateRArgList (function) << " ) {}, "
3389+ << " function(" << args << " ) {}, "
33603390 << (function.type ().isVoid () ? " TRUE" : " FALSE" ) << " , "
33613391 << dllInfo << " , "
33623392 << " '" << contextId_ + " _" + function.name ()
0 commit comments