diff --git a/reactos/boot/freeldr/freeldr/freeldr_base.xml b/reactos/boot/freeldr/freeldr/freeldr_base.xml index 6b86cc4d051..3024356e7ac 100644 --- a/reactos/boot/freeldr/freeldr/freeldr_base.xml +++ b/reactos/boot/freeldr/freeldr/freeldr_base.xml @@ -1,5 +1,6 @@ include + cache -nostdlib -nostdinc -ffreestanding diff --git a/reactos/tools/rbuild/automaticdependency.cpp b/reactos/tools/rbuild/automaticdependency.cpp index b27e575de20..9ed17b3d790 100644 --- a/reactos/tools/rbuild/automaticdependency.cpp +++ b/reactos/tools/rbuild/automaticdependency.cpp @@ -13,20 +13,42 @@ /* Read at most this amount of bytes from each file and assume that all #includes are located within this block */ #define MAX_BYTES_TO_READ 4096 - + using std::string; using std::vector; using std::map; SourceFile::SourceFile ( AutomaticDependency* automaticDependency, Module& module, - const string& filename ) + const string& filename, + SourceFile* parent, + bool isNonAutomaticDependency ) : automaticDependency ( automaticDependency ), module ( module ), - filename ( filename ) + filename ( filename ), + isNonAutomaticDependency ( isNonAutomaticDependency ) { + if ( parent != NULL ) + parents.push_back ( parent ); + GetDirectoryAndFilenameParts (); } - + +void +SourceFile::GetDirectoryAndFilenameParts () +{ + size_t index = filename.find_last_of ( CSEP ); + if ( index != string::npos ) + { + directoryPart = filename.substr ( 0, index ); + filenamePart = filename.substr ( index + 1, filename.length () - index ); + } + else + { + directoryPart = ""; + filenamePart = filename; + } +} + void SourceFile::Close () { @@ -87,14 +109,65 @@ SourceFile::ReadInclude ( string& filename ) return false; } +bool +SourceFile::IsParentOf ( const SourceFile* parent, + const SourceFile* child ) +{ + size_t i; + for ( i = 0; i < child->parents.size (); i++ ) + { + if ( child->parents[i] != NULL ) + { + if ( child->parents[i] == parent ) + return true; + } + } + for ( i = 0; i < child->parents.size (); i++ ) + { + if ( child->parents[i] != NULL ) + { + if ( IsParentOf ( parent, + child->parents[i] ) ) + return true; + } + } + return false; +} + +bool +SourceFile::IsIncludedFrom ( const string& normalizedFilename ) +{ + if ( normalizedFilename == filename ) + return true; + + SourceFile* sourceFile = automaticDependency->RetrieveFromCache ( normalizedFilename ); + if ( sourceFile == NULL ) + return false; + + return IsParentOf ( sourceFile, + this ); +} + +SourceFile* +SourceFile::GetParentSourceFile () +{ + if ( isNonAutomaticDependency ) + return NULL; + return this; +} + SourceFile* SourceFile::ParseFile ( const string& normalizedFilename ) { string extension = GetExtension ( normalizedFilename ); - if ( extension == ".c" || extension == ".C" || extension == ".h" || extension == ".H") + if ( extension == ".c" || extension == ".C" || extension == ".h" || extension == ".H" ) { + if ( IsIncludedFrom ( normalizedFilename ) ) + return NULL; + SourceFile* sourceFile = automaticDependency->RetrieveFromCacheOrParse ( module, - normalizedFilename ); + normalizedFilename, + GetParentSourceFile () ); return sourceFile; } return NULL; @@ -118,7 +191,8 @@ SourceFile::Parse () if ( locatedFile ) { SourceFile* sourceFile = ParseFile ( resolvedFilename ); - files.push_back ( sourceFile ); + if ( sourceFile != NULL ) + files.push_back ( sourceFile ); } } p++; @@ -173,10 +247,9 @@ AutomaticDependency::ProcessFile ( Module& module, const File& file ) { string normalizedFilename = NormalizeFilename ( file.name ); - SourceFile sourceFile = SourceFile ( this, - module, - normalizedFilename ); - sourceFile.Parse (); + RetrieveFromCacheOrParse ( module, + normalizedFilename, + NULL ); } bool @@ -201,40 +274,54 @@ AutomaticDependency::LocateIncludedFile ( Module& module, const string& includedFilename, string& resolvedFilename ) { - for ( size_t i = 0; i < module.includes.size (); i++ ) + size_t i; + for ( i = 0; i < module.includes.size (); i++ ) { - Include* include = module.includes[0]; + Include* include = module.includes[i]; if ( LocateIncludedFile ( include->directory, includedFilename, resolvedFilename ) ) return true; } - + /* FIXME: Ifs */ - + + for ( i = 0; i < module.project.includes.size (); i++ ) + { + Include* include = module.project.includes[i]; + if ( LocateIncludedFile ( include->directory, + includedFilename, + resolvedFilename ) ) + return true; + } + resolvedFilename = ""; return false; } SourceFile* AutomaticDependency::RetrieveFromCacheOrParse ( Module& module, - const string& filename ) + const string& filename, + SourceFile* parentSourceFile ) { SourceFile* sourceFile = sourcefile_map[filename]; if ( sourceFile == NULL ) { sourceFile = new SourceFile ( this, module, - filename ); - sourceFile->Parse (); + filename, + parentSourceFile, + false ); sourcefile_map[filename] = sourceFile; + sourceFile->Parse (); } + else if ( parentSourceFile != NULL ) + sourceFile->parents.push_back ( parentSourceFile ); return sourceFile; } SourceFile* -AutomaticDependency::RetrieveFromCache ( Module& module, - const string& filename ) +AutomaticDependency::RetrieveFromCache ( const string& filename ) { return sourcefile_map[filename]; } diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index 7e9fdd6b23f..cd01e4f8e90 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -19,7 +19,8 @@ public: MingwBackend::MingwBackend ( Project& project ) - : Backend ( project ) + : Backend ( project ), + automaticDependencyUniqueIdCounter ( 0 ) { } @@ -240,12 +241,19 @@ MingwBackend::GenerateAllTarget () const fprintf ( fMakefile, "\n\t\n\n" ); } +string* +MingwBackend::GenerateAutomaticDependencyUniqueId () +{ + automaticDependencyUniqueIdCounter++; + return new string ( ssprintf ( "d%d", + automaticDependencyUniqueIdCounter ) ); +} + void -MingwBackend::GenerateAutomaticDependencies () const +MingwBackend::GenerateAutomaticDependencies () { AutomaticDependency automaticDependency ( ProjectNode ); automaticDependency.Process (); - for ( size_t mi = 0; mi < ProjectNode.modules.size (); mi++ ) { Module& module = *ProjectNode.modules[mi]; @@ -253,34 +261,110 @@ MingwBackend::GenerateAutomaticDependencies () const { File& file = *module.files[fi]; string normalizedFilename = NormalizeFilename ( file.name ); - SourceFile* sourceFile = automaticDependency.RetrieveFromCache ( module, - normalizedFilename ); + + SourceFile* sourceFile = automaticDependency.RetrieveFromCache ( normalizedFilename ); if ( sourceFile != NULL ) { string dependencies ( "" ); - GenerateAutomaticDependenciesForFile ( sourceFile, - dependencies ); - fprintf ( fMakefile, - "%s:: %s", - normalizedFilename.c_str (), - dependencies.c_str () ); + GenerateAutomaticDependenciesForFileCached ( sourceFile, + dependencies ); + if ( dependencies.size () > 0 ) + { + const string& objectFilename = MingwModuleHandler::GetObjectFilename ( normalizedFilename ); + string* uniqueId = automaticDependencyMap[dependencies]; + if ( uniqueId == NULL ) + { + uniqueId = GenerateAutomaticDependencyUniqueId (); + automaticDependencyMap[dependencies] = uniqueId; + fprintf ( fMakefile, + "%s = %s\n", + uniqueId->c_str (), + dependencies.c_str () ); + } + fprintf ( fMakefile, + "%s: $(%s)\n", + objectFilename.c_str (), + uniqueId->c_str () ); + } } } } } -void -MingwBackend::GenerateAutomaticDependenciesForFile ( SourceFile* sourceFile, - string& dependencies ) const +string +MingwBackend::GetFilename ( const string& filename ) const { - if ( dependencies.size () > 0 ) - dependencies += " "; - dependencies += sourceFile->filename; + size_t index = filename.find_last_of ( CSEP ); + if ( index == string::npos ) + return filename; + else + return filename.substr ( index + 1, filename.length () - index ); +} +void +MingwBackend::GenerateAutomaticDependenciesForFileCached ( SourceFile* sourceFile, + string& dependencies ) +{ for ( size_t i = 0; i < sourceFile->files.size (); i++) { - SourceFile* childSourceFile = sourceFile->files[0]; - + SourceFile* childSourceFile = sourceFile->files[i]; + + string* uniqueId = automaticDependencyDirectoryMap[childSourceFile->directoryPart]; + if ( uniqueId == NULL ) + { + uniqueId = GenerateAutomaticDependencyUniqueId (); + automaticDependencyDirectoryMap[childSourceFile->directoryPart] = uniqueId; + fprintf ( fMakefile, + "%s = %s\n", + uniqueId->c_str (), + childSourceFile->directoryPart.c_str () ); + } + dependencies += ssprintf ( "${%s}%s%s", + uniqueId->c_str (), + SSEP, + childSourceFile->filenamePart.c_str () ); + + string childDependencies; + if ( childSourceFile->cachedDependencies.length () > 0 ) + childDependencies = childSourceFile->cachedDependencies; + else + { + GenerateAutomaticDependenciesForFile ( childSourceFile, + childDependencies ); + if ( childDependencies.length () > 200 ) + { + childSourceFile->cachedDependencies = childDependencies; + } + } + dependencies += " " + childDependencies; + } +} + +void +MingwBackend::GenerateAutomaticDependenciesForFile ( SourceFile* sourceFile, + string& dependencies ) +{ + for ( size_t i = 0; i < sourceFile->files.size (); i++ ) + { + SourceFile* childSourceFile = sourceFile->files[i]; + + if ( dependencies.length () > 0 ) + dependencies += " "; + + string* uniqueId = automaticDependencyDirectoryMap[childSourceFile->directoryPart]; + if ( uniqueId == NULL ) + { + uniqueId = GenerateAutomaticDependencyUniqueId (); + automaticDependencyDirectoryMap[childSourceFile->directoryPart] = uniqueId; + fprintf ( fMakefile, + "%s = %s\n", + uniqueId->c_str (), + childSourceFile->directoryPart.c_str () ); + } + dependencies += ssprintf ( "${%s}%s%s", + uniqueId->c_str (), + SSEP, + childSourceFile->filenamePart.c_str () ); GenerateAutomaticDependenciesForFile ( childSourceFile, dependencies ); } diff --git a/reactos/tools/rbuild/backend/mingw/mingw.h b/reactos/tools/rbuild/backend/mingw/mingw.h index de55c9e5a3d..edd6bbf7ac1 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.h +++ b/reactos/tools/rbuild/backend/mingw/mingw.h @@ -8,6 +8,7 @@ class MingwBackend : public Backend { public: MingwBackend ( Project& project ); + virtual ~MingwBackend () { }; virtual void Process (); private: void ProcessModule ( Module& module ) const; @@ -27,10 +28,19 @@ private: void GenerateGlobalVariables () const; bool IncludeInAllTarget ( const Module& module ) const; void GenerateAllTarget () const; - void GenerateAutomaticDependencies () const; + std::string* GenerateAutomaticDependencyUniqueId (); + void GenerateAutomaticDependencies (); + bool IsAutomaticDependencyGenerated ( SourceFile* sourceFile ); + void OutputAutomaticDependenciesForFile ( SourceFile* sourceFile ); + std::string GetFilename ( const std::string& filename ) const; + void GenerateAutomaticDependenciesForFileCached ( SourceFile* sourceFile, + std::string& dependencies ); void GenerateAutomaticDependenciesForFile ( SourceFile* sourceFile, - std::string& dependencies ) const; + std::string& dependencies ); FILE* fMakefile; + int automaticDependencyUniqueIdCounter; + std::map automaticDependencyMap; + std::map automaticDependencyDirectoryMap; }; std::string FixupTargetFilename ( const std::string& targetFilename ); diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index 6e3be2d72bb..d2afb66458f 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -22,6 +22,20 @@ MingwModuleHandler::ref = 0; FILE* MingwModuleHandler::fMakefile = NULL; +string +ReplaceExtension ( const string& filename, + const string& newExtension ) +{ + size_t index = filename.find_last_of ( '/' ); + if (index == string::npos) index = 0; + string tmp = filename.substr( index, filename.size() - index ); + size_t ext_index = tmp.find_last_of( '.' ); + if (ext_index != string::npos) + return filename.substr ( 0, index + ext_index ) + newExtension; + return filename + newExtension; +} + + MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype ) { if ( !ref++ ) @@ -72,10 +86,10 @@ MingwModuleHandler::GetWorkingDirectory () const return "."; } -string -MingwModuleHandler::GetDirectory ( const string& filename ) const +string +MingwModuleHandler::GetDirectory ( const string& filename ) { - size_t index = filename.find_last_of ( '/' ); + size_t index = filename.find_last_of ( CSEP ); if (index == string::npos) return "."; else @@ -91,19 +105,6 @@ MingwModuleHandler::GetBasename ( const string& filename ) const return ""; } -string -MingwModuleHandler::ReplaceExtension ( const string& filename, - const string& newExtension ) const -{ - size_t index = filename.find_last_of ( '/' ); - if (index == string::npos) index = 0; - string tmp = filename.substr( index, filename.size() - index ); - size_t ext_index = tmp.find_last_of( '.' ); - if (ext_index != string::npos) - return filename.substr ( 0, index + ext_index ) + newExtension; - return filename + newExtension; -} - string MingwModuleHandler::GetActualSourceFilename ( const string& filename ) const { @@ -237,7 +238,7 @@ MingwModuleHandler::GetSourceFilenamesWithoutGeneratedFiles ( const Module& modu } string -MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const +MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) { string newExtension; string extension = GetExtension ( sourceFilename ); @@ -247,9 +248,8 @@ MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const newExtension = ".stubs.o"; else newExtension = ".o"; - return PassThruCacheDirectory ( - FixupTargetFilename ( - ReplaceExtension ( sourceFilename, newExtension ) ) ); + return FixupTargetFilename ( + ReplaceExtension ( sourceFilename, newExtension ) ); } string @@ -263,7 +263,7 @@ MingwModuleHandler::GetObjectFilenames ( const Module& module ) const { if ( objectFilenames.size () > 0 ) objectFilenames += " "; - objectFilenames += GetObjectFilename ( module.files[i]->name ); + objectFilenames += PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( module.files[i]->name ) ); } return objectFilenames; } @@ -510,7 +510,7 @@ MingwModuleHandler::GenerateMacros ( fprintf ( fMakefile, "%s := %s $(%s)\n", objs_macro.c_str(), - GetObjectFilename(files[i]->name).c_str(), + PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ).c_str (), objs_macro.c_str() ); } } @@ -530,7 +530,7 @@ MingwModuleHandler::GenerateMacros ( fMakefile, "%s%s", ( i%10 == 9 ? "\\\n\t" : " " ), - GetObjectFilename(files[i]->name).c_str() ); + PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ).c_str () ); } } fprintf ( fMakefile, "\n" ); @@ -612,7 +612,7 @@ MingwModuleHandler::GenerateGccCommand ( const Module& module, const string& cc, const string& cflagsMacro ) const { - string objectFilename = GetObjectFilename ( sourceFilename ); + string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) ); fprintf ( fMakefile, "%s: %s\n", objectFilename.c_str (), @@ -631,7 +631,7 @@ MingwModuleHandler::GenerateGccAssemblerCommand ( const Module& module, const string& cc, const string& cflagsMacro ) const { - string objectFilename = GetObjectFilename ( sourceFilename ); + string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) ); fprintf ( fMakefile, "%s: %s\n", objectFilename.c_str (), @@ -649,7 +649,7 @@ MingwModuleHandler::GenerateNasmCommand ( const Module& module, const string& sourceFilename, const string& nasmflagsMacro ) const { - string objectFilename = GetObjectFilename ( sourceFilename ); + string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) ); fprintf ( fMakefile, "%s: %s\n", objectFilename.c_str (), @@ -667,7 +667,7 @@ MingwModuleHandler::GenerateWindresCommand ( const Module& module, const string& sourceFilename, const string& windresflagsMacro ) const { - string objectFilename = GetObjectFilename ( sourceFilename ); + string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) ); fprintf ( fMakefile, "%s: %s\n", objectFilename.c_str (), @@ -908,7 +908,7 @@ MingwModuleHandler::GetCleanTargets ( vector& out, size_t i; for ( i = 0; i < files.size(); i++ ) - out.push_back ( GetObjectFilename(files[i]->name) ); + out.push_back ( PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ) ); for ( i = 0; i < ifs.size(); i++ ) GetCleanTargets ( out, ifs[i]->files, ifs[i]->ifs ); diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h index 08d359925e7..3ed21d525dd 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.h +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h @@ -3,6 +3,11 @@ #include "../backend.h" +extern std::string +ReplaceExtension ( const std::string& filename, + const std::string& newExtension ); + + class MingwModuleHandler { public: @@ -16,15 +21,13 @@ public: static MingwModuleHandler* LookupHandler ( const std::string& location, ModuleType moduletype_ ); virtual void Process ( const Module& module ) = 0; - void GenerateDirectoryTargets () const; - + void GenerateDirectoryTargets () const; + static std::string GetObjectFilename ( const std::string& sourceFilename ); + static std::string GetDirectory ( const std::string& filename ); protected: const std::string &PassThruCacheDirectory ( const std::string &f ) const; std::string GetWorkingDirectory () const; - std::string GetDirectory (const std::string& filename ) const; std::string GetBasename ( const std::string& filename ) const; - std::string ReplaceExtension ( const std::string& filename, - const std::string& newExtension ) const; std::string GetActualSourceFilename ( const std::string& filename ) const; std::string GetModuleArchiveFilename ( const Module& module ) const; bool IsGeneratedFile ( const File& file ) const; @@ -37,7 +40,6 @@ protected: std::string GetSourceFilenames ( const Module& module ) const; std::string GetSourceFilenamesWithoutGeneratedFiles ( const Module& module ) const; - std::string GetObjectFilename ( const std::string& sourceFilename ) const; std::string GetObjectFilenames ( const Module& module ) const; void GenerateMacrosAndTargetsHost ( const Module& module ) const; void GenerateMacrosAndTargetsTarget ( const Module& module ) const; @@ -47,6 +49,8 @@ protected: std::string GetInvocationDependencies ( const Module& module ) const; std::string GetInvocationParameters ( const Invoke& invoke ) const; void GenerateInvocations ( const Module& module ) const; + + std::string GetPreconditionDependenciesName ( const Module& module ) const; void GeneratePreconditionDependencies ( const Module& module ) const; std::string GetCFlagsMacro ( const Module& module ) const; std::string GetObjectsMacro ( const Module& module ) const; @@ -144,7 +148,6 @@ private: const std::string& ar, const std::string* clags, const std::string* nasmflags ) const; - std::string GetPreconditionDependenciesName ( const Module& module ) const; std::string GetSpecObjectDependencies ( const std::string& filename ) const; }; diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index 392094bef2d..103b9a32380 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -352,7 +352,9 @@ class SourceFile public: SourceFile ( AutomaticDependency* automaticDependency, Module& module, - const std::string& filename ); + const std::string& filename, + SourceFile* parent, + bool isNonAutomaticDependency ); SourceFile* ParseFile ( const std::string& normalizedFilename ); void Parse (); std::string Location () const; @@ -360,11 +362,21 @@ public: AutomaticDependency* automaticDependency; Module& module; std::string filename; + std::string filenamePart; + std::string directoryPart; + std::vector parents; /* List of files, this file is included from */ + bool isNonAutomaticDependency; + std::string cachedDependencies; private: + void GetDirectoryAndFilenameParts (); void Close (); void Open (); void SkipWhitespace (); bool ReadInclude ( std::string& filename ); + bool IsIncludedFrom ( const std::string& normalizedFilename ); + SourceFile* GetParentSourceFile (); + bool IsParentOf ( const SourceFile* parent, + const SourceFile* child ); std::string buf; const char *p; const char *end; @@ -387,9 +399,9 @@ public: const std::string& includedFilename, std::string& resolvedFilename ); SourceFile* RetrieveFromCacheOrParse ( Module& module, - const std::string& filename ); - SourceFile* RetrieveFromCache ( Module& module, - const std::string& filename ); + const std::string& filename, + SourceFile* parentSourceFile ); + SourceFile* RetrieveFromCache ( const std::string& filename ); private: void ProcessModule ( Module& module ); void ProcessFile ( Module& module, diff --git a/reactos/tools/rbuild/test.h b/reactos/tools/rbuild/test.h index e7a97b10c5c..536c7e81099 100644 --- a/reactos/tools/rbuild/test.h +++ b/reactos/tools/rbuild/test.h @@ -108,6 +108,10 @@ class SourceFileTest : public BaseTest { public: void Run(); +private: + bool IsParentOf ( const SourceFile* parent, + const SourceFile* child ); + }; #endif /* __TEST_H */ diff --git a/reactos/tools/rbuild/tests/data/sourcefile1_header2.h b/reactos/tools/rbuild/tests/data/sourcefile1_header2.h index 77d0452848c..f92a74186ae 100644 --- a/reactos/tools/rbuild/tests/data/sourcefile1_header2.h +++ b/reactos/tools/rbuild/tests/data/sourcefile1_header2.h @@ -1,2 +1,3 @@ -#include +#include "sourcefile1/sourcefile1_header3.h" #include +#include diff --git a/reactos/tools/rbuild/tests/data/sourcefile1_recurse.h b/reactos/tools/rbuild/tests/data/sourcefile1_recurse.h new file mode 100644 index 00000000000..f3ab6df93fd --- /dev/null +++ b/reactos/tools/rbuild/tests/data/sourcefile1_recurse.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/reactos/tools/rbuild/tests/sourcefiletest.cpp b/reactos/tools/rbuild/tests/sourcefiletest.cpp index d61e795a59b..699d5380056 100644 --- a/reactos/tools/rbuild/tests/sourcefiletest.cpp +++ b/reactos/tools/rbuild/tests/sourcefiletest.cpp @@ -2,10 +2,48 @@ using std::string; -void SourceFileTest::Run() +bool +SourceFileTest::IsParentOf ( const SourceFile* parent, + const SourceFile* child ) +{ + size_t i; + for ( i = 0; i < child->parents.size (); i++ ) + { + if ( child->parents[i] != NULL ) + { + if ( child->parents[i] == parent ) + { + return true; + } + } + } + for ( i = 0; i < child->parents.size (); i++ ) + { + if ( child->parents[i] != NULL ) + { + if ( IsParentOf ( parent, + child->parents[i] ) ) + { + return true; + } + } + } + return false; +} + +void +SourceFileTest::Run () { const Project project ( "tests/data/automaticdependency.xml" ); AutomaticDependency automaticDependency ( project ); automaticDependency.Process (); - ARE_EQUAL(3, automaticDependency.sourcefile_map.size()); + ARE_EQUAL( 5, automaticDependency.sourcefile_map.size () ); + const SourceFile* header1 = automaticDependency.RetrieveFromCache ( "tests" SSEP "data" SSEP "sourcefile1_header1.h" ); + IS_NOT_NULL( header1 ); + const SourceFile* recurse = automaticDependency.RetrieveFromCache ( "tests" SSEP "data" SSEP "sourcefile1_recurse.h" ); + IS_NOT_NULL( recurse ); + IS_TRUE( IsParentOf ( header1, + recurse ) ); + IS_FALSE( IsParentOf ( recurse, + header1 ) ); }