diff --git a/ChangeLog b/ChangeLog index 8e96f9fd7..c1d8335c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2016-08-02 James J Balamuta + + * R/Rcpp.package.skeleton.R: Added autogeneration warning + * src/attributes.cpp: Fixed invalid C++ Identifiers and modified + export header to warn against hand edits + * vignettes/Rcpp-package.Rnw: Updated code generation snippets + * man/Rcpp.package.skeleton.Rd: Add warning on hand edits to the + autogenerated RcppExports files. + * man/compileAttributes.Rd: Idem + 2016-08-01 Nathan Russell * inst/include/Rcpp/vector/Vector.h: Added decreasing option for Vector diff --git a/R/Rcpp.package.skeleton.R b/R/Rcpp.package.skeleton.R index 6877b33bd..54f326b5d 100644 --- a/R/Rcpp.package.skeleton.R +++ b/R/Rcpp.package.skeleton.R @@ -144,6 +144,8 @@ Rcpp.package.skeleton <- function(name = "anRpackage", list = character(), message(" >> added example src file using Rcpp attributes") compileAttributes(root) message(" >> compiled Rcpp attributes") + message(" >> do NOT modify by hand either RcppExports.cpp or ", + "RcppExports.R") } else { header <- readLines(file.path(skeleton, "rcpp_hello_world.h")) header <- gsub("@PKG@", name, header, fixed = TRUE) diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 8d7af9218..31cf2343f 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -10,9 +10,13 @@ \item The \code{NORET} macro is now defined if it was not already defined by R (Kevin fixing issue \ghit{512}). \item Environment functions get() & find() now accept a Symbol - (James Joseph Balamuta in \ghpr{513} addressing issue \ghit{326}). + (James Balamuta in \ghpr{513} addressing issue \ghit{326}). \item Several uses of \code{Rf_eval} were replaced by the preferred \code{Rcpp::Rcpp_eval} (Qiang in PR \ghpr{523} closing \ghit{498}). + \item Improved Autogeneration Warning for RcppExports + (James Balamuta in \ghpr{528} addressing issue \ghit{526}). + \item Fixed invalid C++ prefix identifiers in auto-generated code + (James Balamuta in \ghpr{528} addressing issue \ghit{387}). } \item Changes in Rcpp unit tests \itemize{ diff --git a/man/Rcpp.package.skeleton.Rd b/man/Rcpp.package.skeleton.Rd index 843a75d71..0119ba82a 100644 --- a/man/Rcpp.package.skeleton.Rd +++ b/man/Rcpp.package.skeleton.Rd @@ -65,8 +65,11 @@ Rcpp.package.skeleton(name = "anRpackage", list = character(), If the \code{attributes} argument is \code{TRUE}, then rather than generate the example files as described above, a single \samp{rcpp_hello_world.cpp} file is created in the \samp{src} directory and it's attributes are - compiled using the \code{\link{compileAttributes}} function, so files - \samp{RcppExports.R} and \samp{RcppExports.cpp} are generated as well. + compiled using the \code{\link{compileAttributes}} function. This leads to + the files \samp{RcppExports.R} and \samp{RcppExports.cpp} being generated. + They are automatically regenerated from \emph{scratch} each time + \code{\link{compileAttributes}} is called. Therefore, one should + \strong{not} modify by hand either of the \samp{RcppExports} files. If the \code{module} argument is \code{TRUE}, a sample Rcpp module will be generated as well. diff --git a/man/compileAttributes.Rd b/man/compileAttributes.Rd index 1773a2444..890d807be 100644 --- a/man/compileAttributes.Rd +++ b/man/compileAttributes.Rd @@ -21,7 +21,7 @@ compileAttributes(pkgdir = ".", verbose = getOption("verbose")) \details{ The source files in the package directory given by \code{pkgdir} are scanned for attributes and code is generated as required based on the attributes. - For C++ functions adorned with the \code{Rcpp::export} attribute, the C++ and R source code required to bind to the function from R is generated and added (respectively) to \code{src/RcppExports.cpp} or \code{R/RcppExports.R}. + For C++ functions adorned with the \code{Rcpp::export} attribute, the C++ and R source code required to bind to the function from R is generated and added (respectively) to \code{src/RcppExports.cpp} or \code{R/RcppExports.R}. Both of these files are automatically generated from \emph{scratch} each time \code{compiledAttributes} is run. In order to access the declarations for custom \code{Rcpp::as} and \code{Rcpp::wrap} handlers the \code{compileAttributes} function will also call any \link[inline:plugins]{inline plugins} available for packages listed in the \code{LinkingTo} field of the \code{DESCRIPTION} file. } diff --git a/src/attributes.cpp b/src/attributes.cpp index 4c54c75ac..6edd1df70 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -1772,8 +1772,9 @@ namespace attributes { // write header/preamble std::ostringstream headerStream; - headerStream << commentPrefix_ << " This file was generated by " - << "Rcpp::compileAttributes" << std::endl; + headerStream << commentPrefix_ << " Generated by using " + << "Rcpp::compileAttributes()" + << " -> do not edit by hand" << std::endl; headerStream << commentPrefix_ << " Generator token: " << generatorToken() << std::endl << std::endl; if (!preamble.empty()) @@ -2045,11 +2046,11 @@ namespace attributes { << getCCallable(packageCpp() + "_" + function.name()) << ";" << std::endl; ostr() << " }" << std::endl; - ostr() << " RObject __result;" << std::endl; + ostr() << " RObject rcpp_result_gen;" << std::endl; ostr() << " {" << std::endl; if (it->rng()) - ostr() << " RNGScope __rngScope;" << std::endl; - ostr() << " __result = " << ptrName << "("; + ostr() << " RNGScope RCPP_rngScope_gen;" << std::endl; + ostr() << " rcpp_result_gen = " << ptrName << "("; const std::vector& args = function.arguments(); for (std::size_t i = 0; i(" - << "__result).c_str());" + << "rcpp_result_gen).c_str());" << std::endl; if (!function.type().isVoid()) { ostr() << " return Rcpp::as<" << function.type() << " >" - << "(__result);" << std::endl; + << "(rcpp_result_gen);" << std::endl; } ostr() << " }" << std::endl << std::endl; @@ -2148,7 +2149,7 @@ namespace attributes { } std::string CppExportsIncludeGenerator::getHeaderGuard() const { - return "__" + packageCpp() + "_RcppExports_h__"; + return "_RCPP_" + packageCpp() + "_RCPPEXPORTS_H_GEN_"; } CppPackageIncludeGenerator::CppPackageIncludeGenerator( @@ -2196,7 +2197,7 @@ namespace attributes { } std::string CppPackageIncludeGenerator::getHeaderGuard() const { - return "__" + packageCpp() + "_h__"; + return "_RCPP_" + packageCpp() + "_H_GEN_"; } RExportsGenerator::RExportsGenerator(const std::string& packageDir, @@ -2582,9 +2583,9 @@ namespace attributes { ostr << args << ") {" << std::endl; ostr << "BEGIN_RCPP" << std::endl; if (!function.type().isVoid()) - ostr << " Rcpp::RObject __result;" << std::endl; + ostr << " Rcpp::RObject rcpp_result_gen;" << std::endl; if (!cppInterface && attribute.rng()) - ostr << " Rcpp::RNGScope __rngScope;" << std::endl; + ostr << " Rcpp::RNGScope rcpp_rngScope_gen;" << std::endl; for (size_t i = 0; i>= -// This file was generated by Rcpp::compileAttributes +// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include @@ -184,10 +184,10 @@ using namespace Rcpp; List rcpp_hello_world(); RcppExport SEXP mypackage_rcpp_hello_world() { BEGIN_RCPP - Rcpp::RObject __result; - Rcpp::RNGScope __rngScope; - __result = Rcpp::wrap(rcpp_hello_world()); - return __result; + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + rcpp_result_gen = Rcpp::wrap(rcpp_hello_world()); + return rcpp_result_gen; END_RCPP } @ @@ -205,7 +205,7 @@ The \rdoc{Rcpp}{compileAttributes} also generates \proglang{R} code that uses the \proglang{C++} function. <>= -# This file was generated by Rcpp::compileAttributes +# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 rcpp_hello_world <- function() {