[Rcpp-commits] r3991 - in pkg/Rcpp: . R man src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sun Nov 18 17:32:11 CET 2012
Author: jjallaire
Date: 2012-11-18 17:32:11 +0100 (Sun, 18 Nov 2012)
New Revision: 3991
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/R/Attributes.R
pkg/Rcpp/TODO
pkg/Rcpp/man/sourceCpp.Rd
pkg/Rcpp/src/Attributes.cpp
pkg/Rcpp/src/AttributesParser.cpp
pkg/Rcpp/src/AttributesParser.h
Log:
sourceCpp embedded R code
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2012-11-18 16:16:04 UTC (rev 3990)
+++ pkg/Rcpp/ChangeLog 2012-11-18 16:32:11 UTC (rev 3991)
@@ -1,3 +1,10 @@
+2012-11-18 JJ Allaire <jj at rstudio.org>
+
+ * R/Attributes.R: sourceCpp embedded R code
+ * src/AttributesParser.h: sourceCpp embedded R code
+ * src/AttributesParser.cpp: sourceCpp embedded R code
+ * src/Attributes.cpp: sourceCpp embedded R code
+
2012-11-18 Romain Francois <romain at r-enthusiasts.com>
* include/Rcpp/vector/converter.h: allow CharacterVector::create( NA_STRING )
Modified: pkg/Rcpp/R/Attributes.R
===================================================================
--- pkg/Rcpp/R/Attributes.R 2012-11-18 16:16:04 UTC (rev 3990)
+++ pkg/Rcpp/R/Attributes.R 2012-11-18 16:32:11 UTC (rev 3991)
@@ -140,6 +140,12 @@
env)
}
+ # source the embeddedR
+ if (length(context$embeddedR) > 0) {
+ srcConn <- textConnection(context$embeddedR)
+ source(file=srcConn, print.eval=TRUE)
+ }
+
# return (invisibly) a list of exported functions
invisible(context$exportedFunctions)
}
Modified: pkg/Rcpp/TODO
===================================================================
--- pkg/Rcpp/TODO 2012-11-18 16:16:04 UTC (rev 3990)
+++ pkg/Rcpp/TODO 2012-11-18 16:32:11 UTC (rev 3991)
@@ -152,9 +152,6 @@
o Clarify in 5.1 of vignette that attribute package features still
require Makevars, etc. created by Rcpp.package.skeleton
- o Provide single action to source both C++ and R code (possible
- source_with attribute and/or embed R code in cpp file w/ comment)
-
o Add docstring parameter to Rcpp::export attribute
o Emit warning if sourceCpp finds no exports (control via option)
Modified: pkg/Rcpp/man/sourceCpp.Rd
===================================================================
--- pkg/Rcpp/man/sourceCpp.Rd 2012-11-18 16:16:04 UTC (rev 3990)
+++ pkg/Rcpp/man/sourceCpp.Rd 2012-11-18 16:32:11 UTC (rev 3991)
@@ -39,6 +39,17 @@
If the source file has compilation dependencies on other packages (e.g. \pkg{Matrix}, \pkg{RcppArmadillo}) then an \code{\link[=dependsAttribute]{Rcpp::depends}} attribute should be provided naming these dependencies.
+ It's possible to embed chunks of R code within the C++ that will be sourced alone with the C++ functions. This is done by starting a block comment with the prefix of \code{/*** R}. For example:
+
+\preformatted{
+/*** R
+
+# Call the fibonacci function defined in C++
+fibonacci(10)
+
+*/
+}
+
The \code{sourceCpp} function will not rebuild the shared library if the source file has not changed since the last compilation.
}
@@ -50,6 +61,7 @@
The \code{sourceCpp} function is designed for compiling a standalone source file whose only dependencies are R packages. If you are compiling more than one source file or have external dependencies then you should create an R package rather than using \code{sourceCpp}. Note that the \code{\link[=exportAttribute]{Rcpp::export}} attribute can also be used within packages via the \code{\link{compileAttributes}} function.
If you are sourcing a C++ file from within the \code{src} directory of a package then the package's \code{LinkingTo} dependencies, \code{inst/include}, and \code{src} directories are automatically included in the compilation.
+
}
\seealso{
Modified: pkg/Rcpp/src/Attributes.cpp
===================================================================
--- pkg/Rcpp/src/Attributes.cpp 2012-11-18 16:16:04 UTC (rev 3990)
+++ pkg/Rcpp/src/Attributes.cpp 2012-11-18 16:32:11 UTC (rev 3991)
@@ -920,6 +920,9 @@
depends_.push_back(it->params()[i].name());
}
}
+
+ // capture embededded R
+ embeddedR_ = sourceAttributes.embeddedR();
}
const std::string& moduleName() const {
@@ -955,6 +958,8 @@
}
const std::vector<std::string>& depends() const { return depends_; };
+
+ const std::vector<std::string>& embeddedR() const { return embeddedR_; }
private:
@@ -973,6 +978,7 @@
std::string dynlibExt_;
std::vector<std::string> exportedFunctions_;
std::vector<std::string> depends_;
+ std::vector<std::string> embeddedR_;
};
// Dynlib cache that allows lookup by either file path or code contents
@@ -1087,6 +1093,7 @@
_["cppSourceFilename"] = dynlib.cppSourceFilename(),
_["dynlibFilename"] = dynlib.dynlibFilename(),
_["dynlibPath"] = dynlib.dynlibPath(),
- _["depends"] = dynlib.depends());
+ _["depends"] = dynlib.depends(),
+ _["embeddedR"] = dynlib.embeddedR());
END_RCPP
}
Modified: pkg/Rcpp/src/AttributesParser.cpp
===================================================================
--- pkg/Rcpp/src/AttributesParser.cpp 2012-11-18 16:16:04 UTC (rev 3990)
+++ pkg/Rcpp/src/AttributesParser.cpp 2012-11-18 16:32:11 UTC (rev 3991)
@@ -60,7 +60,18 @@
if ( (quote == '\'' || quote == '\"') && (*(pStr->rbegin()) == quote) )
*pStr = pStr->substr(1, pStr->length()-2);
}
-
+
+ Rcpp::List regexMatches(Rcpp::CharacterVector lines,
+ const std::string& regex)
+ {
+ Rcpp::Environment base("package:base");
+ Rcpp::Function regexec = base["regexec"];
+ Rcpp::Function regmatches = base["regmatches"];
+ Rcpp::RObject result = regexec(regex, lines);
+ Rcpp::List matches = regmatches(lines, result);
+ return matches;
+ }
+
} // anonymous namespace
namespace Rcpp {
@@ -231,12 +242,8 @@
// Scan for attributes
CommentState commentState;
- Rcpp::Environment base("package:base");
- Rcpp::Function regexec = base["regexec"];
- Rcpp::Function regmatches = base["regmatches"];
- Rcpp::RObject result = regexec(
- "^\\s*//\\s+\\[\\[Rcpp::(\\w+)(\\(.*?\\))?\\]\\]\\s*$", lines_);
- Rcpp::List matches = regmatches(lines_, result);
+ Rcpp::List matches = regexMatches(lines_,
+ "^\\s*//\\s+\\[\\[Rcpp::(\\w+)(\\(.*?\\))?\\]\\]\\s*$");
for (int i = 0; i<matches.size(); i++) {
// track whether we are in a comment and bail if we are in one
@@ -272,6 +279,9 @@
}
}
}
+
+ // Parse embedded R
+ embeddedR_ = parseEmbeddedR(lines_, lines);
}
}
@@ -568,6 +578,44 @@
return Type(type, isConst, isReference);
}
+ // Parse embedded R code chunks from a file (receives the lines of the
+ // file as a CharcterVector for using with regexec and as a standard
+ // stl vector for traversal/insepection)
+ std::vector<std::string> SourceFileAttributes::parseEmbeddedR(
+ Rcpp::CharacterVector linesVector,
+ const std::deque<std::string>& lines) {
+ Rcpp::List matches = regexMatches(linesVector,
+ "^\\s*/\\*{3,}\\s+[Rr]\\s*$");
+ bool withinRBlock = false;
+ CommentState commentState;
+ std::vector<std::string> embeddedR;
+
+ for (int i = 0; i<matches.size(); i++) {
+
+ // track comment state
+ std::string line = lines[i];
+ commentState.submitLine(line);
+
+ // is this a line that begins an R code block?
+ const Rcpp::CharacterVector match = matches[i];
+ bool beginRBlock = match.size() > 0;
+
+ // check state and do the right thing
+ if (beginRBlock) {
+ withinRBlock = true;
+ }
+ else if (withinRBlock) {
+ if (commentState.inComment())
+ embeddedR.push_back(line);
+ else
+ withinRBlock = false;
+ }
+ }
+
+ return embeddedR;
+ }
+
+
// Validation helpers
bool SourceFileAttributes::isKnownAttribute(const std::string& name) const {
Modified: pkg/Rcpp/src/AttributesParser.h
===================================================================
--- pkg/Rcpp/src/AttributesParser.h 2012-11-18 16:16:04 UTC (rev 3990)
+++ pkg/Rcpp/src/AttributesParser.h 2012-11-18 16:32:11 UTC (rev 3991)
@@ -210,6 +210,11 @@
else
return false;
}
+
+ // Get lines of embedded R code
+ const std::vector<std::string>& embeddedR() const {
+ return embeddedR_;
+ }
private:
@@ -221,6 +226,9 @@
std::string parseSignature(size_t lineNumber);
std::vector<std::string> parseArguments(const std::string& argText);
Type parseType(const std::string& text);
+ std::vector<std::string> parseEmbeddedR(
+ Rcpp::CharacterVector linesVector,
+ const std::deque<std::string>& lines);
// Validation helpers
bool isKnownAttribute(const std::string& name) const;
@@ -254,6 +262,7 @@
std::string sourceFile_;
CharacterVector lines_;
std::vector<Attribute> attributes_;
+ std::vector<std::string> embeddedR_;
std::vector<std::string> roxygenBuffer_;
};
More information about the Rcpp-commits
mailing list