@@ -54,6 +54,14 @@ namespace attributes {
54
54
bool exists () const { return exists_; }
55
55
time_t lastModified () const { return lastModified_; }
56
56
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
+
57
65
bool operator <(const FileInfo& other) const {
58
66
return path_ < other.path_ ;
59
67
};
@@ -143,7 +151,17 @@ namespace attributes {
143
151
{
144
152
}
145
153
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
+
147
165
const std::string& name () const { return name_; }
148
166
std::string full_name () const {
149
167
std::string res ;
@@ -175,6 +193,17 @@ namespace attributes {
175
193
}
176
194
177
195
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
+
178
207
179
208
const std::string& name () const { return name_; }
180
209
const Type& type () const { return type_; }
@@ -192,14 +221,13 @@ namespace attributes {
192
221
Function () {}
193
222
Function (const Type& type,
194
223
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)
198
226
{
199
227
}
200
228
201
229
Function renamedTo (const std::string& name) const {
202
- return Function (type (), name, arguments (), source () );
230
+ return Function (type (), name, arguments ());
203
231
}
204
232
205
233
std::string signature () const { return signature (name ()); }
@@ -210,17 +238,25 @@ namespace attributes {
210
238
}
211
239
212
240
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
+ };
213
251
214
252
const Type& type () const { return type_; }
215
253
const std::string& name () const { return name_; }
216
254
const std::vector<Argument>& arguments () const { return arguments_; }
217
- const std::string& source () const { return source_; }
218
-
255
+
219
256
private:
220
257
Type type_;
221
258
std::string name_;
222
259
std::vector<Argument> arguments_;
223
- std::string source_;
224
260
};
225
261
226
262
// Attribute parameter (with optional value)
@@ -229,6 +265,16 @@ namespace attributes {
229
265
Param () {}
230
266
explicit Param (const std::string& paramText);
231
267
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
+
232
278
233
279
const std::string& name () const { return name_; }
234
280
const std::string& value () const { return value_; }
@@ -251,6 +297,18 @@ namespace attributes {
251
297
}
252
298
253
299
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
+
254
312
255
313
const std::string& name () const { return name_; }
256
314
@@ -749,6 +807,9 @@ namespace attributes {
749
807
Rcpp::Function filepath = baseEnv[" file.path" ];
750
808
Rcpp::Function normalizePath = baseEnv[" normalizePath" ];
751
809
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" ];
752
813
753
814
// get the path to the source file's directory
754
815
Rcpp::CharacterVector sourceDir = dirname (sourceFile);
@@ -789,6 +850,25 @@ namespace attributes {
789
850
newDependencies.push_back (
790
851
FileInfo (Rcpp::as<std::string>(include)));
791
852
}
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
+ }
792
872
}
793
873
}
794
874
}
@@ -804,8 +884,17 @@ namespace attributes {
804
884
// parse the source dependencies from the passed lines
805
885
std::vector<FileInfo> parseSourceDependencies (
806
886
const std::string& sourceFile) {
887
+
888
+ // parse dependencies
807
889
std::vector<FileInfo> dependencies;
808
890
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
+
809
898
return dependencies;
810
899
}
811
900
@@ -1075,21 +1164,26 @@ namespace attributes {
1075
1164
// Recursively parse dependencies if requested
1076
1165
if (parseDependencies) {
1077
1166
1078
- // get local includes
1167
+ // get source dependencies
1079
1168
sourceDependencies_ = parseSourceDependencies (sourceFile);
1080
1169
1081
- // parse attributes and modules from each local include
1170
+ // parse attributes and modules from each dependent file
1082
1171
for (size_t i = 0 ; i<sourceDependencies_.size (); i++) {
1083
1172
1084
1173
// perform parse
1085
1174
std::string dependency = sourceDependencies_[i].path ();
1086
1175
SourceFileAttributesParser parser (dependency, false );
1087
1176
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
+
1093
1187
// copy to base modules
1094
1188
std::copy (parser.modules ().begin (),
1095
1189
parser.modules ().end (),
@@ -1339,7 +1433,7 @@ namespace attributes {
1339
1433
arguments.push_back (Argument (name, type, defaultValue));
1340
1434
}
1341
1435
1342
- return Function (type, name, arguments, signature );
1436
+ return Function (type, name, arguments);
1343
1437
}
1344
1438
1345
1439
@@ -2746,7 +2840,7 @@ namespace {
2746
2840
// always include Rcpp.h in case the user didn't
2747
2841
ostr << std::endl << std::endl;
2748
2842
ostr << " #include <Rcpp.h>" << std::endl;
2749
- generateCpp (ostr, sourceAttributes, false , false , contextId_);
2843
+ generateCpp (ostr, sourceAttributes, true , false , contextId_);
2750
2844
generatedCpp_ = ostr.str ();
2751
2845
std::ofstream cppOfs (generatedCppSourcePath ().c_str (),
2752
2846
std::ofstream::out | std::ofstream::app);
@@ -2813,6 +2907,17 @@ namespace {
2813
2907
const std::string& cppSourcePath () const {
2814
2908
return cppSourcePath_;
2815
2909
}
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
+ }
2816
2921
2817
2922
std::string buildDirectory () const {
2818
2923
return buildDirectory_;
@@ -3044,6 +3149,7 @@ BEGIN_RCPP
3044
3149
return List::create (
3045
3150
_[" contextId" ] = pDynlib->contextId (),
3046
3151
_[" cppSourcePath" ] = pDynlib->cppSourcePath (),
3152
+ _[" cppDependencySourcePaths" ] = pDynlib->cppDependencySourcePaths (),
3047
3153
_[" buildRequired" ] = buildRequired,
3048
3154
_[" buildDirectory" ] = pDynlib->buildDirectory (),
3049
3155
_[" generatedCpp" ] = pDynlib->generatedCpp (),
0 commit comments