Skip to content

Commit 847152c

Browse files
committed
Correctly handle signature termination characters ('{' or ';') contained in quotes
1 parent b204a68 commit 847152c

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
* Rcpp.Rproj: don't use devtools mode in RStudio (enables the
44
Test Package command to invoke the RUnit based test-suite)
5+
* src/attributes.cpp: Correctly handle signature termination
6+
characters ('{' or ';') contained in quotes
57

68
2015-07-16 Kevin Ushey <[email protected]>
79

inst/NEWS.Rd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
libraries.
2525
\item The \code{evalCpp} function now also supports the \code{plugins}
2626
argument.
27+
\item Correctly handle signature termination characters ('\{' or ';') contained
28+
in quotes.
2729
}
2830
\item Changes in Rcpp Documentation:
2931
\itemize{

src/attributes.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,19 +1460,34 @@ namespace attributes {
14601460
// Parse the text of a function signature from the specified line
14611461
std::string SourceFileAttributesParser::parseSignature(size_t lineNumber) {
14621462

1463-
// Look for the next {
1463+
// Look for the signature termination ({ or ; not inside quotes)
1464+
// on this line and then subsequent lines if necessary
14641465
std::string signature;
14651466
for (int i = lineNumber; i<lines_.size(); i++) {
14661467
std::string line;
14671468
line = lines_[i];
1468-
std::string::size_type end = line.find_first_of("{;");
1469-
if (end == std::string::npos) {
1470-
signature.append(line);
1471-
signature.push_back(' ');
1472-
} else {
1473-
signature.append(line.substr(0, end));
1474-
return signature;
1469+
bool insideQuotes = false;
1470+
char prevChar = 0;
1471+
// scan for { or ; not inside quotes
1472+
for (size_t c = 0; c < line.length(); ++c) {
1473+
// alias character
1474+
char ch = line.at(c);
1475+
// update quotes state
1476+
if (ch == '"' && prevChar != '\\')
1477+
insideQuotes = !insideQuotes;
1478+
// found signature termination, append and return
1479+
if (!insideQuotes && ((ch == '{') || (ch == ';'))) {
1480+
signature.append(line.substr(0, c));
1481+
return signature;
1482+
}
1483+
// record prev char (used to check for escaped quote i.e. \")
1484+
prevChar = ch;
14751485
}
1486+
1487+
// if we didn't find a terminator on this line then just append the line
1488+
// and move on to the next line
1489+
signature.append(line);
1490+
signature.push_back(' ');
14761491
}
14771492

14781493
// Not found

0 commit comments

Comments
 (0)