added xi:fallback support
fixed some memory leaks in Project
detect and report "end of file looking for end tag" instead of just
crashing
Modified: branches/xmlbuildsystem/reactos/ReactOS.xml
Added: branches/xmlbuildsystem/reactos/config.template.xml
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.h
Modified:
branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.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/project.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
_____
Modified: branches/xmlbuildsystem/reactos/ReactOS.xml
--- branches/xmlbuildsystem/reactos/ReactOS.xml 2005-01-09 17:24:09 UTC
(rev 12910)
+++ branches/xmlbuildsystem/reactos/ReactOS.xml 2005-01-09 19:16:35 UTC
(rev 12911)
@@ -1,6 +1,11 @@
<?xml version="1.0"?>
<!DOCTYPE project SYSTEM "tools/rbuild/project.dtd">
<project name="ReactOS" makefile="Makefile.auto"
xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="config.xml">
+ <xi:fallback>
+ <xi:include href="config.template.xml" />
+ </xi:fallback>
+ </xi:include>
<define name="_M_IX86" />
<include>include</include>
<include>w32api/include</include>
_____
Added: branches/xmlbuildsystem/reactos/config.template.xml
--- branches/xmlbuildsystem/reactos/config.template.xml 2005-01-09
17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/config.template.xml 2005-01-09
19:16:35 UTC (rev 12911)
@@ -0,0 +1,66 @@
+<!--
+ Architecture to build for
+
+ Specify one of: i386
+ Possible values in the future: alpha,i386,m68k,mips,powerpc
+-->
+
+<define name="ARCH" value="i386" />
+
+
+<!--
+ Which cpu should reactos optimze for
+ example : i486, i586, pentium, pentium2, pentum3, pentium4
+ athlon-xp, athlon-mp, k6-2,
+
+ see gcc manual for more cpu name and which cpu it can
+ be optimze for.
+-->
+
+<define name="OARCH" value="i486" />
+
+<!--
+ Whether to compile in the kernel debugger
+-->
+
+<define name="KDBG" value="0" />
+
+
+<!--
+ Whether to compile for debugging
+-->
+
+<define name="DBG" value="0" />
+
+
+<!--
+ Whether to compile with optimizations
+-->
+
+<define name="OPTIMIZED" value="0" />
+
+
+<!--
+ Whether to compile a multiprocessor or single processor version
+-->
+
+<define name="MP" value="0" />
+
+<!--
+ Whether to compile for ACPI compliant systems
+-->
+
+<define name="ACPI" value="0" />
+
+
+<!--
+ whether to use a 3GB User, 1GB Kernel memory map
+-->
+
+<define name="3GB" value="1" />
+
+
+<!--
+ Which version of NDIS do we support up to?
+<define name="NDISVERSION" value="NDIS50" />
+-->
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp
2005-01-09 17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp
2005-01-09 19:16:35 UTC (rev 12911)
@@ -22,6 +22,28 @@
string working_directory;
+class XMLInclude
+{
+public:
+ XMLElement *e;
+ Path path;
+
+ XMLInclude ( XMLElement* e_, const Path& path_ )
+ : e(e_), path(path_)
+ {
+ }
+};
+
+class XMLIncludes : public vector<XMLInclude*>
+{
+public:
+ ~XMLIncludes()
+ {
+ for ( size_t i = 0; i < this->size(); i++ )
+ delete (*this)[i];
+ }
+};
+
void
InitWorkingDirectory()
{
@@ -306,6 +328,19 @@
{
}
+XMLAttribute::XMLAttribute ( const XMLAttribute& src )
+ : name(src.name), value(src.value)
+{
+
+}
+
+XMLAttribute& XMLAttribute::operator = ( const XMLAttribute& src )
+{
+ name = src.name;
+ value = src.value;
+ return *this;
+}
+
XMLElement::XMLElement ( const string& location_ )
: location(location_),
parentElement(NULL)
@@ -451,7 +486,6 @@
// XMLParse()
// This function reads a "token" from the file loaded in XMLFile
-// REM TODO FIXME: At the moment it can't handle comments or non-xml
tags.
// if it finds a tag that is non-singular, it parses sub-elements
and/or
// inner text into the XMLElement that it is building to return.
// Return Value: an XMLElement allocated via the new operator that
contains
@@ -459,13 +493,14 @@
// (no more data)
XMLElement*
XMLParse(XMLFile& f,
+ XMLIncludes* includes,
const Path& path,
- bool* pend_tag /*= NULL*/)
+ bool* pend_tag = NULL )
{
string token;
if ( !f.get_token(token) )
return NULL;
- bool end_tag;
+ bool end_tag, is_include = false;
while ( token[0] != '<'
|| !strncmp ( token.c_str(), "<!--", 4 )
@@ -482,32 +517,10 @@
XMLElement* e = new XMLElement ( f.Location() );
bool bNeedEnd = e->Parse ( token, end_tag );
- if ( e->name == "xi:include" )
+ if ( e->name == "xi:include" && includes )
{
- XMLAttribute* att;
- att = e->GetAttribute("href",true);
- assert(att);
-
- string file ( path.Fixup(att->value,true) );
- string top_file ( Path::RelativeFromWorkingDirectory (
file ) );
- e->attributes.push_back ( new XMLAttribute ( "top_href",
top_file ) );
- XMLFile fInc;
- if ( !fInc.open ( file ) )
- throw FileNotFoundException (
- ssprintf("%s (referenced from %s)",
- file.c_str(),
- f.Location().c_str() ) );
- else
- {
- Path path2 ( path, att->value );
- for ( ;; )
- {
- XMLElement* e2 = XMLParse ( fInc, path2
);
- if ( !e2 )
- break;
- e->AddSubElement ( e2 );
- }
- }
+ includes->push_back ( new XMLInclude ( e, path ) );
+ is_include = true;
}
if ( !bNeedEnd )
@@ -531,7 +544,9 @@
{
if ( !f.get_token ( token ) || !token.size() )
{
- throw Exception ( "internal tool error -
get_token() failed when more_tokens() returned true" );
+ throw InvalidBuildFileException (
+ f.Location(),
+ "internal tool error -
get_token() failed when more_tokens() returned true" );
break;
}
if ( e->subElements.size() &&
!bThisMixingErrorReported )
@@ -556,12 +571,23 @@
}
else
{
- XMLElement* e2 = XMLParse ( f, path, &end_tag );
+ XMLElement* e2 = XMLParse ( f, is_include ? NULL
: includes, path, &end_tag );
+ if ( !e2 )
+ {
+ throw InvalidBuildFileException (
+ e->location,
+ "end of file found looking for
end tag" );
+ break;
+ }
if ( end_tag )
{
if ( e->name != e2->name )
+ {
+ delete e2;
throw XMLSyntaxErrorException (
f.Location(),
"end tag name mismatch" );
+ break;
+ }
delete e2;
break;
}
@@ -576,3 +602,118 @@
}
return e;
}
+
+void
+XMLReadFile ( XMLFile& f, XMLElement& head, XMLIncludes& includes,
const Path& path )
+{
+ for ( ;; )
+ {
+ XMLElement* e = XMLParse ( f, &includes, path );
+ if ( !e )
+ return;
+ head.AddSubElement ( e );
+ }
+}
+
+XMLElement*
+XMLLoadInclude ( XMLElement* e, const Path& path, XMLIncludes& includes
)
+{
+ // TODO FIXME
+ XMLAttribute* att;
+ att = e->GetAttribute("href",true);
+ assert(att);
+
+ string file ( path.Fixup(att->value,true) );
+ string top_file ( Path::RelativeFromWorkingDirectory ( file ) );
+ e->attributes.push_back ( new XMLAttribute ( "top_href",
top_file ) );
+ XMLFile fInc;
+ if ( !fInc.open ( file ) )
+ {
+ // look for xi:fallback element
+ for ( size_t i = 0; i < e->subElements.size(); i++ )
+ {
+ XMLElement* e2 = e->subElements[i];
+ if ( e2->name == "xi:fallback" )
+ {
+ // now look for xi:include below...
+ for ( i = 0; i < e2->subElements.size();
i++ )
+ {
+ XMLElement* e3 =
e2->subElements[i];
+ if ( e3->name == "xi:include" )
+ {
+ return XMLLoadInclude (
e3, path, includes );
+ }
+ }
+ throw InvalidBuildFileException (
+ e2->location,
+ "<xi:fallback> must have a
<xi:include> sub-element" );
+ return NULL;
+ }
+ }
+ return NULL;
+ }
+ else
+ {
+ XMLElement* new_e = new XMLElement ( e->location );
+ new_e->name = "xi:included";
+ Path path2 ( path, att->value );
+ XMLReadFile ( fInc, *new_e, includes, path2 );
+ return new_e;
+ }
+}
+
+XMLElement*
+XMLLoadFile ( const string& filename, const Path& path )
+{
+ XMLIncludes includes;
+ XMLFile f;
+
+ if ( !f.open ( filename ) )
+ throw FileNotFoundException ( filename );
+
+ XMLElement* head = new XMLElement("(virtual)");
+
+ XMLReadFile ( f, *head, includes, path );
+
+ for ( size_t i = 0; i < includes.size(); i++ )
+ {
+ XMLElement* e = includes[i]->e;
+ XMLElement* e2 = XMLLoadInclude ( includes[i]->e,
includes[i]->path, includes );
+ if ( !e2 )
+ {
+ throw FileNotFoundException (
+ ssprintf("%s (referenced from %s)",
+
e->GetAttribute("top_href",true)->value.c_str(),
+ f.Location().c_str() ) );
+ }
+ XMLElement* parent = e->parentElement;
+ XMLElement** parent_container = NULL;
+ if ( !parent )
+ {
+ delete e;
+ throw Exception ( "internal tool error:
xi:include doesn't have a parent" );
+ return NULL;
+ }
+ for ( size_t j = 0; j < parent->subElements.size(); j++
)
+ {
+ if ( parent->subElements[j] == e )
+ {
+ parent_container =
&parent->subElements[j];
+ break;
+ }
+ }
+ if ( !parent_container )
+ {
+ delete e;
+ throw Exception ( "internal tool error: couldn't
find xi:include in parent's sub-elements" );
+ return NULL;
+ }
+ // replace inclusion tree with the imported tree
+ e2->name = e->name;
+ e2->attributes = e->attributes;
+ *parent_container = e2;
+ e->attributes.resize(0);
+ delete e;
+ }
+ return head;
+}
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/XML.h 2005-01-09
17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/XML.h 2005-01-09
19:16:35 UTC (rev 12911)
@@ -52,6 +52,8 @@
XMLAttribute();
XMLAttribute ( const std::string& name_, const std::string&
value_ );
+ XMLAttribute ( const XMLAttribute& );
+ XMLAttribute& operator = ( const XMLAttribute& );
};
@@ -77,8 +79,11 @@
};
XMLElement*
+XMLLoadFile ( const std::string& filename, const Path& path );
+
+/*XMLElement*
XMLParse(XMLFile& f,
const Path& path,
- bool* pend_tag = NULL);
+ bool* pend_tag = NULL);*/
#endif//XML_H
_____
Modified:
branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.cpp
2005-01-09 17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.cpp
2005-01-09 19:16:35 UTC (rev 12911)
@@ -8,17 +8,29 @@
using std::vector;
using std::map;
-map<string,Backend::Factory*>* Backend::Factory::factories = NULL;
+map<string,Backend::Factory*>*
+Backend::Factory::factories = NULL;
+int
+Backend::Factory::ref = 0;
Backend::Factory::Factory ( const std::string& name_ )
{
string name(name_);
strlwr ( &name[0] );
- if ( !factories )
+ if ( !ref++ )
factories = new map<string,Factory*>;
(*factories)[name] = this;
}
+Backend::Factory::~Factory()
+{
+ if ( !--ref )
+ {
+ delete factories;
+ factories = NULL;
+ }
+}
+
/*static*/ Backend*
Backend::Factory::Create ( const string& name,
Project& project )
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.h
2005-01-09 17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/backend.h
2005-01-09 19:16:35 UTC (rev 12911)
@@ -13,11 +13,12 @@
class Factory
{
static std::map<std::string,Factory*>* factories;
+ static int ref;
protected:
Factory ( const std::string& name_ );
- virtual ~Factory() {}
+ virtual ~Factory();
virtual Backend* operator() ( Project& ) = 0;
_____
Modified:
branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler
.cpp
---
branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler
.cpp 2005-01-09 17:24:09 UTC (rev 12910)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler
.cpp 2005-01-09 19:16:35 UTC (rev 12911)
@@ -12,17 +12,28 @@
map<ModuleType,MingwModuleHandler*>*
MingwModuleHandler::handler_map = NULL;
+int
+MingwModuleHandler::ref = 0;
FILE*
MingwModuleHandler::fMakefile = NULL;
MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype )
{
- if ( !handler_map )
+ if ( !ref++ )
handler_map = new map<ModuleType,MingwModuleHandler*>;
(*handler_map)[moduletype] = this;
}
+MingwModuleHandler::~MingwModuleHandler()
+{
+ if ( !--ref )
+ {
+ delete handler_map;
+ handler_map = NULL;
+ }
+}
+
/*static*/ void
MingwModuleHandler::SetMakefile ( FILE* f )
{
_____
Modified:
branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler
.h
---
branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler
.h 2005-01-09 17:24:09 UTC (rev 12910)
+++
branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler
.h 2005-01-09 19:16:35 UTC (rev 12911)
@@ -7,9 +7,10 @@
{
public:
static std::map<ModuleType,MingwModuleHandler*>* handler_map;
+ static int ref;
MingwModuleHandler ( ModuleType moduletype );
- virtual ~MingwModuleHandler() {}
+ virtual ~MingwModuleHandler();
static void SetMakefile ( FILE* f );
static MingwModuleHandler* LookupHandler ( const std::string&
location,
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp
2005-01-09 17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp
2005-01-09 19:16:35 UTC (rev 12911)
@@ -7,39 +7,48 @@
using std::string;
using std::vector;
-Project::Project()
+/*Project::Project()
+ : node(NULL), head(NULL)
{
-}
+}*/
Project::Project ( const string& filename )
+ : xmlfile(filename), node(NULL), head(NULL)
{
- if ( !xmlfile.open ( filename ) )
- throw FileNotFoundException ( filename );
ReadXml();
}
Project::~Project ()
{
- for ( size_t i = 0; i < modules.size (); i++ )
+ size_t i;
+ for ( i = 0; i < modules.size (); i++ )
delete modules[i];
- delete node;
+ for ( i = 0; i < includes.size(); i++ )
+ delete includes[i];
+ for ( i = 0; i < defines.size(); i++ )
+ delete defines[i];
+ delete head;
}
void
-Project::ReadXml ()
+Project::ReadXml()
{
Path path;
-
- do
+ head = XMLLoadFile ( xmlfile, path );
+ node = NULL;
+ for ( size_t i = 0; i < head->subElements.size(); i++ )
{
- node = XMLParse ( xmlfile, path );
- if ( !node )
- throw InvalidBuildFileException (
- node->location,
- "Document contains no 'project' tag." );
- } while ( node->name != "project" );
+ if ( head->subElements[i]->name == "project" )
+ {
+ node = head->subElements[i];
+ this->ProcessXML ( "." );
+ return;
+ }
+ }
- this->ProcessXML ( "." );
+ throw InvalidBuildFileException (
+ node->location,
+ "Document contains no 'project' tag." );
}
void
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
2005-01-09 17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
2005-01-09 19:16:35 UTC (rev 12911)
@@ -31,38 +31,6 @@
Backend* backend = Backend::Factory::Create (
buildtarget, project );
backend->Process ();
delete backend;
-
- // REM TODO FIXME actually do something with Project
object...
-#if 0
- printf ( "Found %d modules:\n", project.modules.size()
);
- for ( size_t i = 0; i < project.modules.size(); i++ )
- {
- Module& m = *project.modules[i];
- printf ( "\t%s in folder: %s\n",
- m.name.c_str(),
- m.path.c_str() );
- printf ( "\txml dependencies:\n\t\t%s\n",
- projectFilename.c_str() );
- const XMLElement* e = &m.node;
- while ( e )
- {
- if ( e->name == "xi:include" )
- {
- const XMLAttribute* att =
e->GetAttribute("top_href",false);
- if ( att )
- {
- printf ( "\t\t%s\n",
att->value.c_str() );
- }
- }
- e = e->parentElement;
- }
- printf ( "\tfiles:\n" );
- for ( size_t j = 0; j < m.files.size(); j++ )
- {
- printf ( "\t\t%s\n",
m.files[j]->name.c_str() );
- }
- }
-#endif
return 0;
}
_____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
2005-01-09 17:24:09 UTC (rev 12910)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
2005-01-09 19:16:35 UTC (rev 12911)
@@ -33,6 +33,8 @@
class Project
{
+ std::string xmlfile;
+ XMLElement *node, *head;
public:
std::string name;
std::string makefile;
@@ -40,7 +42,7 @@
std::vector<Include*> includes;
std::vector<Define*> defines;
- Project ();
+ //Project ();
Project ( const std::string& filename );
~Project ();
void ProcessXML ( const std::string& path );
@@ -48,10 +50,12 @@
const Module* LocateModule ( const std::string& name ) const;
private:
void ReadXml ();
- XMLFile xmlfile;
- XMLElement* node;
void ProcessXMLSubElement ( const XMLElement& e,
const std::string& path );
+
+ // disable copy semantics
+ Project ( const Project& );
+ Project& operator = ( const Project& );
};