| 885 | } |
| 886 | |
| 887 | void parseSourceDependencies(const std::string& sourceFile, |
| 888 | std::vector<FileInfo>* pDependencies) { |
| 889 | |
| 890 | // import R functions |
| 891 | Rcpp::Environment baseEnv = Rcpp::Environment::base_env(); |
| 892 | Rcpp::Function dirname = baseEnv["dirname"]; |
| 893 | Rcpp::Function filepath = baseEnv["file.path"]; |
| 894 | Rcpp::Function normalizePath = baseEnv["normalizePath"]; |
| 895 | Rcpp::Function fileExists = baseEnv["file.exists"]; |
| 896 | Rcpp::Environment toolsEnv = Rcpp::Environment::namespace_env( |
| 897 | "tools"); |
| 898 | Rcpp::Function filePathSansExt = toolsEnv["file_path_sans_ext"]; |
| 899 | |
| 900 | // get the path to the source file's directory |
| 901 | Rcpp::CharacterVector sourceDir = dirname(sourceFile); |
| 902 | |
| 903 | // read the source file into a buffer |
| 904 | std::stringstream buffer; |
| 905 | readFile(sourceFile, buffer); |
| 906 | |
| 907 | // Now read into a list of strings (which we can pass to regexec) |
| 908 | // First read into a std::deque (which will handle lots of append |
| 909 | // operations efficiently) then copy into an R chracter vector |
| 910 | std::deque<std::string> lines; |
| 911 | readLines(buffer, &lines); |
| 912 | Rcpp::CharacterVector linesVector = Rcpp::wrap(lines); |
| 913 | |
| 914 | // look for local includes |
| 915 | Rcpp::List matches = regexMatches( |
| 916 | linesVector, "^\\s*#include\\s*\"([^\"]+)\"\\s*$"); |
| 917 | |
| 918 | // accumulate local includes (skip commented sections) |
| 919 | CommentState commentState; |
| 920 | std::vector<FileInfo> newDependencies; |
| 921 | for (int i = 0; i<matches.size(); i++) { |
| 922 | std::string line = lines[i]; |
| 923 | commentState.submitLine(line); |
| 924 | if (!commentState.inComment()) { |
| 925 | // get the match |
| 926 | const Rcpp::CharacterVector match = matches[i]; |
| 927 | if (match.size() == 2) { |
| 928 | // compose a full file path for the match |
| 929 | Rcpp::CharacterVector include = |
| 930 | filepath(sourceDir, std::string(match[1])); |
| 931 | // if it exists then normalize and add to our list |
| 932 | LogicalVector exists = fileExists(include); |
| 933 | if (exists[0]) { |
| 934 | include = normalizePath(include, "/"); |
| 935 | if (addUniqueDependency(include, pDependencies)) { |
| 936 | newDependencies.push_back( |
| 937 | FileInfo(Rcpp::as<std::string>(include))); |
| 938 | } |
| 939 | |
| 940 | std::vector<std::string> exts; |
| 941 | exts.push_back(".cc"); |
| 942 | exts.push_back(".cpp"); |
| 943 | for (size_t i = 0; i<exts.size(); ++i) { |
| 944 |
no test coverage detected