76 std::string::size_type
pos =
path_.find_last_of(
'.');
77 if (
pos != std::string::npos)
94 return ! (*
this ==
other);
150namespace attributes {
188 return !(*
this ==
other);
194 if(
isConst() ) res +=
"const " ;
230 return !(*
this ==
other);
249 const std::string&
name,
263 return name().find_first_of(
'.') == 0;
275 return !(*
this ==
other);
301 return !(*
this ==
other);
318 const std::vector<Param>&
params,
320 const std::vector<std::string>&
roxygen)
335 return !(*
this ==
other);
365 return params()[0].name();
375 std::replace(
name.begin(),
name.end(),
'.',
'_');
403 if (
sig.empty())
return sig;
404#if __cplusplus < 201103L
405 if (
sig[
sig.size() - 1] ==
'}')
407 if (
sig.back() ==
'}')
411 if (
sig.empty())
return sig;
412#if __cplusplus < 201103L
415 if (
sig.front() ==
'{')
447 virtual const std::vector<std::string>&
modules()
const = 0;
449 virtual const std::vector<std::vector<std::string> >&
roxygenChunks()
const = 0;
467namespace attributes {
505 virtual const std::vector<std::string>&
modules()
const
510 virtual const std::vector<std::vector<std::string> >&
roxygenChunks()
const {
525 return it->hasParameter(name);
596namespace attributes {
631 operator std::ostream&() {
648 return "RcppExport_validate";
682 return "10BE3573-1514-4C36-9D1C-5A225CD40393";
703 virtual void writeEnd(
bool hasPackageInit);
711 const std::string& exportedName,
712 const std::string& name)
const;
736 virtual void writeEnd(
bool hasPackageInit);
742 std::string
getCCallable(
const std::string& function)
const;
757 virtual void writeEnd(
bool hasPackageInit);
778 virtual void writeEnd(
bool hasPackageInit);
792 typedef std::vector<ExportsGenerator*>::iterator
Itr;
805 std::vector<std::string>
commit(
806 const std::vector<std::string>&
includes);
809 std::vector<std::string>
remove();
843namespace attributes {
848 const std::string&
regex)
858 template <
typename Stream>
860 std::ifstream
ifs(file.c_str());
867 template <
typename Collection>
871 while(std::getline(
is,
line)) {
873 if (
line.length() > 0 && *
line.rbegin() ==
'\r')
912 std::stringstream buffer;
918 std::deque<std::string>
lines;
924 linesVector,
"^\\s*#include\\s*\"([^\"]+)\"\\s*$");
929 for (
int i = 0; i<
matches.size(); i++) {
948 std::vector<std::string>
exts;
949 exts.push_back(
".cc");
950 exts.push_back(
".cpp");
951 for (
size_t i = 0; i<
exts.size(); ++i) {
980 std::string sourceFile) {
1005 const std::deque<std::string>&
lines) {
1007 "^\\s*/\\*{3,}\\s*[Rr]\\s*$");
1010 std::vector<std::string> embeddedR;
1012 for (
int i = 0; i<
matches.size(); i++) {
1028 embeddedR.push_back(
line);
1042 std::string Function::signature(
const std::string& name)
const {
1044 std::ostringstream ostr;
1046 ostr <<
type() <<
"(*" <<
name <<
")(";
1049 for (std::size_t i = 0; i<
args.size(); i++) {
1050 ostr <<
args[i].type();
1051 if (i != (
args.size()-1))
1065 if (
pos != std::string::npos ) {
1083 for (std::vector<Param>::const_iterator
1093 if (!type.
empty()) {
1129 if (!function.
empty()) {
1136 const std::vector<Argument>& arguments = function.
arguments();
1137 for (std::size_t i = 0; i<arguments.size(); i++) {
1139 if (i != (arguments.size()-1))
1154 if (!
param.empty()) {
1156 if (!
param.value().empty())
1166 const std::vector<Param>& params =
attribute.params();
1167 if (params.size() > 0) {
1169 for (std::size_t i = 0; i<params.size(); i++) {
1171 if (i != (params.size()-1))
1186 const std::string& sourceFile,
1189 : sourceFile_(sourceFile), hasPackageInit_(
false)
1199 std::stringstream buffer;
1201 std::string
contents = buffer.str();
1204 if (
contents.find(
"[[Rcpp::") != std::string::npos ||
1205 contents.find(
"RCPP_MODULE") != std::string::npos ||
1211 std::deque<std::string>
lines;
1218 "^\\s*//\\s*\\[\\[Rcpp::(\\w+)(\\(.*?\\))?\\]\\]\\s*$");
1219 for (
int i = 0; i<
matches.size(); i++) {
1249 if (
line.find(
"//'") == 0) {
1265 "^\\s*RCPP_MODULE\\s*\\(\\s*(\\w+)\\s*\\).*$");
1277 const char * name =
match[1];
1330 std::copy(
parser.modules().begin(),
1340 const std::vector<std::string>&
match,
1343 std::string name =
match[1];
1352 std::vector<Param> params;
1382 for (std::size_t i=0; i<params.size(); i++) {
1384 std::string name = params[i].name();
1385 std::string value = params[i].value();
1388 if (value.empty() && (i > 0)) {
1394 else if (!value.empty() &&
1427 if (params.empty()) {
1431 for (std::size_t i=0; i<params.size(); i++) {
1432 std::string
param = params[i].name();
1451 const std::string&
input) {
1456 std::vector<Param> params;
1457 std::string::size_type current;
1458 std::string::size_type
next = std::string::npos;
1462 if (
next == std::string::npos)
1468 (
next != std::string::npos));
1473 }
while(
next != std::string::npos);
1495 if (signature.empty()) {
1502 std::string::size_type
endParenLoc = signature.find_last_of(
')');
1503 std::string::size_type
beginParenLoc = signature.find_first_of(
'(');
1517 for (std::string::const_reverse_iterator
1521 if (!name.empty()) {
1535 name.insert(0
U, 1U,
ch);
1552 std::vector<Argument> arguments;
1556 for (std::vector<std::string>::const_iterator
it =
1560 std::string
arg = *
it;
1568 std::string defaultValue;
1569 std::string::size_type
eqPos =
arg.find_first_of(
'=');
1570 if ( (
eqPos != std::string::npos) && ((
eqPos + 1) <
arg.size()) ) {
1571 defaultValue =
arg.substr(
eqPos+1);
1588 if (
pos != std::string::npos) {
1590 std::string::size_type
ref_pos =
arg.substr(
pos).find_last_of(
"&");
1591 if (
ref_pos != std::string::npos) {
1612 arguments.push_back(
Argument(name, type, defaultValue));
1615 return Function(type, name, arguments);
1624 std::string signature;
1631 for (
size_t c = 0;
c <
line.length(); ++
c) {
1639 signature.append(
line.substr(0,
c));
1648 signature.append(
line);
1649 signature.push_back(
' ');
1653 return std::string();
1666 std::vector<std::string>
args;
1669 typedef std::string::const_iterator
it_t;
1676 if ( !
quote && (
ch ==
'"' ||
ch ==
'\''))
1732 std::string type =
text;
1736 bool isConst =
false;
1737 bool isReference =
false;
1759 return Type(type, isConst, isReference);
1783 std::ostringstream ostr;
1786 ostr <<
" for " <<
attribute <<
" attribute";
1810 const std::string&
param,
1826 std::size_t
pos = 0;
1827 while (
pos != std::string::npos) {
1833 std::string token =
inComment() ?
"*/" :
"/*";
1837 if (
pos != std::string::npos) {
1844 pos += token.size();
1858namespace attributes {
1867 const std::string& package,
1869 : targetFile_(targetFile),
1871 packageCpp_(package),
1873 hasCppInterface_(
false) {
1880 std::stringstream buffer;
1881 buffer <<
ifs.rdbuf();
1918 <<
"Rcpp::compileAttributes()"
1919 <<
" -> do not edit by hand" << std::endl;
1930 std::ofstream::out | std::ofstream::trunc);
1957 const std::string& package,
1984 if (
it->isExportedFunction()) {
2002 const std::vector<std::string>& modules = attributes.
modules();
2009 for (std::vector<Attribute>::const_iterator
2011 if (
it->isExportedFunction())
2026 ostr() << std::endl;
2027 ostr() <<
"// validate"
2028 <<
" (ensure exported C++ functions exist before "
2029 <<
"calling them)" << std::endl;
2031 <<
"(const char* sig) { " << std::endl;
2032 ostr() <<
" static std::set<std::string> signatures;"
2034 ostr() <<
" if (signatures.empty()) {" << std::endl;
2038 ostr() <<
" signatures.insert(\""
2040 <<
"\");" << std::endl;
2042 ostr() <<
" }" << std::endl;
2043 ostr() <<
" return signatures.find(sig) != signatures.end();"
2045 ostr() <<
"}" << std::endl;
2049 ostr() << std::endl;
2050 ostr() <<
"// registerCCallable (register entry points for "
2051 "exported C++ functions)" << std::endl;
2053 <<
"() { " << std::endl;
2060 ostr() << std::endl;
2065 ostr() << std::endl;
2066 ostr() <<
" return R_NilValue;" << std::endl;
2067 ostr() <<
"}" << std::endl;
2082 for (std::size_t i=0;i<
modules_.size(); i++) {
2098 for (std::size_t i=0;i<
modules_.size(); i++) {
2104 ostr() << std::endl;
2110 ostr() << std::endl;
2111 ostr() <<
"static const R_CallMethodDef CallEntries[] = {" << std::endl;
2118 for (std::size_t i = 0; i<
callEntries.size(); i++)
2121 ostr() <<
" {NULL, NULL, 0}" << std::endl;
2122 ostr() <<
"};" << std::endl;
2124 ostr() << std::endl;
2130 ostr() <<
";" << std::endl;
2133 ostr() <<
"RcppExport void R_init_" <<
packageCpp() <<
"(DllInfo *dll) {" << std::endl;
2134 ostr() <<
" R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);" << std::endl;
2135 ostr() <<
" R_useDynamicSymbols(dll, FALSE);" << std::endl;
2139 ostr() <<
" " << function.
name() <<
"(dll);" << std::endl;
2141 ostr() <<
"}" << std::endl;
2146 showWarning(
"[[Rcpp::init]] attribute used in a package with an explicit "
2147 "R_init function (Rcpp::init functions will not be called)");
2153 const std::string& exportedName,
2154 const std::string& name)
const {
2155 std::ostringstream
ostr;
2166 std::ostringstream
ostr;
2168 for (std::size_t i=0;i<
includes.size(); i++)
2172 ostr <<
"#include <string>" << std::endl;
2173 ostr <<
"#include <set>" << std::endl;
2178 ostr <<
"using namespace Rcpp;" << std::endl << std::endl;
2188 const std::string& package,
2202 << std::endl << std::endl;
2210 ostr() <<
" using namespace Rcpp;" << std::endl << std::endl;
2215 ostr() <<
" namespace {" << std::endl;
2216 ostr() <<
" void validateSignature(const char* sig) {"
2218 ostr() <<
" Rcpp::Function require = "
2219 <<
"Rcpp::Environment::base_env()[\"require\"];"
2222 <<
"Rcpp::Named(\"quietly\") = true);"
2227 ostr() <<
" typedef int(*" <<
fnType <<
")(const char*);"
2232 <<
"(" <<
fnType <<
")" << std::endl
2235 <<
";" << std::endl;
2236 ostr() <<
" if (!" <<
ptrName <<
"(sig)) {" << std::endl;
2237 ostr() <<
" throw Rcpp::function_not_exported("
2240 <<
"\"C++ function with signature '\" + std::string(sig) + \"' not found in " <<
package()
2241 <<
"\");" << std::endl;
2242 ostr() <<
" }" << std::endl;
2243 ostr() <<
" }" << std::endl;
2245 ostr() <<
" }" << std::endl << std::endl;
2256 for(std::vector<Attribute>::const_iterator
2259 if (
it->isExportedFunction()) {
2268 ostr() <<
" inline " << function <<
" {"
2271 std::string
fnType =
"Ptr_" + function.
name();
2272 ostr() <<
" typedef SEXP(*" <<
fnType <<
")(";
2273 for (
size_t i=0; i<function.
arguments().size(); i++) {
2275 if (i != (function.
arguments().size()-1))
2278 ostr() <<
");" << std::endl;
2286 ostr() <<
" validateSignature"
2287 <<
"(\"" << function.
signature() <<
"\");"
2293 ostr() <<
" }" << std::endl;
2294 ostr() <<
" RObject rcpp_result_gen;" << std::endl;
2295 ostr() <<
" {" << std::endl;
2297 ostr() <<
" RNGScope RCPP_rngScope_gen;" << std::endl;
2298 ostr() <<
" rcpp_result_gen = " <<
ptrName <<
"(";
2301 for (std::size_t i = 0; i<
args.size(); i++) {
2302 ostr() <<
"Shield<SEXP>(Rcpp::wrap(" <<
args[i].name() <<
"))";
2303 if (i != (
args.size()-1))
2307 ostr() <<
");" << std::endl;
2308 ostr() <<
" }" << std::endl;
2310 ostr() <<
" if (rcpp_result_gen.inherits(\"interrupted-error\"))"
2312 <<
" throw Rcpp::internal::InterruptedException();"
2314 ostr() <<
" if (Rcpp::internal::isLongjumpSentinel(rcpp_result_gen))"
2316 <<
" throw Rcpp::LongjumpException(rcpp_result_gen);"
2318 ostr() <<
" if (rcpp_result_gen.inherits(\"try-error\"))"
2320 <<
" throw Rcpp::exception(Rcpp::as<std::string>("
2321 <<
"rcpp_result_gen).c_str());"
2324 ostr() <<
" return Rcpp::as<" << function.
type() <<
" >"
2325 <<
"(rcpp_result_gen);" << std::endl;
2328 ostr() <<
" }" << std::endl << std::endl;
2334 ostr() <<
"}" << std::endl;
2335 ostr() << std::endl;
2340 const std::vector<std::string>&
includes) {
2348 std::ostringstream
ostr;
2352 ostr <<
"#ifndef " <<
guard << std::endl;
2353 ostr <<
"#define " <<
guard << std::endl << std::endl;
2357 for (std::size_t i=0;i<
includes.size(); i++)
2362 std::string
preamble =
"#include \"../inst/include/";
2371 std::string
include =
"#include \"" +
2392 const std::string& function)
const {
2393 std::ostringstream
ostr;
2394 ostr <<
"R_GetCCallable"
2395 <<
"(\"" <<
package() <<
"\", "
2396 <<
"\"" << function <<
"\")";
2401 return "RCPP_" +
packageCpp() +
"_RCPPEXPORTS_H_GEN_";
2406 const std::string& package,
2410 fileSep + dotNameHelper(package) +
".h",
2421 ostr() <<
"#ifndef " <<
guard << std::endl;
2422 ostr() <<
"#define " <<
guard << std::endl << std::endl;
2424 <<
"\"" << std::endl;
2426 ostr() << std::endl;
2450 const std::string& package,
2465 const std::vector<std::vector<std::string> >& roxygenChunks =
2467 for (std::size_t i = 0; i<roxygenChunks.size(); i++) {
2468 const std::vector<std::string>&
chunk = roxygenChunks[i];
2469 for (std::size_t
l = 0;
l <
chunk.size();
l++)
2471 ostr() <<
"NULL" << std::endl << std::endl;
2477 for(std::vector<Attribute>::const_iterator
2487 for (
size_t i=0; i<
attribute.roxygen().size(); i++)
2501 std::string name =
attribute.exportedName();
2507 ostr() << name <<
" <- function(" <<
args <<
") {"
2511 ostr() <<
"invisible(";
2519 ostr() <<
"', " <<
"PACKAGE = '" <<
package() <<
"'";
2524 const std::vector<Argument>& arguments = function.
arguments();
2525 for (
size_t i = 0; i<arguments.size(); i++)
2526 ostr() <<
", " << arguments[i].name();
2530 ostr() << std::endl;
2532 ostr() <<
"}" << std::endl << std::endl;
2540 ostr() <<
"# Register entry points for exported C++ functions"
2542 ostr() <<
"methods::setLoadAction(function(ns) {" << std::endl;
2550 << std::endl <<
"})" << std::endl;
2573 (*it)->writeBegin();
2580 (*it)->writeFunctions(attributes,
verbose);
2585 (*it)->writeEnd(hasPackageInit);
2590 const std::vector<std::string>&
includes) {
2592 std::vector<std::string>
updated;
2596 updated.push_back((*it)->targetFile());
2604 std::vector<std::string>
removed;
2606 if ((*it)->remove())
2607 removed.push_back((*it)->targetFile());
2619 const std::string&
cppArg) {
2635 if (
cppArg.find(
'.') == std::string::npos &&
2636 type !=
"double" && type !=
"float")
2644 return std::string();
2652 std::string create =
"::create";
2656 return std::string();
2666 if (type ==
"CharacterVector")
2667 return "as.character( c" +
args +
")";
2668 if (type ==
"IntegerVector")
2669 return "as.integer( c" +
args +
")";
2670 if (type ==
"NumericVector")
2671 return "as.numeric( c" +
args +
")";
2672 if (type ==
"LogicalVector")
2673 return "as.logical( c" +
args +
")";
2675 return std::string();
2683 std::string
matrix =
"Matrix";
2687 return std::string();
2691 return "matrix" +
args;
2699 else if (
cppArg ==
"false")
2701 else if (
cppArg ==
"R_NilValue")
2703 else if (
cppArg ==
"NA_STRING")
2704 return "NA_character_";
2705 else if (
cppArg ==
"NA_INTEGER")
2706 return "NA_integer_";
2707 else if (
cppArg ==
"NA_LOGICAL")
2708 return "NA_integer_";
2709 else if (
cppArg ==
"NA_REAL")
2712 return std::string();
2730 typedef std::map<std::string, std::string>::const_iterator
Iterator;
2733 if (
loc != std::string::npos) {
2734 return it->second +
cppArg.substr(
it->first.size(), std::string::npos);
2738 return std::string();
2745 const std::string&
cppArg) {
2777 return std::string();
2785 const std::vector<Argument>& arguments = function.
arguments();
2786 for (
size_t i = 0; i<arguments.size(); i++) {
2789 if (!
argument.defaultValue().empty()) {
2792 if (!
rArg.empty()) {
2795 showWarning(
"Unable to parse C++ default value '" +
2796 argument.defaultValue() +
"' for argument "+
2797 argument.name() +
" of function " +
2802 if (i != (arguments.size()-1))
2811 const std::vector<Argument>& arguments = function.
arguments();
2812 for (
size_t i = 0; i<arguments.size(); i++) {
2816 args =
"function(" +
args +
") {}";
2820 Rcpp::Environment::namespace_env(
"methods")[
"formalArgs"];
2838 ostr <<
"#ifdef RCPP_USE_GLOBAL_ROSTREAM" << std::endl;
2839 ostr <<
"Rcpp::Rostream<true>& Rcpp::Rcout = Rcpp::Rcpp_cout_get();";
2841 ostr <<
"Rcpp::Rostream<false>& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();";
2843 ostr <<
"#endif" << std::endl << std::endl;
2855 for(std::vector<Attribute>::const_iterator
2866 ostr <<
"// " << function.
name() << std::endl;
2882 const std::vector<Argument>& arguments = function.
arguments();
2883 for (
size_t i = 0; i<arguments.size(); i++) {
2886 if (i != (arguments.size()-1))
2890 ostr <<
args <<
") {" << std::endl;
2891 ostr <<
"BEGIN_RCPP" << std::endl;
2893 ostr <<
" Rcpp::RObject rcpp_result_gen;" << std::endl;
2895 ostr <<
" Rcpp::RNGScope rcpp_rngScope_gen;" << std::endl;
2896 for (
size_t i = 0; i<arguments.size(); i++) {
2899 ostr <<
" Rcpp::traits::input_parameter< "
2901 <<
"(" <<
argument.name() <<
"SEXP);" << std::endl;
2906 ostr <<
"rcpp_result_gen = Rcpp::wrap(";
2907 ostr << function.
name() <<
"(";
2908 for (
size_t i = 0; i<arguments.size(); i++) {
2911 if (i != (arguments.size()-1))
2916 ostr <<
");" << std::endl;
2920 ostr <<
" return rcpp_result_gen;" << std::endl;
2924 ostr <<
" return R_NilValue;" << std::endl;
2926 ostr << (
cppInterface ?
"END_RCPP_RETURN_ERROR" :
"END_RCPP")
2928 ostr <<
"}" << std::endl;
2932 ostr <<
"RcppExport SEXP " <<
funcName <<
"(" <<
args <<
") {"
2934 ostr <<
" SEXP rcpp_result_gen;" << std::endl;
2935 ostr <<
" {" << std::endl;
2937 ostr <<
" Rcpp::RNGScope rcpp_rngScope_gen;" << std::endl;
2938 ostr <<
" rcpp_result_gen = PROTECT(" <<
funcName
2940 for (
size_t i = 0; i<arguments.size(); i++) {
2943 if (i != (arguments.size()-1))
2946 ostr <<
"));" << std::endl;
2947 ostr <<
" }" << std::endl;
2948 ostr <<
" Rboolean rcpp_isInterrupt_gen = Rf_inherits(rcpp_result_gen, \"interrupted-error\");"
2950 <<
" if (rcpp_isInterrupt_gen) {" << std::endl
2951 <<
" UNPROTECT(1);" << std::endl
2952 <<
" Rf_onintr();" << std::endl
2953 <<
" }" << std::endl
2954 <<
" bool rcpp_isLongjump_gen = Rcpp::internal::isLongjumpSentinel(rcpp_result_gen);" << std::endl
2955 <<
" if (rcpp_isLongjump_gen) {" << std::endl
2957 <<
" Rcpp::internal::resumeJump(rcpp_result_gen);" << std::endl
2958 <<
" }" << std::endl
2959 <<
" Rboolean rcpp_isError_gen = Rf_inherits(rcpp_result_gen, \"try-error\");"
2961 <<
" if (rcpp_isError_gen) {" << std::endl
2962 <<
" SEXP rcpp_msgSEXP_gen = Rf_asChar(rcpp_result_gen);" << std::endl
2963 <<
" UNPROTECT(1);" << std::endl
2964 <<
" Rf_error(\"%s\", CHAR(rcpp_msgSEXP_gen));" << std::endl
2965 <<
" }" << std::endl
2966 <<
" UNPROTECT(1);" << std::endl
2967 <<
" return rcpp_result_gen;" << std::endl
2968 <<
"}" << std::endl;
2982namespace attributes {
2986 : path_(path), exists_(
false), lastModified_(0)
2989 struct _stat buffer;
3038 if (
pStr->empty())
return;
3040 size_t len =
pStr->length();
3049 if (
idx == std::string::npos)
return;
3057 while (
idx < len - 1) {
3088 if (
pos != std::string::npos)
3098 if (
pStr->length() < 2)
3107 if (
str.length() < 2)
3127 size_t len =
str.length();
3128 if (len < 3)
return false;
3130 if (
idx == std::string::npos)
return false;
3133 if (len - 2 <
idx)
return false;
3159 class SourceCppDynlib {
3161 SourceCppDynlib() {}
3163 SourceCppDynlib(
const std::string& cacheDir,
3164 const std::string& cppSourcePath,
3166 : cppSourcePath_(cppSourcePath)
3170 FileInfo cppSourceFilenameInfo(cppSourcePath_);
3171 if (!cppSourceFilenameInfo.exists())
3175 Rcpp::Function basename = Rcpp::Environment::base_env()[
"basename"];
3183 Rcpp::Function tempfile = Rcpp::Environment::base_env()[
"tempfile"];
3185 std::replace(buildDirectory_.begin(), buildDirectory_.end(),
'\\',
'/');
3186 Rcpp::Function dircreate = Rcpp::Environment::base_env()[
"dir.create"];
3187 dircreate(buildDirectory_);
3190 contextId_ =
"sourceCpp_" + uniqueToken(cacheDir);
3193 regenerateSource(cacheDir);
3197 explicit SourceCppDynlib(
const Rcpp::List& dynlib)
3199 using namespace Rcpp;
3201 cppSourcePath_ = as<std::string>(dynlib[
"cppSourcePath"]);
3202 generatedCpp_ = as<std::string>(dynlib[
"generatedCpp"]);
3203 cppSourceFilename_ = as<std::string>(dynlib[
"cppSourceFilename"]);
3204 contextId_ = as<std::string>(dynlib[
"contextId"]);
3205 buildDirectory_ = as<std::string>(dynlib[
"buildDirectory"]);
3206 fileSep_ = as<std::string>(dynlib[
"fileSep"]);
3207 dynlibFilename_ = as<std::string>(dynlib[
"dynlibFilename"]);
3208 previousDynlibFilename_ = as<std::string>(dynlib[
"previousDynlibFilename"]);
3209 dynlibExt_ = as<std::string>(dynlib[
"dynlibExt"]);
3210 exportedFunctions_ = as<std::vector<std::string> >(dynlib[
"exportedFunctions"]);
3211 modules_ = as<std::vector<std::string> >(dynlib[
"modules"]);
3212 depends_ = as<std::vector<std::string> >(dynlib[
"depends"]);
3213 plugins_ = as<std::vector<std::string> >(dynlib[
"plugins"]);
3214 embeddedR_ = as<std::vector<std::string> >(dynlib[
"embeddedR"]);
3215 List sourceDependencies = as<List>(dynlib[
"sourceDependencies"]);
3216 for (R_xlen_t i = 0; i<sourceDependencies.length(); i++) {
3217 List fileInfo = as<List>(sourceDependencies.at(i));
3218 sourceDependencies_.push_back(
FileInfo(fileInfo));
3224 using namespace Rcpp;
3226 dynlib[
"cppSourcePath"] = cppSourcePath_;
3227 dynlib[
"generatedCpp"] = generatedCpp_;
3228 dynlib[
"cppSourceFilename"] = cppSourceFilename_;
3229 dynlib[
"contextId"] = contextId_;
3230 dynlib[
"buildDirectory"] = buildDirectory_;
3231 dynlib[
"fileSep"] = fileSep_;
3232 dynlib[
"dynlibFilename"] = dynlibFilename_;
3233 dynlib[
"previousDynlibFilename"] = previousDynlibFilename_;
3234 dynlib[
"dynlibExt"] = dynlibExt_;
3235 dynlib[
"exportedFunctions"] = exportedFunctions_;
3236 dynlib[
"modules"] = modules_;
3237 dynlib[
"depends"] = depends_;
3238 dynlib[
"plugins"] = plugins_;
3239 dynlib[
"embeddedR"] = embeddedR_;
3240 List sourceDependencies;
3241 for (std::size_t i = 0; i<sourceDependencies_.size(); i++) {
3242 FileInfo fileInfo = sourceDependencies_.
at(i);
3245 dynlib[
"sourceDependencies"] = sourceDependencies;
3250 bool isEmpty()
const {
return cppSourcePath_.empty(); }
3252 bool isBuilt()
const {
return FileInfo(dynlibPath()).
exists(); };
3254 bool isSourceDirty()
const {
3256 if (
FileInfo(cppSourcePath_).lastModified() >
3257 FileInfo(generatedCppSourcePath()).lastModified())
3265 std::vector<FileInfo> sourceDependencies = parseSourceDependencies(
3267 if (sourceDependencies != sourceDependencies_)
3274 void regenerateSource(
const std::string& cacheDir) {
3277 previousDynlibFilename_ = dynlibFilename_;
3278 dynlibFilename_ =
"sourceCpp_" + uniqueToken(cacheDir) + dynlibExt_;
3281 Rcpp::Function filecopy = Rcpp::Environment::base_env()[
"file.copy"];
3282 filecopy(cppSourcePath_, generatedCppSourcePath(),
true,
Rcpp::_[
"copy.mode"] =
false);
3288 std::ostringstream ostr;
3290 ostr << std::endl << std::endl;
3291 ostr <<
"#include <Rcpp.h>" << std::endl;
3294 generateCpp(ostr, sourceAttributes,
true,
false, contextId_);
3295 generatedCpp_ = ostr.str();
3296 std::ofstream cppOfs(generatedCppSourcePath().c_str(),
3297 std::ofstream::out | std::ofstream::app);
3300 cppOfs << generatedCpp_;
3304 std::ofstream rOfs(generatedRSourcePath().c_str(),
3305 std::ofstream::out | std::ofstream::trunc);
3310 std::string dllInfo =
"`." + contextId_ +
"_DLLInfo`";
3311 rOfs << dllInfo <<
" <- dyn.load('" << dynlibPath() <<
"')"
3312 << std::endl << std::endl;
3315 generateR(rOfs, sourceAttributes, dllInfo);
3318 rOfs << std::endl <<
"rm(" << dllInfo <<
")"
3324 exportedFunctions_.clear();
3328 it = sourceAttributes.begin(); it != sourceAttributes.end(); ++it) {
3331 exportedFunctions_.push_back(it->exportedName());
3334 for (
size_t i = 0; i<it->params().size(); ++i)
3335 depends_.push_back(it->params()[i].name());
3339 for (
size_t i = 0; i<it->params().size(); ++i)
3340 plugins_.push_back(it->params()[i].name());
3345 modules_ = sourceAttributes.modules();
3348 embeddedR_ = sourceAttributes.embeddedR();
3351 sourceDependencies_ = sourceAttributes.sourceDependencies();
3354 const std::string& contextId()
const {
3358 const std::string& cppSourcePath()
const {
3359 return cppSourcePath_;
3362 const std::vector<std::string> cppDependencySourcePaths() {
3363 std::vector<std::string> dependencies;
3364 for (
size_t i = 0; i<sourceDependencies_.size(); ++i) {
3365 FileInfo dep = sourceDependencies_[i];
3367 dependencies.push_back(dep.
path());
3370 return dependencies;
3373 std::string buildDirectory()
const {
3374 return buildDirectory_;
3377 std::string generatedCpp()
const {
3378 return generatedCpp_;
3381 std::string cppSourceFilename()
const {
3382 return cppSourceFilename_;
3385 std::string rSourceFilename()
const {
3386 return cppSourceFilename() +
".R";
3389 std::string dynlibFilename()
const {
3390 return dynlibFilename_;
3393 std::string dynlibPath()
const {
3394 return buildDirectory_ + fileSep_ + dynlibFilename();
3397 std::string previousDynlibPath()
const {
3398 if (!previousDynlibFilename_.empty())
3399 return buildDirectory_ + fileSep_ + previousDynlibFilename_;
3401 return std::string();
3404 const std::vector<std::string>& exportedFunctions()
const {
3405 return exportedFunctions_;
3408 const std::vector<std::string>& modules()
const {
3412 const std::vector<std::string>& depends()
const {
return depends_; };
3414 const std::vector<std::string>& plugins()
const {
return plugins_; };
3416 const std::vector<std::string>& embeddedR()
const {
return embeddedR_; }
3420 std::string generatedCppSourcePath()
const {
3421 return buildDirectory_ + fileSep_ + cppSourceFilename();
3424 std::string generatedRSourcePath()
const {
3425 return buildDirectory_ + fileSep_ + rSourceFilename();
3428 void generateR(std::ostream& ostr,
3430 const std::string& dllInfo)
const
3433 for(std::vector<Attribute>::const_iterator
3434 it = attributes.
begin(); it != attributes.
end(); ++it) {
3449 std::string rsig_err_msg =
"Missing args in " + args;
3456 <<
" <- Rcpp:::sourceCppFunction("
3457 <<
"function(" << args <<
") {}, "
3458 << (function.
type().
isVoid() ?
"TRUE" :
"FALSE") <<
", "
3460 <<
"'" << contextId_ +
"_" + function.
name()
3461 <<
"')" << std::endl;
3465 std::vector<std::string> modules = attributes.
modules();
3466 if (modules.size() > 0)
3469 ostr <<
"library(Rcpp)" << std::endl;
3472 for (std::vector<std::string>::const_iterator
3473 it = modules.begin(); it != modules.end(); ++it)
3475 ostr <<
" populate( Rcpp::Module(\"" << *it <<
"\","
3476 << dllInfo <<
"), environment() ) " << std::endl;
3482 std::string uniqueToken(
const std::string& cacheDir) {
3484 Rcpp::Function uniqueTokenFunc = rcppEnv[
".sourceCppDynlibUniqueToken"];
3489 std::string cppSourcePath_;
3490 std::string generatedCpp_;
3491 std::string cppSourceFilename_;
3492 std::string contextId_;
3493 std::string buildDirectory_;
3494 std::string fileSep_;
3495 std::string dynlibFilename_;
3496 std::string previousDynlibFilename_;
3497 std::string dynlibExt_;
3498 std::vector<std::string> exportedFunctions_;
3499 std::vector<std::string> modules_;
3500 std::vector<std::string> depends_;
3501 std::vector<std::string> plugins_;
3502 std::vector<std::string> embeddedR_;
3503 std::vector<FileInfo> sourceDependencies_;
3508 void dynlibCacheInsert(
const std::string& cacheDir,
3509 const std::string& file,
3510 const std::string& code,
3511 const SourceCppDynlib& dynlib)
3514 Rcpp::Function dynlibInsertFunc = rcppEnv[
".sourceCppDynlibInsert"];
3515 dynlibInsertFunc(cacheDir, file, code, dynlib.toList());
3518 void dynlibCacheInsertFile(
const std::string& cacheDir,
3519 const std::string& file,
3520 const SourceCppDynlib& dynlib)
3522 dynlibCacheInsert(cacheDir, file,
"", dynlib);
3525 void dynlibCacheInsertCode(
const std::string& cacheDir,
3526 const std::string& code,
3527 const SourceCppDynlib& dynlib)
3529 dynlibCacheInsert(cacheDir,
"", code, dynlib);
3532 SourceCppDynlib dynlibCacheLookup(
const std::string& cacheDir,
3533 const std::string& file,
3534 const std::string& code)
3537 Rcpp::Function dynlibLookupFunc = rcppEnv[
".sourceCppDynlibLookup"];
3538 Rcpp::List dynlibList = dynlibLookupFunc(cacheDir, file, code);
3539 if (dynlibList.
length() > 0)
3540 return SourceCppDynlib(dynlibList);
3542 return SourceCppDynlib();
3545 SourceCppDynlib dynlibCacheLookupByFile(
const std::string& cacheDir,
3546 const std::string& file)
3548 return dynlibCacheLookup(cacheDir, file,
"");
3551 SourceCppDynlib dynlibCacheLookupByCode(
const std::string& cacheDir,
3552 const std::string& code)
3554 return dynlibCacheLookup(cacheDir,
"", code);
3562 SEXP sRebuild, SEXP sCacheDir, SEXP sPlatform) {
3572 SourceCppDynlib dynlib = !code.empty() ? dynlibCacheLookupByCode(cacheDir, code)
3573 : dynlibCacheLookupByFile(cacheDir, file);
3576 bool buildRequired =
false;
3579 if (dynlib.isEmpty()) {
3580 buildRequired =
true;
3581 dynlib = SourceCppDynlib(cacheDir, file, platform);
3585 else if (rebuild || dynlib.isSourceDirty()) {
3586 buildRequired =
true;
3587 dynlib.regenerateSource(cacheDir);
3591 else if (!dynlib.isBuilt()) {
3592 buildRequired =
true;
3597 dynlibCacheInsertCode(cacheDir, code, dynlib);
3599 dynlibCacheInsertFile(cacheDir, file, dynlib);
3602 using namespace Rcpp;
3604 _[
"contextId"] = dynlib.contextId(),
3605 _[
"cppSourcePath"] = dynlib.cppSourcePath(),
3606 _[
"cppDependencySourcePaths"] = dynlib.cppDependencySourcePaths(),
3607 _[
"buildRequired"] = buildRequired,
3608 _[
"buildDirectory"] = dynlib.buildDirectory(),
3609 _[
"generatedCpp"] = dynlib.generatedCpp(),
3610 _[
"exportedFunctions"] = dynlib.exportedFunctions(),
3611 _[
"modules"] = dynlib.modules(),
3612 _[
"cppSourceFilename"] = dynlib.cppSourceFilename(),
3613 _[
"rSourceFilename"] = dynlib.rSourceFilename(),
3614 _[
"dynlibFilename"] = dynlib.dynlibFilename(),
3615 _[
"dynlibPath"] = dynlib.dynlibPath(),
3616 _[
"previousDynlibPath"] = dynlib.previousDynlibPath(),
3617 _[
"depends"] = dynlib.depends(),
3618 _[
"plugins"] = dynlib.plugins(),
3619 _[
"embeddedR"] = dynlib.embeddedR());
3630 SEXP sCppFileBasenames,
3640 std::set<std::string> depends;
3642 it = vDepends.
begin(); it != vDepends.
end(); ++it) {
3643 depends.insert(std::string(*it));
3648 std::vector<std::string> cppFiles =
3650 std::vector<std::string> cppFileBasenames =
3652 std::vector<std::string> includes =
3672 "The header file '" + e.
filePath() +
"' already exists so "
3673 "cannot be overwritten by Rcpp::interfaces";
3690 bool hasPackageInit =
false;
3691 bool haveAttributes =
false;
3692 std::set<std::string> dependsAttribs;
3693 for (std::size_t i=0; i<cppFiles.size(); i++) {
3696 std::string cppFile = cppFiles[i];
3697 if (
endsWith(cppFile,
"RcppExports.cpp"))
3705 hasPackageInit =
true;
3712 haveAttributes =
true;
3719 it = attributes.
begin(); it != attributes.
end(); ++it) {
3721 for (
size_t i = 0; i<it->params().size(); ++i)
3722 dependsAttribs.insert(it->params()[i].name());
3728 generators.
writeEnd(hasPackageInit);
3731 std::vector<std::string> updated;
3733 updated = generators.
commit(includes);
3735 updated = generators.
remove();
3739 std::vector<std::string> diff;
3740 std::set_difference(dependsAttribs.begin(), dependsAttribs.end(),
3741 depends.begin(), depends.end(),
3742 std::back_inserter(diff));
3743 if (!diff.empty()) {
3745 "The following packages are referenced using Rcpp::depends "
3746 "attributes however are not listed in the Depends, Imports or "
3747 "LinkingTo fields of the package DESCRIPTION file: ";
3748 for (
size_t i=0; i<diff.size(); i++) {
3750 if (i != (diff.size()-1))
3758 for (
size_t i=0; i<updated.size(); i++)
3759 Rcpp::Rcout << updated[i] <<
" updated." << std::endl;
RcppExport SEXP compileAttributes(SEXP sPackageDir, SEXP sPackageName, SEXP sDepends, SEXP sRegistration, SEXP sCppFiles, SEXP sCppFileBasenames, SEXP sIncludes, SEXP sVerbose, SEXP sPlatform)
RcppExport SEXP sourceCppContext(SEXP sFile, SEXP sCode, SEXP sRebuild, SEXP sCacheDir, SEXP sPlatform)
void push_back(const T &object)
Proxy at(const size_t &i)
traits::r_vector_iterator< RTYPE, PreserveStorage >::type iterator
const std::string & defaultValue() const
Argument(const std::string &name, const Type &type, const std::string &defaultValue)
const std::string & name() const
bool operator!=(const Argument &other) const
const Type & type() const
std::string defaultValue_
bool operator==(const Argument &other) const
std::vector< Param > params_
std::vector< std::string > roxygen_
bool hasParameter(const std::string &name) const
const std::vector< std::string > & roxygen() const
const std::vector< Param > & params() const
bool operator!=(const Attribute &other) const
const Function & function() const
std::string exportedCppName() const
std::string exportedName() const
bool operator==(const Attribute &other) const
std::string customRSignature() const
Param paramNamed(const std::string &name) const
const std::string & name() const
Attribute(const std::string &name, const std::vector< Param > ¶ms, const Function &function, const std::vector< std::string > &roxygen)
bool isExportedFunction() const
std::string registerCCallable(size_t indent, const std::string &exportedName, const std::string &name) const
std::vector< Attribute > initFunctions_
virtual bool commit(const std::vector< std::string > &includes)
virtual void doWriteFunctions(const SourceFileAttributes &attributes, bool verbose)
CppExportsGenerator(const std::string &packageDir, const std::string &package, const std::string &fileSep)
virtual void writeBegin()
std::vector< std::string > modules_
std::vector< Attribute > nativeRoutines_
std::vector< Attribute > cppExports_
virtual void writeEnd(bool hasPackageInit)
virtual void writeBegin()
CppExportsIncludeGenerator(const std::string &packageDir, const std::string &package, const std::string &fileSep)
virtual void writeEnd(bool hasPackageInit)
virtual void doWriteFunctions(const SourceFileAttributes &attributes, bool verbose)
std::string getHeaderGuard() const
std::string getCCallable(const std::string &function) const
virtual bool commit(const std::vector< std::string > &includes)
virtual void doWriteFunctions(const SourceFileAttributes &, bool)
virtual void writeEnd(bool hasPackageInit)
virtual bool commit(const std::vector< std::string > &includes)
virtual void writeBegin()
std::string getHeaderGuard() const
CppPackageIncludeGenerator(const std::string &packageDir, const std::string &package, const std::string &fileSep)
bool hasCppInterface() const
ExportsGenerator(const ExportsGenerator &)
virtual void doWriteFunctions(const SourceFileAttributes &attributes, bool verbose)=0
std::string exportValidationFunction()
void writeFunctions(const SourceFileAttributes &attributes, bool verbose)
std::string generatorToken() const
virtual bool commit(const std::vector< std::string > &includes)=0
std::string registerCCallableExportedName()
const std::string & packageCpp() const
std::string exportValidationFunctionRegisteredName()
std::string existingCode_
const std::string packageCppPrefix() const
std::string commentPrefix_
virtual void writeEnd(bool hasPackageInit)=0
const std::string & package() const
ExportsGenerator & operator=(const ExportsGenerator &)
std::string dotNameHelper(const std::string &name) const
virtual ~ExportsGenerator()
const std::string & targetFile() const
bool isSafeToOverwrite() const
std::ostringstream codeStream_
virtual void writeBegin()=0
ExportsGenerator(const std::string &targetFile, const std::string &package, const std::string &commentPrefix)
ExportsGenerators(const ExportsGenerators &)
void writeEnd(bool hasPackageInit)
void add(ExportsGenerator *pGenerator)
std::vector< ExportsGenerator * >::iterator Itr
std::vector< std::string > remove()
ExportsGenerators & operator=(const ExportsGenerators &)
virtual ~ExportsGenerators()
void writeFunctions(const SourceFileAttributes &attributes, bool verbose)
std::vector< ExportsGenerator * > generators_
std::vector< std::string > commit(const std::vector< std::string > &includes)
std::string extension() const
FileInfo(const std::string &path)
bool operator<(const FileInfo &other) const
std::ostream & operator<<(std::ostream &os) const
FileInfo(const List &fileInfo)
double lastModified() const
bool operator==(const FileInfo &other) const
bool operator!=(const FileInfo &other) const
const std::string & name() const
std::string signature() const
bool operator==(const Function &other) const
const Type & type() const
const std::vector< Argument > & arguments() const
Function(const Type &type, const std::string &name, const std::vector< Argument > &arguments)
Function renamedTo(const std::string &name) const
bool operator!=(const Function &other) const
std::vector< Argument > arguments_
const std::string & name() const
bool operator!=(const Param &other) const
bool operator==(const Param &other) const
const std::string & value() const
virtual void writeEnd(bool hasPackageInit)
virtual void doWriteFunctions(const SourceFileAttributes &attributes, bool verbose)
virtual void writeBegin()
RExportsGenerator(const std::string &packageDir, const std::string &package, bool registration, const std::string &fileSep)
virtual bool commit(const std::vector< std::string > &includes)
std::string parseSignature(size_t lineNumber)
std::vector< std::vector< std::string > > roxygenChunks_
bool isKnownAttribute(const std::string &name) const
void attributeWarning(const std::string &message, const std::string &attribute, size_t lineNumber)
void rcppInterfacesWarning(const std::string &message, size_t lineNumber)
SourceFileAttributesParser(const std::string &sourceFile, const std::string &packageFile, bool parseDependencies)
virtual bool hasInterface(const std::string &name) const
void rcppExportNoFunctionFoundWarning(size_t lineNumber)
virtual const std::string & sourceFile() const
virtual const std::vector< std::string > & modules() const
virtual const_iterator begin() const
std::vector< std::string > roxygenBuffer_
Function parseFunction(size_t lineNumber)
SourceFileAttributesParser & operator=(const SourceFileAttributesParser &)
std::vector< std::string > modules_
Type parseType(const std::string &text)
virtual const_iterator end() const
std::vector< std::string > embeddedR_
virtual bool hasGeneratorOutput() const
const std::vector< FileInfo > & sourceDependencies() const
virtual const std::vector< std::vector< std::string > > & roxygenChunks() const
SourceFileAttributesParser(const SourceFileAttributesParser &)
std::vector< FileInfo > sourceDependencies_
void rcppExportWarning(const std::string &message, size_t lineNumber)
Attribute parseAttribute(const std::vector< std::string > &match, int lineNumber)
bool hasPackageInit() const
std::vector< Attribute > attributes_
void rcppExportInvalidParameterWarning(const std::string ¶m, size_t lineNumber)
std::vector< Param > parseParameters(const std::string &input)
const std::vector< std::string > & embeddedR() const
std::vector< std::string > parseArguments(const std::string &argText)
virtual const std::vector< std::vector< std::string > > & roxygenChunks() const =0
virtual const_iterator end() const =0
std::vector< Attribute >::const_iterator const_iterator
virtual const std::string & sourceFile() const =0
virtual bool hasGeneratorOutput() const =0
virtual bool hasPackageInit() const =0
virtual const std::vector< std::string > & modules() const =0
virtual const_iterator begin() const =0
virtual ~SourceFileAttributes()
virtual bool hasInterface(const std::string &name) const =0
const std::string & name() const
bool operator!=(const Type &other) const
Type(const std::string &name, bool isConst, bool isReference)
bool operator==(const Type &other) const
std::string full_name() const
std::string filePath() const
const char *const kParamValueTRUE
void initializeGlobals(std::ostream &ostr)
void stripQuotes(std::string *pStr)
const char *const kInitAttribute
const char *const kParamValueFalse
const char *const kExportInvisible
const char *const kExportRng
void printArgument(std::ostream &os, const Argument &argument, bool printDefault=true)
bool isQuoted(const std::string &str)
const char *const kWhitespaceChars
bool endsWith(const std::string &str, const std::string &suffix)
const char *const kInterfaceR
void printFunction(std::ostream &os, const Function &function, bool printArgDefaults=true)
std::ostream & operator<<(std::ostream &os, const Type &type)
const char *const kInterfaceCpp
const char *const kDependsAttribute
const char *const kPluginsAttribute
bool isWhitespace(char ch)
void showWarning(const std::string &msg)
const char *const kParamValueTrue
bool isRoxygenCpp(const std::string &str)
const char *const kExportName
void trimWhitespace(std::string *pStr)
std::string generateRArgList(const Function &function)
bool checkRSignature(const Function &function, std::string args)
const char *const kParamValueFALSE
const char *const kExportSignature
void stripTrailingLineComments(std::string *pStr)
const char *const kInterfacesAttribute
const char *const kParamBlockEnd
const char *const kExportAttribute
bool removeFile(const std::string &path)
void generateCpp(std::ostream &ostr, const SourceFileAttributes &attributes, bool includePrototype, bool cppInterface, const std::string &contextId)
void createDirectory(const std::string &path)
const char *const kParamBlockStart
Function_Impl< PreserveStorage > Function
Argument Named(const std::string &name)
Vector< LGLSXP > LogicalVector
SEXP find(const std::string &name) const
RObject_Impl< PreserveStorage > RObject
static internal::NamedPlaceHolder _
static Rostream< true > Rcout
IntegerVector match(const VectorBase< RTYPE, NA, T > &x, const VectorBase< RTYPE, RHS_NA, RHS_T > &table_)
Environment_Impl< PreserveStorage > Environment
bool exists(const std::string &name) const
void warning(const std::string &message)
SEXP wrap(const Date &date)
static R_CallMethodDef callEntries[]