Started on automatic dependencies support
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.h
Added:
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/makefile
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/test.h
Modified:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/automaticdepende
ncy.xml
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1/
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1/sour
cefile1_header3.h
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1.c
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er1.h
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er2.h
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/XML.h 2005-01-28
18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/XML.h 2005-01-28
19:11:22 UTC (rev 13353)
@@ -8,6 +8,13 @@
void
InitWorkingDirectory();
+#ifdef _MSC_VER
+unsigned __int64
+#else
+unsigned long long
+#endif
+filelen ( FILE* f );
+
class Path
{
std::vector<std::string> path;
_____
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/automaticdependency.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/automaticdependency.cpp
2005-01-28 18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/automaticdependency.cpp
2005-01-28 19:11:22 UTC (rev 13353)
@@ -0,0 +1,240 @@
+#include "pch.h"
+
+#ifdef WIN32
+#include <direct.h>
+#include <io.h>
+#else
+#include <sys/stat.h>
+#define _MAX_PATH 255
+#endif
+#include <assert.h>
+
+#include "rbuild.h"
+
+/* 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 )
+ : automaticDependency ( automaticDependency ),
+ module ( module ),
+ filename ( filename )
+{
+}
+
+void
+SourceFile::Close ()
+{
+ buf.resize ( 0 );
+ p = end = NULL;
+}
+
+void
+SourceFile::Open ()
+{
+ Close ();
+ FILE* f = fopen ( filename.c_str (), "rb" );
+ if ( !f )
+ throw FileNotFoundException ( filename );
+ unsigned long len = (unsigned long) filelen ( f );
+ if ( len > MAX_BYTES_TO_READ)
+ len = MAX_BYTES_TO_READ;
+ buf.resize ( len );
+ fread ( &buf[0], 1, len, f );
+ fclose ( f );
+ p = buf.c_str ();
+ end = p + len;
+}
+
+void
+SourceFile::SkipWhitespace ()
+{
+ while ( p < end && isspace ( *p ))
+ p++;
+}
+
+bool
+SourceFile::ReadInclude ( string& filename )
+{
+ while ( p < end )
+ {
+ if ( ( *p == '#') && ( end - p > 8 ) )
+ {
+ if ( strncmp ( p, "#include", 8 ) == 0 )
+ {
+ p += 8;
+ SkipWhitespace ();
+ if ( p < end && *p == '<' || *p == '"' )
+ {
+ p++;
+ filename.resize ( MAX_PATH );
+ int i = 0;
+ while ( p < end && *p != '>' &&
*p != '"' && *p != '\n' )
+ filename[i++] = *p++;
+ filename.resize ( i );
+ return true;
+ }
+ }
+ }
+ p++;
+ }
+ filename = "";
+ return false;
+}
+
+SourceFile*
+SourceFile::ParseFile ( const string& normalizedFilename )
+{
+ string extension = GetExtension ( normalizedFilename );
+ if ( extension == ".c" || extension == ".C" || extension ==
".h"
|| extension == ".H")
+ {
+ SourceFile* sourceFile =
automaticDependency->RetrieveFromCacheOrParse ( module,
+
normalizedFilename );
+ return sourceFile;
+ }
+ return NULL;
+}
+
+void
+SourceFile::Parse ()
+{
+ Open ();
+ while ( p < end )
+ {
+ string includedFilename ( "" );
+ //printf ( "Parsing '%s'\n", filename.c_str () );
+
+ while ( ReadInclude ( includedFilename ))
+ {
+ string resolvedFilename ( "" );
+ bool locatedFile =
automaticDependency->LocateIncludedFile ( module,
+
includedFilename,
+
resolvedFilename );
+ if ( locatedFile )
+ {
+ SourceFile* sourceFile = ParseFile (
resolvedFilename );
+ files.push_back ( sourceFile );
+ }
+ }
+ p++;
+ }
+ Close ();
+}
+
+string
+SourceFile::Location () const
+{
+ int line = 1;
+ const char* end_of_line = strchr ( buf.c_str (), '\n' );
+ while ( end_of_line && end_of_line < p )
+ {
+ ++line;
+ end_of_line = strchr ( end_of_line + 1, '\n' );
+ }
+ return ssprintf ( "%s(%i)",
+ filename.c_str (),
+ line );
+}
+
+
+AutomaticDependency::AutomaticDependency ( const Project& project )
+ : project ( project )
+{
+}
+
+AutomaticDependency::~AutomaticDependency ()
+{
+ std::map<std::string, SourceFile*>::iterator theIterator;
+ for ( theIterator = sourcefile_map.begin (); theIterator !=
sourcefile_map.end (); theIterator++ )
+ delete theIterator->second;
+}
+
+void
+AutomaticDependency::Process ()
+{
+ for ( size_t i = 0; i < project.modules.size (); i++ )
+ ProcessModule ( *project.modules[i] );
+}
+
+void
+AutomaticDependency::ProcessModule ( Module& module )
+{
+ for ( size_t i = 0; i < module.files.size (); i++ )
+ ProcessFile ( module, *module.files[i] );
+}
+
+void
+AutomaticDependency::ProcessFile ( Module& module,
+ const File& file )
+{
+ string normalizedFilename = NormalizeFilename ( file.name );
+ SourceFile sourceFile = SourceFile ( this,
+ module,
+ normalizedFilename );
+ sourceFile.Parse ();
+}
+
+bool
+AutomaticDependency::LocateIncludedFile ( const string& directory,
+ const string&
includedFilename,
+ string& resolvedFilename )
+{
+ string normalizedFilename = NormalizeFilename ( directory + SSEP
+ includedFilename );
+ FILE* f = fopen ( normalizedFilename.c_str (), "rb" );
+ if ( f != NULL )
+ {
+ fclose ( f );
+ resolvedFilename = normalizedFilename;
+ return true;
+ }
+ resolvedFilename = "";
+ return false;
+}
+
+bool
+AutomaticDependency::LocateIncludedFile ( Module& module,
+ const string&
includedFilename,
+ string& resolvedFilename )
+{
+ for ( size_t i = 0; i < module.includes.size (); i++ )
+ {
+ Include* include = module.includes[0];
+ if ( LocateIncludedFile ( include->directory,
+ includedFilename,
+ resolvedFilename ) )
+ return true;
+ }
+
+ /* FIXME: Ifs */
+
+ resolvedFilename = "";
+ return false;
+}
+
+SourceFile*
+AutomaticDependency::RetrieveFromCacheOrParse ( Module& module,
+ const string&
filename )
+{
+ SourceFile* sourceFile = sourcefile_map[filename];
+ if ( sourceFile == NULL )
+ {
+ sourceFile = new SourceFile ( this,
+ module,
+ filename );
+ sourceFile->Parse ();
+ sourcefile_map[filename] = sourceFile;
+ }
+ return sourceFile;
+}
+
+SourceFile*
+AutomaticDependency::RetrieveFromCache ( Module& module,
+ 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-28 18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
2005-01-28 19:11:22 UTC (rev 13353)
@@ -35,6 +35,7 @@
Module& module = *ProjectNode.modules[i];
ProcessModule ( module );
}
+ //GenerateAutomaticDependencies ();
CloseMakefile ();
}
@@ -240,6 +241,52 @@
}
void
+MingwBackend::GenerateAutomaticDependencies () const
+{
+ AutomaticDependency automaticDependency ( ProjectNode );
+ automaticDependency.Process ();
+
+ for ( size_t mi = 0; mi < ProjectNode.modules.size (); mi++ )
+ {
+ Module& module = *ProjectNode.modules[mi];
+ for ( size_t fi = 0; fi < module.files.size (); fi++ )
+ {
+ File& file = *module.files[fi];
+ string normalizedFilename = NormalizeFilename (
file.name );
+ SourceFile* sourceFile =
automaticDependency.RetrieveFromCache ( module,
+
normalizedFilename );
+ if ( sourceFile != NULL )
+ {
+ string dependencies ( "" );
+ GenerateAutomaticDependenciesForFile (
sourceFile,
+ dependencies
);
+ fprintf ( fMakefile,
+ "%s:: %s",
+ normalizedFilename.c_str (),
+ dependencies.c_str () );
+ }
+ }
+ }
+}
+
+void
+MingwBackend::GenerateAutomaticDependenciesForFile ( SourceFile*
sourceFile,
+ string&
dependencies ) const
+{
+ if ( dependencies.size () > 0 )
+ dependencies += " ";
+ dependencies += sourceFile->filename;
+
+ for ( size_t i = 0; i < sourceFile->files.size (); i++)
+ {
+ SourceFile* childSourceFile = sourceFile->files[0];
+
+ GenerateAutomaticDependenciesForFile ( childSourceFile,
+ dependencies );
+ }
+}
+
+void
MingwBackend::ProcessModule ( Module& module ) const
{
MingwModuleHandler* h = MingwModuleHandler::LookupHandler (
_____
Modified:
branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
2005-01-28 18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
2005-01-28 19:11:22 UTC (rev 13353)
@@ -27,6 +27,9 @@
void GenerateGlobalVariables () const;
bool IncludeInAllTarget ( const Module& module ) const;
void GenerateAllTarget () const;
+ void GenerateAutomaticDependencies () const;
+ void GenerateAutomaticDependenciesForFile ( SourceFile*
sourceFile,
+ std::string&
dependencies ) const;
FILE* fMakefile;
};
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/makefile
--- branches/xmlbuildsystem/reactos/tools/rbuild/makefile
2005-01-28 18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/makefile
2005-01-28 19:11:22 UTC (rev 13353)
@@ -17,6 +17,7 @@
BASE_OBJECTS = \
$(BACKEND_BASE_OBJECTS) \
+ automaticdependency.o \
compilerflag.o \
define.o \
exception.o \
@@ -37,7 +38,8 @@
tests/invoketest.o \
tests/linkerflagtest.o \
tests/moduletest.o \
- tests/projecttest.o
+ tests/projecttest.o \
+ tests/sourcefiletest.o
TEST_OBJECTS = $(BASE_OBJECTS) $(TESTS) tests/alltests.o
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
2005-01-28 18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
2005-01-28 19:11:22 UTC (rev 13353)
@@ -30,7 +30,8 @@
{
string projectFilename ( "ReactOS.xml" );
Project project ( projectFilename );
- Backend* backend = Backend::Factory::Create (
buildtarget, project );
+ Backend* backend = Backend::Factory::Create (
buildtarget,
+ project );
backend->Process ();
delete backend;
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
2005-01-28 18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
2005-01-28 19:11:22 UTC (rev 13353)
@@ -35,7 +35,10 @@
class CompilerFlag;
class LinkerFlag;
class Property;
+class AutomaticDependency;
+class SourceFileTest;
+
class Project
{
std::string xmlfile;
@@ -343,6 +346,58 @@
void ProcessXML();
};
+
+class SourceFile
+{
+public:
+ SourceFile ( AutomaticDependency* automaticDependency,
+ Module& module,
+ const std::string& filename );
+ SourceFile* ParseFile ( const std::string& normalizedFilename );
+ void Parse ();
+ std::string Location () const;
+ std::vector<SourceFile*> files;
+ AutomaticDependency* automaticDependency;
+ Module& module;
+ std::string filename;
+private:
+ void Close ();
+ void Open ();
+ void SkipWhitespace ();
+ bool ReadInclude ( std::string& filename );
+ std::string buf;
+ const char *p;
+ const char *end;
+};
+
+
+class AutomaticDependency
+{
+ friend class SourceFileTest;
+public:
+ const Project& project;
+
+ AutomaticDependency ( const Project& project );
+ ~AutomaticDependency ();
+ void Process ();
+ bool LocateIncludedFile ( const std::string& directory,
+ const std::string& includedFilename,
+ std::string& resolvedFilename );
+ bool LocateIncludedFile ( Module& module,
+ const std::string& includedFilename,
+ std::string& resolvedFilename );
+ SourceFile* RetrieveFromCacheOrParse ( Module& module,
+ const std::string&
filename );
+ SourceFile* RetrieveFromCache ( Module& module,
+ const std::string& filename );
+private:
+ void ProcessModule ( Module& module );
+ void ProcessFile ( Module& module,
+ const File& file );
+ std::map<std::string, SourceFile*> sourcefile_map;
+};
+
+
extern std::string
FixSeparator ( const std::string& s );
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/test.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/test.h 2005-01-28
18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/test.h 2005-01-28
19:11:22 UTC (rev 13353)
@@ -96,10 +96,18 @@
void Run();
};
+
class FunctionTest : public BaseTest
{
public:
void Run();
};
+
+class SourceFileTest : public BaseTest
+{
+public:
+ void Run();
+};
+
#endif /* __TEST_H */
_____
Modified:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp
2005-01-28 18:35:21 UTC (rev 13352)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp
2005-01-28 19:11:22 UTC (rev 13353)
@@ -177,6 +177,7 @@
tests.push_back(new LinkerFlagTest());
tests.push_back(new IfTest());
tests.push_back(new FunctionTest());
+ tests.push_back(new SourceFileTest());
}
};
_____
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/automaticdepende
ncy.xml
---
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/automaticdepende
ncy.xml 2005-01-28 18:35:21 UTC (rev 13352)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/automaticdepende
ncy.xml 2005-01-28 19:11:22 UTC (rev 13353)
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<project name="Project" makefile="Makefile">
+ <directory name="tests">
+ <directory name="data">
+ <module name="module1" type="buildtool">
+ <include base="module1">.</include>
+ <file>sourcefile1.c</file>
+ </module>
+ </directory>
+ </directory>
+</project>
_____
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1/sour
cefile1_header3.h
---
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1/sour
cefile1_header3.h 2005-01-28 18:35:21 UTC (rev 13352)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1/sour
cefile1_header3.h 2005-01-28 19:11:22 UTC (rev 13353)
@@ -0,0 +1 @@
+/* empty */
_____
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1.c
---
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1.c
2005-01-28 18:35:21 UTC (rev 13352)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1.c
2005-01-28 19:11:22 UTC (rev 13353)
@@ -0,0 +1,13 @@
+/*
+ * ReactOS kernel
+ */
+/* $Id: main.c 12694 2005-01-01 11:47:33Z hbirr $
+ * FILE: ntoskrnl/ke/main.c
+ */
+
+/* INCLUDES
*****************************************************************/
+
+#include <sourcefile1_header1.h>
+#include <sourcefile1_header2.h>
+
+/* GLOBALS
*******************************************************************/
_____
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er1.h
---
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er1.h 2005-01-28 18:35:21 UTC (rev 13352)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er1.h 2005-01-28 19:11:22 UTC (rev 13353)
@@ -0,0 +1 @@
+#include <sourcefile1_header2.h>
_____
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er2.h
---
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er2.h 2005-01-28 18:35:21 UTC (rev 13352)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/sourcefile1_head
er2.h 2005-01-28 19:11:22 UTC (rev 13353)
@@ -0,0 +1,2 @@
+#include <sourcefile1/sourcefile1_header3.h>
+#include <sourcefile2/sourcefile1_dontexist.h>
_____
Added:
branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp
---
branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp
2005-01-28 18:35:21 UTC (rev 13352)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/tests/sourcefiletest.cpp
2005-01-28 19:11:22 UTC (rev 13353)
@@ -0,0 +1,11 @@
+#include "test.h"
+
+using std::string;
+
+void SourceFileTest::Run()
+{
+ const Project project ( "tests/data/automaticdependency.xml" );
+ AutomaticDependency automaticDependency ( project );
+ automaticDependency.Process ();
+ ARE_EQUAL(3, automaticDependency.sourcefile_map.size());
+}