@@ -738,9 +738,23 @@ namespace attributes {
738738 }
739739 }
740740
741- // parse the local includes from the passed lines
742- std::vector<FileInfo> parseLocalIncludes (
743- const std::string& sourceFile) {
741+ bool addUniqueInclude (Rcpp::CharacterVector include,
742+ std::vector<FileInfo>* pLocalIncludes) {
743+
744+ // return false if we already have this include
745+ std::string path = Rcpp::as<std::string>(include);
746+ for (size_t i = 0 ; i<pLocalIncludes->size (); ++i) {
747+ if (pLocalIncludes->at (i).path () == path)
748+ return false ;
749+ }
750+
751+ // add it and return true
752+ pLocalIncludes->push_back (FileInfo (path));
753+ return true ;
754+ }
755+
756+ void parseLocalIncludes (const std::string& sourceFile,
757+ std::vector<FileInfo>* pLocalIncludes) {
744758
745759 // import R functions
746760 Rcpp::Environment baseEnv = Rcpp::Environment::base_env ();
@@ -769,7 +783,7 @@ namespace attributes {
769783
770784 // accumulate local includes (skip commented sections)
771785 CommentState commentState;
772- std::vector<FileInfo> localIncludes ;
786+ std::vector<FileInfo> newIncludes ;
773787 for (int i = 0 ; i<matches.size (); i++) {
774788 std::string line = lines[i];
775789 commentState.submitLine (line);
@@ -781,34 +795,30 @@ namespace attributes {
781795 Rcpp::CharacterVector include =
782796 filepath (sourceDir, std::string (match[1 ]));
783797 // if it exists then normalize and add to our list
784- if (fileExists (include)) {
798+ LogicalVector exists = fileExists (include);
799+ if (exists[0 ]) {
785800 include = normalizePath (include);
786- localIncludes.push_back (
787- FileInfo (Rcpp::as<std::string>(include)));
801+ if (addUniqueInclude (include, pLocalIncludes)) {
802+ newIncludes.push_back (
803+ FileInfo (Rcpp::as<std::string>(include)));
804+ }
788805 }
789806 }
790807 }
791808 }
792809
793- // look for local includes recursively (make a copy of the local
794- // includes first so we can mutate it during iteration)
795- std::vector<FileInfo> localIncludesCopy = localIncludes;
796- for (size_t i = 0 ; i<localIncludesCopy.size (); i++) {
797- FileInfo include = localIncludesCopy[i];
798- std::vector<FileInfo> includes = parseLocalIncludes (
799- include.path ());
800- std::copy (includes.begin (),
801- includes.end (),
802- std::back_inserter (localIncludes));
810+ // look for includes recursively
811+ for (size_t i = 0 ; i<newIncludes.size (); i++) {
812+ FileInfo include = newIncludes[i];
813+ parseLocalIncludes (include.path (), pLocalIncludes);
803814 }
804-
805- // remove duplicates
806- std::sort (localIncludes.begin (), localIncludes.end ());
807- std::vector<FileInfo>::iterator end =
808- std::unique (localIncludes.begin (), localIncludes.end ());
809- localIncludes.erase (end, localIncludes.end ());
810-
811- // return includes
815+ }
816+
817+ // parse the local includes from the passed lines
818+ std::vector<FileInfo> parseLocalIncludes (
819+ const std::string& sourceFile) {
820+ std::vector<FileInfo> localIncludes;
821+ parseLocalIncludes (sourceFile, &localIncludes);
812822 return localIncludes;
813823 }
814824
0 commit comments