[Rcpp-commits] r4073 - in pkg/Rcpp: . src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Dec 4 16:35:33 CET 2012
Author: jjallaire
Date: 2012-12-04 16:35:33 +0100 (Tue, 04 Dec 2012)
New Revision: 4073
Added:
pkg/Rcpp/src/AttributesGen.cpp
pkg/Rcpp/src/AttributesGen.h
pkg/Rcpp/src/AttributesTypes.h
pkg/Rcpp/src/AttributesUtil.h
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/src/Attributes.cpp
pkg/Rcpp/src/AttributesParser.cpp
pkg/Rcpp/src/AttributesParser.h
Log:
move generators into their own source file
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2012-12-04 15:16:01 UTC (rev 4072)
+++ pkg/Rcpp/ChangeLog 2012-12-04 15:35:33 UTC (rev 4073)
@@ -1,3 +1,13 @@
+2012-12-04 JJ Allaire <jj at rstudio.org>
+
+ * src/Attributes.cpp: move generators into their own source file
+ * src/AttributesGen.cpp: move generators into their own source file
+ * src/AttributesGen.h: move generators into their own source file
+ * src/AttributesParser.cpp: move generators into their own source file
+ * src/AttributesParser.h: move generators into their own source file
+ * src/AttributesTypes.h: new header for attributes types
+ * src/AttributesUtil.h: new header for attributes utilities
+
2012-12-04 Romain Francois <romain at r-enthusiasts.com>
* include/Rcpp/hash/hash.h: new implementation of IndexHash, based on
Modified: pkg/Rcpp/src/Attributes.cpp
===================================================================
--- pkg/Rcpp/src/Attributes.cpp 2012-12-04 15:16:01 UTC (rev 4072)
+++ pkg/Rcpp/src/Attributes.cpp 2012-12-04 15:35:33 UTC (rev 4073)
@@ -19,61 +19,47 @@
// You should have received a copy of the GNU General Public License
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
#include <fstream>
#include <cstring>
#include <map>
#include <algorithm>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
+#include <Rcpp.h>
-#include <Rcpp/Function.h>
-#include <Rcpp/Environment.h>
-#include <Rcpp/exceptions.h>
-
+#include "AttributesGen.h"
#include "AttributesParser.h"
+#include "AttributesUtil.h"
-using namespace Rcpp::attributes_parser;
-
-// General utilities
-namespace {
-
+// provide implementations for util
+namespace Rcpp {
+namespace attributes {
+
// Utility class for getting file existence and last modified time
- class FileInfo {
- public:
- explicit FileInfo(const std::string& path)
- : path_(path), exists_(false), lastModified_(0)
- {
+ FileInfo::FileInfo(const std::string& path)
+ : path_(path), exists_(false), lastModified_(0)
+ {
#ifdef _WIN32
- struct _stat buffer;
- int result = _stat(path.c_str(), &buffer);
+ struct _stat buffer;
+ int result = _stat(path.c_str(), &buffer);
#else
- struct stat buffer;
- int result = stat(path.c_str(), &buffer);
+ struct stat buffer;
+ int result = stat(path.c_str(), &buffer);
#endif
- if (result != 0) {
- if (errno == ENOENT)
- exists_ = false;
- else
- throw Rcpp::file_io_error(errno, path);
- } else {
- exists_ = true;
- lastModified_ = buffer.st_mtime;
- }
+ if (result != 0) {
+ if (errno == ENOENT)
+ exists_ = false;
+ else
+ throw Rcpp::file_io_error(errno, path);
+ } else {
+ exists_ = true;
+ lastModified_ = buffer.st_mtime;
}
-
- std::string path() const { return path_; }
- bool exists() const { return exists_; }
- time_t lastModified() const { return lastModified_; }
-
- private:
- std::string path_;
- bool exists_;
- time_t lastModified_;
- };
-
+ }
+
// Remove a file (call back into R for this)
bool removeFile(const std::string& path) {
if (FileInfo(path).exists()) {
@@ -92,801 +78,47 @@
Rcpp::Function mkdir = Rcpp::Environment::base_env()["dir.create"];
mkdir(path, Rcpp::Named("recursive") = true);
}
- }
+ }
-
- // Check if the passed attribute represents an exported function
- bool isExportedFunction(const Attribute& attribute) {
- return (attribute.name() == kExportAttribute) &&
- !attribute.function().empty();
+ // Known whitespace chars
+ const char * const kWhitespaceChars = " \f\n\r\t\v";
+
+ // Query whether a character is whitespace
+ bool isWhitespace(char ch) {
+ return std::strchr(kWhitespaceChars, ch) != NULL;
}
- // Determine the exported name for a function
- std::string exportedName(const Attribute& attribute) {
- if (!attribute.params().empty())
- return attribute.params()[0].name();
- else
- return attribute.function().name();
- }
-
- // Generate function entries for passed attributes
- void generateCppModuleFunctions(std::ostream& ostr,
- const SourceFileAttributes& attributes,
- bool verbose)
- {
- for(std::vector<Attribute>::const_iterator
- it = attributes.begin(); it != attributes.end(); ++it) {
-
- // verify this is an exported function
- if (isExportedFunction(*it)) {
-
- // verbose output
- const Function& function = it->function();
- if (verbose)
- Rcpp::Rcout << " " << function << std::endl;
-
- // add module function export
- ostr << " Rcpp::function(\"" << exportedName(*it) << "\", &"
- << function.name();
-
- // add information on arguments
- const std::vector<Argument>& args =
- it->function().arguments();
- ostr << ", Rcpp::List::create(";
- for (size_t i=0; i<args.size(); i++) {
- const Argument& arg = args[i];
- ostr << "Rcpp::Named(\"" << arg.name() << "\")";
- if (!arg.defaultValue().empty())
- ostr << " = " << arg.defaultValue();
- if (i != (args.size()-1))
- ostr << ", ";
- }
- ostr << ")";
- ostr << ");" << std::endl;
-
- }
- }
- }
-} // anonymous namespace
-
-
-// Implementation helpers for compileAttributes
-namespace {
-
- // Generate placeholder function declaration (for roxygen)
- void generateRoxygenPlaceholder(std::ostream& ostr,
- const Attribute& attribute) {
+ // Trim a string
+ void trimWhitespace(std::string* pStr) {
- ostr << exportedName(attribute) << "<- function(";
- const std::vector<Argument>& args = attribute.function().arguments();
- for (std::size_t i=0; i<args.size(); i++) {
- ostr << args[i].name();
- if (i != (args.size()-1))
- ostr << ", ";
- }
- ostr << ") {}" << std::endl;
- }
-
- // Generate roxygen
- void generateRoxygen(std::ostream& ostr,
- const SourceFileAttributes& attributes) {
+ // skip empty case
+ if (pStr->empty())
+ return;
- for(std::vector<Attribute>::const_iterator
- it = attributes.begin(); it != attributes.end(); ++it) {
-
- if (isExportedFunction(*it) && !it->roxygen().empty()) {
- ostr << std::endl;
- for (std::size_t i=0; i<it->roxygen().size(); i++)
- ostr << it->roxygen()[i] << std::endl;
- generateRoxygenPlaceholder(ostr, *it);
- ostr << std::endl;
- }
- }
- }
-
- // Abstract class which manages writing of code for compileAttributes
- class ExportsGenerator {
- protected:
- ExportsGenerator(const std::string& targetFile,
- const std::string& package,
- const std::string& commentPrefix)
- : targetFile_(targetFile),
- package_(package),
- commentPrefix_(commentPrefix) {
+ // trim right
+ std::string::size_type pos = pStr->find_last_not_of(kWhitespaceChars);
+ if (pos != std::string::npos)
+ pStr->erase(pos + 1);
- // read the existing target file if it exists
- if (FileInfo(targetFile_).exists()) {
- std::ifstream ifs(targetFile_.c_str());
- if (ifs.fail())
- throw Rcpp::file_io_error(targetFile_);
- std::stringstream buffer;
- buffer << ifs.rdbuf();
- existingCode_ = buffer.str();
- }
-
- // see if this is safe to overwite and throw if it isn't
- if (!isSafeToOverwrite())
- throw Rcpp::file_exists(targetFile_);
- }
-
- private:
- // prohibit copying
- ExportsGenerator(const ExportsGenerator&);
- ExportsGenerator& operator=(const ExportsGenerator&);
-
- public:
- virtual ~ExportsGenerator() {}
-
- // Name of target file
- const std::string& targetFile() const {
- return targetFile_;
- }
-
- // Name of package
- const std::string& package() const {
- return package_;
- }
-
- // Abstract interface for code generation
- virtual void writeBegin() = 0;
- virtual void writeFunctions(const SourceFileAttributes &attributes,
- bool verbose) = 0;
- virtual void writeEnd() = 0;
-
- virtual bool commit(const std::vector<std::string>& includes) = 0;
-
- // Remove the generated file entirely
- bool remove() {
- return removeFile(targetFile_);
- }
-
- // Allow generator to appear as a std::ostream&
- operator std::ostream&() {
- return codeStream_;
- }
-
- protected:
-
- // Allow access to the output stream
- std::ostream& ostr() {
- return codeStream_;
- }
-
- // Shared knowledge about the special export validation function
- std::string exportValidationFunction() {
- return "validateExported";
- }
- std::string exportValidationFunctionRegisteredName() {
- return "RcppExports_" + exportValidationFunction();
- }
-
- // Commit the stream -- is a no-op if the existing code is identical
- // to the generated code. Returns true if data was written and false
- // if it wasn't (throws exception on io error)
- bool commit(const std::string& preamble = std::string()) {
-
- // get the generated code
- std::string code = codeStream_.str();
-
- // if there is no generated code AND the exports file does not
- // currently exist then do nothing
- if (code.empty() && !FileInfo(targetFile_).exists())
- return false;
-
- // write header/preamble
- std::ostringstream headerStream;
- headerStream << commentPrefix_ << " This file was generated by "
- << "Rcpp::compileAttributes" << std::endl;
- headerStream << commentPrefix_ << " Generator token: "
- << generatorToken() << std::endl << std::endl;
- if (!preamble.empty())
- headerStream << preamble;
-
- // get generated code and only write it if there was a change
- std::string generatedCode = headerStream.str() + code;
- if (generatedCode != existingCode_) {
- // open the file
- std::ofstream ofs(targetFile_.c_str(),
- std::ofstream::out | std::ofstream::trunc);
- if (ofs.fail())
- throw Rcpp::file_io_error(targetFile_);
-
- // write generated code and return
- ofs << generatedCode;
- ofs.close();
- return true;
- }
- else {
- return false;
- }
- }
-
- private:
-
- // Check whether it's safe to overwrite this file (i.e. whether we
- // generated the file in the first place)
- bool isSafeToOverwrite() const {
- return existingCode_.empty() ||
- (existingCode_.find(generatorToken()) != std::string::npos);
- }
-
- // UUID that we write into a comment within the file (so that we can
- // strongly identify that a file was generated by us before overwriting it)
- std::string generatorToken() const {
- return "10BE3573-1514-4C36-9D1C-5A225CD40393";
- }
-
- private:
- std::string targetFile_;
- std::string package_;
- std::string commentPrefix_;
- std::string existingCode_;
- std::ostringstream codeStream_;
- };
-
- // Class which manages generating RcppExports.cpp
- class CppExportsGenerator : public ExportsGenerator {
- public:
- explicit CppExportsGenerator(const std::string& packageDir,
- const std::string& package,
- const std::string& fileSep)
- : ExportsGenerator(
- packageDir + fileSep + "src" + fileSep + "RcppExports.cpp",
- package,
- "//")
- {
- }
-
- virtual void writeBegin() {
- ostr() << "RCPP_MODULE(" << package() << "_RcppExports) {"
- << std::endl;
- }
-
- virtual void writeFunctions(const SourceFileAttributes &attributes,
- bool verbose) {
- // verbose output if requested
- if (verbose) {
- Rcpp::Rcout << "Exports from " << attributes.sourceFile() << ":"
- << std::endl;
- }
-
- // generate functions
- generateCppModuleFunctions(ostr(), attributes, verbose);
-
- // track prototypes/signatures for inclusion in the preamble
- for (SourceFileAttributes::const_iterator
- it = attributes.begin(); it != attributes.end(); ++it) {
- if (isExportedFunction(*it)) {
-
- // prototypes
- std::ostringstream ostr;
- ostr << it->function();
- prototypes_.push_back(ostr.str());
-
- // signatures
- if (!it->function().isHidden()) {
- signatures_.push_back(
- it->function().signature(exportedName(*it)));
- }
- }
- }
-
- // verbose if requested
- if (verbose)
- Rcpp::Rcout << std::endl;
- }
-
- virtual void writeEnd() {
-
- // add our export validation helper
- ostr() << " Rcpp::function(\""
- << exportValidationFunctionRegisteredName() << "\", &"
- << exportValidationFunction() << ");" << std::endl;
-
- ostr() << "}" << std::endl;
- }
-
- virtual bool commit(const std::vector<std::string>& includes) {
-
- // includes
- std::ostringstream ostr;
- if (!includes.empty()) {
- for (std::size_t i=0;i<includes.size(); i++)
- ostr << includes[i] << std::endl;
- }
- ostr << "#include <string>" << std::endl;
- ostr << "#include <set>" << std::endl;
- ostr << std::endl;
-
- // always bring in Rcpp
- ostr << "using namespace Rcpp;" << std::endl << std::endl;
-
- // prototypes
- if (!prototypes_.empty()) {
- for (std::size_t i=0;i<prototypes_.size(); i++)
- ostr << prototypes_[i] << ";" << std::endl;
- ostr << std::endl;
- }
-
- // generate a function that can be used to validate exported
- // functions and their signatures prior to looking up with
- // GetCppCallable (otherwise inconsistent signatures between
- // client and library would cause a crash)
- ostr << "static bool " << exportValidationFunction()
- << "(const std::string& sig)" << " {" << std::endl;
- ostr << " static std::set<std::string> signatures;"
- << std::endl;
- ostr << " if (signatures.empty()) {" << std::endl;
- for (std::size_t i=0;i<signatures_.size(); i++) {
- ostr << " signatures.insert(\"" << signatures_[i]
- << "\");" << std::endl;
- }
- ostr << " }" << std::endl;
- ostr << " return signatures.find(sig) != signatures.end();"
- << std::endl;
- ostr << "}" << std::endl << std::endl;
-
- // commit with preamble
- return ExportsGenerator::commit(ostr.str());
- }
-
- private:
- std::vector<std::string> prototypes_;
- std::vector<std::string> signatures_;
- };
-
- // Class which manages generating PackageName_RcppExports.h header file
- const char * const kRcppExportsSuffix = "_RcppExports.h";
- class CppExportsIncludeGenerator : public ExportsGenerator {
- public:
- CppExportsIncludeGenerator(const std::string& packageDir,
- const std::string& package,
- const std::string& fileSep)
- : ExportsGenerator(
- packageDir + fileSep + "inst" + fileSep + "include" +
- fileSep + package + kRcppExportsSuffix,
- package,
- "//")
- {
- includeDir_ = packageDir + fileSep + "inst" + fileSep + "include";
- hasCppInterface_ = false;
- }
-
- virtual void writeBegin() {
- ostr() << "namespace " << package() << " {"
- << std::endl << std::endl;
-
- // Import Rcpp into this namespace. This allows declarations to
- // be written without fully qualifying all Rcpp types. The only
- // negative side-effect is that when this package's namespace
- // is imported it will also pull in Rcpp. However since this is
- // opt-in and represents a general desire to do namespace aliasing
- // this seems okay
- ostr() << " using namespace Rcpp;" << std::endl << std::endl;
-
- // Write our export validation helper function. Putting it in
- // an anonymous namespace will hide it from callers and give
- // it per-translation unit linkage
- ostr() << " namespace {" << std::endl;
- ostr() << " void " << exportValidationFunction()
- << "(const std::string& sig) {" << std::endl;
- std::string ptrName = "p_" + exportValidationFunction();
- ostr() << " static bool(" << "*" << ptrName
- << ")(const std::string&) = "
- << getCppCallable(exportValidationFunctionRegisteredName())
- << ";" << std::endl;
- ostr() << " if (!" << ptrName << "(sig))" << std::endl;
- ostr() << " throw Rcpp::function_not_exported(\""
- << "Function '\" + sig + \"' not found in " << package()
- << "\");" << std::endl;
- ostr() << " }" << std::endl;
-
- ostr() << " }" << std::endl << std::endl;
- }
-
- virtual void writeFunctions(const SourceFileAttributes &attributes,
- bool verbose) {
-
- // don't write anything if there is no C++ interface
- if (!attributes.hasInterface(kInterfaceCpp))
- return;
-
- // there is a C++ interface so set flag indicating so
- hasCppInterface_ = true;
-
- for(std::vector<Attribute>::const_iterator
- it = attributes.begin(); it != attributes.end(); ++it) {
-
- if (isExportedFunction(*it)) {
-
- Function function =
- it->function().renamedTo(exportedName(*it));
-
- // if it's hidden then don't generate a C++ interface
- if (function.isHidden())
- continue;
-
- ostr() << " inline " << function << " {"
- << std::endl;
-
- std::string ptrName = "p_" + function.name();
- ostr() << " static " << function.signature(ptrName);
- ostr() << " = NULL;" << std::endl;
- ostr() << " if (" << ptrName << " == NULL) {"
- << std::endl;
- ostr() << " " << exportValidationFunction()
- << "(\"" << function.signature() << "\");"
- << std::endl;
- ostr() << " " << ptrName << " = "
- << getCppCallable(function.name()) << ";"
- << std::endl;
- ostr() << " }" << std::endl;
- ostr() << " return " << ptrName << "(";
-
- const std::vector<Argument>& args = function.arguments();
- for (std::size_t i = 0; i<args.size(); i++) {
- ostr() << args[i].name();
- if (i != (args.size()-1))
- ostr() << ",";
- }
-
- ostr() << ");" << std::endl;
- ostr() << " }" << std::endl << std::endl;
- }
- }
- }
-
- virtual void writeEnd() {
- ostr() << "}" << std::endl;
- ostr() << std::endl;
- ostr() << "#endif // " << getHeaderGuard() << std::endl;
- }
-
- virtual bool commit(const std::vector<std::string>& includes) {
-
- if (hasCppInterface_) {
-
- // create the include dir if necessary
- createDirectory(includeDir_);
-
- // generate preamble
- std::ostringstream ostr;
-
- // header guard
- std::string guard = getHeaderGuard();
- ostr << "#ifndef " << guard << std::endl;
- ostr << "#define " << guard << std::endl << std::endl;
-
- // includes
- if (!includes.empty()) {
- for (std::size_t i=0;i<includes.size(); i++)
- ostr << includes[i] << std::endl;
- ostr << std::endl;
- }
-
- // commit with preamble
- return ExportsGenerator::commit(ostr.str());
- }
- else {
- return ExportsGenerator::remove();
- }
- }
-
- private:
-
- std::string getCppCallable(const std::string& function) const {
- std::ostringstream ostr;
- ostr << "Rcpp::GetCppCallable"
- << "(\"" << package() << "\", "
- << "\"" << package() + "_RcppExports\", "
- << "\"" << function << "\")";
- return ostr.str();
- }
-
- std::string getHeaderGuard() const {
- return package() + "_RcppExports_h";
- }
-
- private:
- std::string includeDir_;
- bool hasCppInterface_;
- };
-
- // Class which manages generating PackageName_RcppExports.h header file
- class CppPackageIncludeGenerator : public ExportsGenerator {
- public:
- CppPackageIncludeGenerator(const std::string& packageDir,
- const std::string& package,
- const std::string& fileSep)
- : ExportsGenerator(
- packageDir + fileSep + "inst" + fileSep + "include" +
- fileSep + package + ".h",
- package,
- "//")
- {
- includeDir_ = packageDir + fileSep + "inst" + fileSep + "include";
- hasCppInterface_ = false;
- }
-
- virtual void writeBegin() {
- }
-
- virtual void writeFunctions(const SourceFileAttributes &attributes,
- bool verbose) {
- // See if there is a C++ interface exported by any attributes
- if (attributes.hasInterface(kInterfaceCpp))
- hasCppInterface_ = true;
- }
-
- virtual void writeEnd() {
- if (hasCppInterface_) {
- // header guard
- std::string guard = getHeaderGuard();
- ostr() << "#ifndef " << guard << std::endl;
- ostr() << "#define " << guard << std::endl << std::endl;
-
- ostr() << "#include \"" << package() << kRcppExportsSuffix
- << "\"" << std::endl;
-
- ostr() << std::endl;
- ostr() << "#endif // " << getHeaderGuard() << std::endl;
- }
- }
-
- virtual bool commit(const std::vector<std::string>& includes) {
-
- if (hasCppInterface_) {
-
- // create the include dir if necessary
- createDirectory(includeDir_);
-
- // commit
- return ExportsGenerator::commit();
- }
- else {
- return ExportsGenerator::remove();
- }
- }
-
- private:
-
- std::string getHeaderGuard() const {
- return package() + "_h";
- }
-
- private:
- std::string includeDir_;
- bool hasCppInterface_;
- };
-
-
- // Class which manages generator RcppExports.R
- class RExportsGenerator : public ExportsGenerator {
- public:
- explicit RExportsGenerator(const std::string& packageDir,
- const std::string& package,
- const std::string& fileSep)
- : ExportsGenerator(
- packageDir + fileSep + "R" + fileSep + "RcppExports.R",
- package,
- "#")
- {
- }
-
- virtual void writeBegin() {
- }
-
- virtual void writeFunctions(const SourceFileAttributes &attributes,
- bool verbose) {
-
- // add to exported functions if we have an R interface
- if (attributes.hasInterface(kInterfaceR)) {
-
- // track exported functions
- for (SourceFileAttributes::const_iterator
- it = attributes.begin(); it != attributes.end(); ++it) {
- if (isExportedFunction(*it)) {
- rExports_.push_back(exportedName(*it));
- }
- }
-
- // generate roxygen
- generateRoxygen(ostr(), attributes);
- }
- }
-
- virtual void writeEnd() {
-
- ostr() << "Rcpp::loadModule(\"" << package() << "_RcppExports\", ";
- if (rExports_.size() > 0) {
- ostr() << std::endl;
- ostr() << " what = c(";
- for (size_t i=0; i<rExports_.size(); i++) {
- if (i != 0)
- ostr() << " ";
- ostr() << "\"" << rExports_[i] << "\"";
- if (i != (rExports_.size()-1))
- ostr() << "," << std::endl;
- }
- ostr() << "))" << std::endl;
- }
- else {
- ostr() << "what = character())";
- }
- }
-
- virtual bool commit(const std::vector<std::string>& includes) {
- return ExportsGenerator::commit();
- }
-
- private:
- std::vector<std::string> rExports_;
- };
-
- // Class to manage and dispatch to a list of generators
- class ExportsGenerators {
- public:
- typedef std::vector<ExportsGenerator*>::iterator Itr;
-
- ExportsGenerators() {}
-
- virtual ~ExportsGenerators() {
- try {
- for(Itr it = generators_.begin(); it != generators_.end(); ++it)
- delete *it;
- generators_.clear();
- }
- catch(...) {}
- }
-
- void add(ExportsGenerator* pGenerator) {
- generators_.push_back(pGenerator);
- }
-
- void writeBegin() {
- for(Itr it = generators_.begin(); it != generators_.end(); ++it)
- (*it)->writeBegin();
- }
-
- void writeFunctions(const SourceFileAttributes &attributes,
- bool verbose) {
- for(Itr it = generators_.begin(); it != generators_.end(); ++it)
- (*it)->writeFunctions(attributes, verbose);
- }
-
- void writeEnd() {
- for(Itr it = generators_.begin(); it != generators_.end(); ++it)
- (*it)->writeEnd();
- }
-
- // Commit and return a list of the files that were updated
- std::vector<std::string> commit(
- const std::vector<std::string>& includes) {
-
- std::vector<std::string> updated;
-
- for(Itr it = generators_.begin(); it != generators_.end(); ++it) {
- if ((*it)->commit(includes))
- updated.push_back((*it)->targetFile());
- }
-
- return updated;
- }
-
- // Remove and return a list of files that were removed
- std::vector<std::string> remove() {
- std::vector<std::string> removed;
- for(Itr it = generators_.begin(); it != generators_.end(); ++it) {
- if ((*it)->remove())
- removed.push_back((*it)->targetFile());
- }
- return removed;
- }
-
- private:
- // prohibit copying
- ExportsGenerators(const ExportsGenerators&);
- ExportsGenerators& operator=(const ExportsGenerators&);
-
- private:
- std::vector<ExportsGenerator*> generators_;
- };
-
-} // anonymous namespace
-
-
-// Compile the attributes within the specified package directory into
-// RcppExports.cpp and RcppExports.R
-RcppExport SEXP compileAttributes(SEXP sPackageDir,
- SEXP sPackageName,
- SEXP sCppFiles,
- SEXP sCppFileBasenames,
- SEXP sIncludes,
- SEXP sVerbose,
- SEXP sPlatform) {
-BEGIN_RCPP
- // arguments
- std::string packageDir = Rcpp::as<std::string>(sPackageDir);
- std::string packageName = Rcpp::as<std::string>(sPackageName);
- std::vector<std::string> cppFiles =
- Rcpp::as<std::vector<std::string> >(sCppFiles);
- std::vector<std::string> cppFileBasenames =
- Rcpp::as<std::vector<std::string> >(sCppFileBasenames);
- std::vector<std::string> includes =
- Rcpp::as<std::vector<std::string> >(sIncludes);
- bool verbose = Rcpp::as<bool>(sVerbose);
- Rcpp::List platform = Rcpp::as<Rcpp::List>(sPlatform);
- std::string fileSep = Rcpp::as<std::string>(platform["file.sep"]);
-
- // initialize generators
- ExportsGenerators generators;
- generators.add(new CppExportsGenerator(packageDir, packageName, fileSep));
- generators.add(new RExportsGenerator(packageDir, packageName, fileSep));
-
- // catch file exists exception if the include file already exists
- // and we are unable to overwrite it
- try {
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/rcpp -r 4073
More information about the Rcpp-commits
mailing list