Generate automatic dependencies.
Modified: branches/xmlbuildsystem/reactos/boot/freeldr/freeldr/freeldr_base.xml
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/automaticdependency.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/test.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_header2.h
Added: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_recurse.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp

Modified: branches/xmlbuildsystem/reactos/boot/freeldr/freeldr/freeldr_base.xml
--- branches/xmlbuildsystem/reactos/boot/freeldr/freeldr/freeldr_base.xml	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/boot/freeldr/freeldr/freeldr_base.xml	2005-01-31 18:25:55 UTC (rev 13371)
@@ -1,5 +1,6 @@
 <module name="freeldr_base" type="objectlibrary">
 	<include base="freeldr_base">include</include>
+	<include base="freeldr_base">cache</include>
 	<compilerflag>-nostdlib</compilerflag>
 	<compilerflag>-nostdinc</compilerflag>
 	<compilerflag>-ffreestanding</compilerflag>

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/automaticdependency.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/automaticdependency.cpp	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/automaticdependency.cpp	2005-01-31 18:25:55 UTC (rev 13371)
@@ -13,21 +13,43 @@
 
 /* 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 ()
 {
 	buf.resize ( 0 );
@@ -87,14 +109,65 @@
 	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 @@
 			if ( locatedFile )
 			{
 				SourceFile* sourceFile = ParseFile ( resolvedFilename );
-				files.push_back ( sourceFile );
+				if ( sourceFile != NULL )
+					files.push_back ( sourceFile );
 			}
 		}
 		p++;
@@ -173,10 +247,9 @@
 	                               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 @@
 	                                      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 );
+		                              filename,
+		                              parentSourceFile,
+		                              false );
+		sourcefile_map[filename] = sourceFile;
 		sourceFile->Parse ();
-		sourcefile_map[filename] = sourceFile;
 	}
+	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];
 }

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-01-31 18:25:55 UTC (rev 13371)
@@ -19,7 +19,8 @@
 
 
 MingwBackend::MingwBackend ( Project& project )
-	: Backend ( project )
+	: Backend ( project ),
+	  automaticDependencyUniqueIdCounter ( 0 )
 {
 }
 
@@ -240,12 +241,19 @@
 	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 @@
 		{
 			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 () );
+				}
 			}
 		}
 	}
 }
 
+string 
+MingwBackend::GetFilename ( const string& filename ) const 
+{
+	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[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 ) const
+	                                                 string& dependencies )
 {
-	if ( dependencies.size () > 0 )
-		dependencies += " ";
-	dependencies += sourceFile->filename;
+	for ( size_t i = 0; i < sourceFile->files.size (); i++ )
+	{
+		SourceFile* childSourceFile = sourceFile->files[i];
 
-	for ( size_t i = 0; i < sourceFile->files.size (); i++)
-	{
-		SourceFile* childSourceFile = sourceFile->files[0];
-		
+		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 );
 	}

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-01-31 18:25:55 UTC (rev 13371)
@@ -8,6 +8,7 @@
 {
 public:
 	MingwBackend ( Project& project );
+	virtual ~MingwBackend () { };
 	virtual void Process ();
 private:
 	void ProcessModule ( Module& module ) const;
@@ -27,10 +28,19 @@
 	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<std::string, std::string*> automaticDependencyMap;
+	std::map<std::string, std::string*> automaticDependencyDirectoryMap;
 };
 
 std::string FixupTargetFilename ( const std::string& targetFilename );

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-01-31 18:25:55 UTC (rev 13371)
@@ -22,6 +22,20 @@
 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 @@
 	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
@@ -92,19 +106,6 @@
 }
 
 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
 {
 	string extension = GetExtension ( filename );
@@ -237,7 +238,7 @@
 }
 
 string
-MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const
+MingwModuleHandler::GetObjectFilename ( const string& sourceFilename )
 {
 	string newExtension;
 	string extension = GetExtension ( sourceFilename );
@@ -247,9 +248,8 @@
 		newExtension = ".stubs.o";
 	else
 		newExtension = ".o";
-	return PassThruCacheDirectory (
-		FixupTargetFilename (
-			ReplaceExtension ( sourceFilename, newExtension ) ) );
+	return FixupTargetFilename (
+			ReplaceExtension ( sourceFilename, newExtension ) );
 }
 
 string
@@ -263,7 +263,7 @@
 	{
 		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 @@
 				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 @@
 					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 @@
                                          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 @@
                                                   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 @@
                                           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 @@
                                              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 @@
 	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 );

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-01-31 18:25:55 UTC (rev 13371)
@@ -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 @@
 	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 @@
 	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 @@
 	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 @@
 	                                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;
 };
 

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-31 18:25:55 UTC (rev 13371)
@@ -352,7 +352,9 @@
 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 @@
 	AutomaticDependency* automaticDependency;
 	Module& module;
 	std::string filename;
+	std::string filenamePart;
+	std::string directoryPart;
+	std::vector<SourceFile*> 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 @@
 	                          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,

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/test.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/test.h	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/test.h	2005-01-31 18:25:55 UTC (rev 13371)
@@ -108,6 +108,10 @@
 {
 public:
 	void Run();
+private:
+	bool IsParentOf ( const SourceFile* parent,
+	                  const SourceFile* child );
+
 };
 
 #endif /* __TEST_H */

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_header2.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_header2.h	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_header2.h	2005-01-31 18:25:55 UTC (rev 13371)
@@ -1,2 +1,3 @@
-#include <sourcefile1/sourcefile1_header3.h>
+#include "sourcefile1/sourcefile1_header3.h"
 #include <sourcefile2/sourcefile1_dontexist.h>
+#include <sourcefile1_recurse.h>

Added: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_recurse.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_recurse.h	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_recurse.h	2005-01-31 18:25:55 UTC (rev 13371)
@@ -0,0 +1,2 @@
+#include <sourcefile1_recurse.h>
+#include <sourcefile1_header1.h>

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp	2005-01-31 12:49:46 UTC (rev 13370)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp	2005-01-31 18:25:55 UTC (rev 13371)
@@ -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 ) );
 }