@@ -54,6 +54,14 @@ namespace attributes {
5454 bool exists () const { return exists_; }
5555 time_t lastModified () const { return lastModified_; }
5656
57+ std::string extension () const {
58+ std::string::size_type pos = path_.find_last_of (' .' );
59+ if (pos != std::string::npos)
60+ return path_.substr (pos);
61+ else
62+ return " " ;
63+ }
64+
5765 bool operator <(const FileInfo& other) const {
5866 return path_ < other.path_ ;
5967 };
@@ -143,7 +151,17 @@ namespace attributes {
143151 {
144152 }
145153 bool empty () const { return name ().empty (); }
146-
154+
155+ bool operator ==(const Type& other) const {
156+ return name_ == other.name_ &&
157+ isConst_ == other.isConst_ &&
158+ isReference_ == other.isReference_ ;
159+ };
160+
161+ bool operator !=(const Type& other) const {
162+ return !(*this == other);
163+ };
164+
147165 const std::string& name () const { return name_; }
148166 std::string full_name () const {
149167 std::string res ;
@@ -175,6 +193,17 @@ namespace attributes {
175193 }
176194
177195 bool empty () const { return type ().empty (); }
196+
197+ bool operator ==(const Argument& other) const {
198+ return name_ == other.name_ &&
199+ type_ == other.type_ &&
200+ defaultValue_ == other.defaultValue_ ;
201+ };
202+
203+ bool operator !=(const Argument& other) const {
204+ return !(*this == other);
205+ };
206+
178207
179208 const std::string& name () const { return name_; }
180209 const Type& type () const { return type_; }
@@ -192,14 +221,13 @@ namespace attributes {
192221 Function () {}
193222 Function (const Type& type,
194223 const std::string& name,
195- const std::vector<Argument>& arguments,
196- const std::string& source)
197- : type_(type), name_(name), arguments_(arguments), source_(source)
224+ const std::vector<Argument>& arguments)
225+ : type_(type), name_(name), arguments_(arguments)
198226 {
199227 }
200228
201229 Function renamedTo (const std::string& name) const {
202- return Function (type (), name, arguments (), source () );
230+ return Function (type (), name, arguments ());
203231 }
204232
205233 std::string signature () const { return signature (name ()); }
@@ -210,17 +238,25 @@ namespace attributes {
210238 }
211239
212240 bool empty () const { return name ().empty (); }
241+
242+ bool operator ==(const Function& other) const {
243+ return type_ == other.type_ &&
244+ name_ == other.name_ &&
245+ arguments_ == other.arguments_ ;
246+ };
247+
248+ bool operator !=(const Function& other) const {
249+ return !(*this == other);
250+ };
213251
214252 const Type& type () const { return type_; }
215253 const std::string& name () const { return name_; }
216254 const std::vector<Argument>& arguments () const { return arguments_; }
217- const std::string& source () const { return source_; }
218-
255+
219256 private:
220257 Type type_;
221258 std::string name_;
222259 std::vector<Argument> arguments_;
223- std::string source_;
224260 };
225261
226262 // Attribute parameter (with optional value)
@@ -229,6 +265,16 @@ namespace attributes {
229265 Param () {}
230266 explicit Param (const std::string& paramText);
231267 bool empty () const { return name ().empty (); }
268+
269+ bool operator ==(const Param& other) const {
270+ return name_ == other.name_ &&
271+ value_ == other.value_ ;
272+ };
273+
274+ bool operator !=(const Param& other) const {
275+ return !(*this == other);
276+ };
277+
232278
233279 const std::string& name () const { return name_; }
234280 const std::string& value () const { return value_; }
@@ -251,6 +297,18 @@ namespace attributes {
251297 }
252298
253299 bool empty () const { return name ().empty (); }
300+
301+ bool operator ==(const Attribute& other) const {
302+ return name_ == other.name_ &&
303+ params_ == other.params_ &&
304+ function_ == other.function_ &&
305+ roxygen_ == other.roxygen_ ;
306+ };
307+
308+ bool operator !=(const Attribute& other) const {
309+ return !(*this == other);
310+ };
311+
254312
255313 const std::string& name () const { return name_; }
256314
@@ -749,6 +807,9 @@ namespace attributes {
749807 Rcpp::Function filepath = baseEnv[" file.path" ];
750808 Rcpp::Function normalizePath = baseEnv[" normalizePath" ];
751809 Rcpp::Function fileExists = baseEnv[" file.exists" ];
810+ Rcpp::Environment toolsEnv = Rcpp::Environment::namespace_env (
811+ " tools" );
812+ Rcpp::Function filePathSansExt = toolsEnv[" file_path_sans_ext" ];
752813
753814 // get the path to the source file's directory
754815 Rcpp::CharacterVector sourceDir = dirname (sourceFile);
@@ -789,6 +850,25 @@ namespace attributes {
789850 newDependencies.push_back (
790851 FileInfo (Rcpp::as<std::string>(include)));
791852 }
853+
854+ std::vector<std::string> exts;
855+ exts.push_back (" .cc" );
856+ exts.push_back (" .cpp" );
857+ for (size_t i = 0 ; i<exts.size (); ++i) {
858+
859+ // look for corresponding cpp file and add it
860+ std::string file = Rcpp::as<std::string>(
861+ filePathSansExt (include)) + exts[i];
862+
863+ exists = fileExists (file);
864+ if (exists[0 ]) {
865+ if (addUniqueDependency (file,
866+ pDependencies)) {
867+ FileInfo fileInfo (file);
868+ newDependencies.push_back (fileInfo);
869+ }
870+ }
871+ }
792872 }
793873 }
794874 }
@@ -804,8 +884,17 @@ namespace attributes {
804884 // parse the source dependencies from the passed lines
805885 std::vector<FileInfo> parseSourceDependencies (
806886 const std::string& sourceFile) {
887+
888+ // parse dependencies
807889 std::vector<FileInfo> dependencies;
808890 parseSourceDependencies (sourceFile, &dependencies);
891+
892+ // remove main source file
893+ dependencies.erase (std::remove (dependencies.begin (),
894+ dependencies.end (),
895+ FileInfo (sourceFile)),
896+ dependencies.end ());
897+
809898 return dependencies;
810899 }
811900
@@ -1075,21 +1164,26 @@ namespace attributes {
10751164 // Recursively parse dependencies if requested
10761165 if (parseDependencies) {
10771166
1078- // get local includes
1167+ // get source dependencies
10791168 sourceDependencies_ = parseSourceDependencies (sourceFile);
10801169
1081- // parse attributes and modules from each local include
1170+ // parse attributes and modules from each dependent file
10821171 for (size_t i = 0 ; i<sourceDependencies_.size (); i++) {
10831172
10841173 // perform parse
10851174 std::string dependency = sourceDependencies_[i].path ();
10861175 SourceFileAttributesParser parser (dependency, false );
10871176
1088- // copy to base attributes
1089- std::copy (parser.begin (),
1090- parser.end (),
1091- std::back_inserter (attributes_));
1092-
1177+ // copy to base attributes (if it's a new attribute)
1178+ for (SourceFileAttributesParser::const_iterator
1179+ it = parser.begin (); it != parser.end (); ++it) {
1180+ if (std::find (attributes_.begin (),
1181+ attributes_.end (),
1182+ *it) == attributes_.end ()) {
1183+ attributes_.push_back (*it);
1184+ }
1185+ }
1186+
10931187 // copy to base modules
10941188 std::copy (parser.modules ().begin (),
10951189 parser.modules ().end (),
@@ -1339,7 +1433,7 @@ namespace attributes {
13391433 arguments.push_back (Argument (name, type, defaultValue));
13401434 }
13411435
1342- return Function (type, name, arguments, signature );
1436+ return Function (type, name, arguments);
13431437 }
13441438
13451439
@@ -2746,7 +2840,7 @@ namespace {
27462840 // always include Rcpp.h in case the user didn't
27472841 ostr << std::endl << std::endl;
27482842 ostr << " #include <Rcpp.h>" << std::endl;
2749- generateCpp (ostr, sourceAttributes, false , false , contextId_);
2843+ generateCpp (ostr, sourceAttributes, true , false , contextId_);
27502844 generatedCpp_ = ostr.str ();
27512845 std::ofstream cppOfs (generatedCppSourcePath ().c_str (),
27522846 std::ofstream::out | std::ofstream::app);
@@ -2813,6 +2907,17 @@ namespace {
28132907 const std::string& cppSourcePath () const {
28142908 return cppSourcePath_;
28152909 }
2910+
2911+ const std::vector<std::string> cppDependencySourcePaths () {
2912+ std::vector<std::string> dependencies;
2913+ for (size_t i = 0 ; i<sourceDependencies_.size (); ++i) {
2914+ FileInfo dep = sourceDependencies_[i];
2915+ if (dep.extension () == " .cc" || dep.extension () == " .cpp" ) {
2916+ dependencies.push_back (dep.path ());
2917+ }
2918+ }
2919+ return dependencies;
2920+ }
28162921
28172922 std::string buildDirectory () const {
28182923 return buildDirectory_;
@@ -3044,6 +3149,7 @@ BEGIN_RCPP
30443149 return List::create (
30453150 _[" contextId" ] = pDynlib->contextId (),
30463151 _[" cppSourcePath" ] = pDynlib->cppSourcePath (),
3152+ _[" cppDependencySourcePaths" ] = pDynlib->cppDependencySourcePaths (),
30473153 _[" buildRequired" ] = buildRequired,
30483154 _[" buildDirectory" ] = pDynlib->buildDirectory (),
30493155 _[" generatedCpp" ] = pDynlib->generatedCpp (),
0 commit comments