@@ -154,6 +154,7 @@ namespace attributes {
154
154
const char * const kExportName = " name" ;
155
155
const char * const kExportRng = " rng" ;
156
156
const char * const kExportInvisible = " invisible" ;
157
+ const char * const kExportSignature = " signature" ;
157
158
const char * const kInitAttribute = " init" ;
158
159
const char * const kDependsAttribute = " depends" ;
159
160
const char * const kPluginsAttribute = " plugins" ;
@@ -164,6 +165,8 @@ namespace attributes {
164
165
const char * const kParamValueTrue = " true" ;
165
166
const char * const kParamValueFALSE = " FALSE" ;
166
167
const char * const kParamValueTRUE = " TRUE" ;
168
+ const char * const kParamBlockStart = " {;" ;
169
+ const char * const kParamBlockEnd = " }" ;
167
170
168
171
// Type info
169
172
class Type {
@@ -390,8 +393,19 @@ namespace attributes {
390
393
else
391
394
return false ;
392
395
}
393
-
396
+
394
397
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
+ }
395
409
396
410
private:
397
411
std::string name_;
@@ -1312,7 +1326,6 @@ namespace attributes {
1312
1326
Attribute SourceFileAttributesParser::parseAttribute (
1313
1327
const std::vector<std::string>& match,
1314
1328
int lineNumber) {
1315
-
1316
1329
// Attribute name
1317
1330
std::string name = match[1 ];
1318
1331
@@ -1368,7 +1381,8 @@ namespace attributes {
1368
1381
else if (!value.empty () &&
1369
1382
(name != kExportName ) &&
1370
1383
(name != kExportRng ) &&
1371
- (name != kExportInvisible )) {
1384
+ (name != kExportInvisible ) &&
1385
+ (name != kExportSignature )) {
1372
1386
rcppExportWarning (" Unrecognized parameter '" + name + " '" ,
1373
1387
lineNumber);
1374
1388
}
@@ -1422,19 +1436,22 @@ namespace attributes {
1422
1436
// Parse attribute parameters
1423
1437
std::vector<Param> SourceFileAttributesParser::parseParameters (
1424
1438
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
+
1426
1442
const std::string delimiters (" ," );
1427
-
1428
1443
std::vector<Param> params;
1429
1444
std::string::size_type current;
1430
1445
std::string::size_type next = -1 ;
1431
1446
do { // #nocov
1432
1447
next = input.find_first_not_of (delimiters, next + 1 );
1433
1448
if (next == std::string::npos)
1434
1449
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));
1438
1455
params.push_back (Param (input.substr (current, next - current)));
1439
1456
} while (next != std::string::npos);
1440
1457
@@ -2443,7 +2460,12 @@ namespace attributes {
2443
2460
2444
2461
// build the parameter list
2445
2462
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
+
2447
2469
// determine the function name
2448
2470
std::string name = attribute.exportedName ();
2449
2471
@@ -3352,11 +3374,19 @@ namespace {
3352
3374
if (!attribute.isExportedFunction ())
3353
3375
continue ;
3354
3376
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
+
3356
3386
// export the function
3357
3387
ostr << attribute.exportedName ()
3358
3388
<< " <- Rcpp:::sourceCppFunction("
3359
- << " function(" << generateRArgList (function) << " ) {}, "
3389
+ << " function(" << args << " ) {}, "
3360
3390
<< (function.type ().isVoid () ? " TRUE" : " FALSE" ) << " , "
3361
3391
<< dllInfo << " , "
3362
3392
<< " '" << contextId_ + " _" + function.name ()
0 commit comments