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::mapstd::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& ); };