xml nodes now store the location they were parsed from; invalidbuildexceptions now required a location of the error; don't allow modules to process xml until all modules are created; don't allow libraries, defines, includes, etc to process xml until all modules have processed; don't allow module to link against itself or a non-existant module; don't allow library to specify non-existant module;
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/define.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/include.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp	2005-01-08 03:37:32 UTC (rev 12879)
@@ -306,8 +306,9 @@
 {
 }
 
-XMLElement::XMLElement()
-	: parentElement(NULL)
+XMLElement::XMLElement ( const string& location_ )
+	: location(location_),
+	  parentElement(NULL)
 {
 }
 
@@ -476,7 +477,7 @@
 			return NULL;
 	}
 
-	XMLElement* e = new XMLElement;
+	XMLElement* e = new XMLElement ( f.Location() );
 	bool bNeedEnd = e->Parse ( token, end_tag );
 
 	if ( e->name == "xi:include" )

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/XML.h	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/XML.h	2005-01-08 03:37:32 UTC (rev 12879)
@@ -58,13 +58,14 @@
 class XMLElement
 {
 public:
+	std::string location;
 	std::string name;
 	std::vector<XMLAttribute*> attributes;
 	XMLElement* parentElement;
 	std::vector<XMLElement*> subElements;
 	std::string value;
 
-	XMLElement();
+	XMLElement ( const std::string& location_ );
 	~XMLElement();
 	bool Parse(const std::string& token,
 	           bool& end_tag);

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-01-08 03:37:32 UTC (rev 12879)
@@ -48,7 +48,7 @@
 	{
 		if ( dependencies.size () > 0 )
 			dependencies += " ";
-		Module* importedModule = module.project->LocateModule ( module.libraries[i]->name );
+		const Module* importedModule = module.project.LocateModule ( module.libraries[i]->name );
 		assert ( importedModule != NULL );
 		dependencies += importedModule->GetPath ().c_str ();
 	}
@@ -117,7 +117,7 @@
 string
 MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const
 {
-	string parameters = GenerateGccDefineParametersFromVector ( module.project->defines );
+	string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );
 	string s = GenerateGccDefineParametersFromVector ( module.defines );
 	if (s.length () > 0)
 	{
@@ -160,7 +160,7 @@
 MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const
 {
 	string parameters = GenerateGccIncludeParametersFromVector ( ".",
-	                                                             module.project->includes );
+	                                                             module.project.includes );
 	string s = GenerateGccIncludeParametersFromVector ( module.path,
 	                                                    module.includes );
 	if (s.length () > 0)

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/define.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/define.cpp	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/define.cpp	2005-01-08 03:37:32 UTC (rev 12879)
@@ -6,23 +6,23 @@
 using std::string;
 using std::vector;
 
-Define::Define ( Project* project,
+Define::Define ( const Project& project,
                  const XMLElement& defineNode )
 	: project(project),
 	  module(NULL),
 	  node(defineNode)
 {
-	Initialize (defineNode);
+	Initialize();
 }
 
-Define::Define ( Project* project,
-	             Module* module,
+Define::Define ( const Project& project,
+	             const Module* module,
                  const XMLElement& defineNode )
 	: project(project),
 	  module(module),
 	  node(defineNode)
 {
-	Initialize (defineNode);
+	Initialize();
 }
 
 Define::~Define ()
@@ -30,15 +30,15 @@
 }
 
 void
-Define::Initialize ( const XMLElement& defineNode )
+Define::Initialize()
 {
-	const XMLAttribute* att = defineNode.GetAttribute ( "name", true );
+	const XMLAttribute* att = node.GetAttribute ( "name", true );
 	assert(att);
 	name = att->value;
-	value = defineNode.value;
+	value = node.value;
 }
 
 void
-Define::ProcessXML ( const XMLElement& e )
+Define::ProcessXML()
 {
 }

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp	2005-01-08 03:37:32 UTC (rev 12879)
@@ -58,14 +58,14 @@
 }
 
 
-InvalidBuildFileException::InvalidBuildFileException ( const char* message,
+InvalidBuildFileException::InvalidBuildFileException ( const string& location,
+                                                       const char* message,
                                                        ...)
 {
 	va_list args;
 	va_start ( args,
 	           message );
-	SetMessage ( message,
-	            args );
+	SetLocationMessage ( location, message, args );
 	va_end ( args );
 }
 
@@ -73,6 +73,13 @@
 {
 }
 
+void
+InvalidBuildFileException::SetLocationMessage ( const std::string& location,
+                                                const char* message,
+                                                va_list args )
+{
+	Message = location + ": " + ssvprintf ( message, args );
+}
 
 XMLSyntaxErrorException::XMLSyntaxErrorException ( const string& location,
 	                                               const char* message,
@@ -81,7 +88,7 @@
 	va_list args;
 	va_start ( args,
 	          message );
-	Message = location + ": " + ssvprintf ( message, args );
+	SetLocationMessage ( location, message, args );
 	va_end ( args );
 }
 

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/exception.h	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/exception.h	2005-01-08 03:37:32 UTC (rev 12879)
@@ -40,12 +40,15 @@
 	std::string Filename;
 };
 
-
 class InvalidBuildFileException : public Exception
 {
 public:
-	InvalidBuildFileException ( const char* message,
+	InvalidBuildFileException ( const std::string& location,
+	                            const char* message,
 	                            ...);
+	void SetLocationMessage ( const std::string& location,
+	                          const char* message,
+	                          va_list args );
 protected:
 	InvalidBuildFileException ();
 };

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/include.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/include.cpp	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/include.cpp	2005-01-08 03:37:32 UTC (rev 12879)
@@ -6,21 +6,23 @@
 using std::string;
 using std::vector;
 
-Include::Include ( Project* project,
+Include::Include ( const Project& project_,
                    const XMLElement& includeNode )
-	: project(project),
+	: project(project_),
+	  module(NULL),
 	  node(includeNode)
 {
-	Initialize ( includeNode );
+	Initialize();
 }
 
-Include::Include ( Project* project,
-	               Module* module,
+Include::Include ( const Project& project_,
+	               const Module* module_,
 	               const XMLElement& includeNode )
-	: project(project),
+	: project(project_),
+	  module(module_),
 	  node(includeNode)
 {
-	Initialize ( includeNode );
+	Initialize();
 }
 
 Include::~Include ()
@@ -28,12 +30,12 @@
 }
 
 void
-Include::Initialize ( const XMLElement& includeNode )
+Include::Initialize()
 {
-	directory = FixSeparator ( includeNode.value );
+	directory = FixSeparator ( node.value );
 }
 
 void
-Include::ProcessXML ( const XMLElement& e )
+Include::ProcessXML()
 {
 }

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-01-08 03:37:32 UTC (rev 12879)
@@ -21,14 +21,17 @@
 	return s2;
 }
 
-Module::Module ( Project* project,
+Module::Module ( const Project& project,
                  const XMLElement& moduleNode,
                  const string& modulePath )
 	: project(project),
 	  node(moduleNode)
 {
-  	path = FixSeparator ( modulePath );
+	if ( node.name != "module" )
+		throw Exception ( "internal tool error: Module created with non-<module> node" );
 
+	path = FixSeparator ( modulePath );
+
 	const XMLAttribute* att = moduleNode.GetAttribute ( "name", true );
 	assert(att);
 	name = att->value;
@@ -54,17 +57,30 @@
 }
 
 void
-Module::ProcessXML ( const XMLElement& e,
-                     const string& path )
+Module::ProcessXML()
 {
+	size_t i;
+	for ( i = 0; i < node.subElements.size(); i++ )
+		ProcessXMLSubElement ( *node.subElements[i], path );
+	for ( i = 0; i < libraries.size(); i++ )
+		libraries[i]->ProcessXML();
+}
+
+void
+Module::ProcessXMLSubElement ( const XMLElement& e,
+                               const string& path )
+{
+	bool subs_invalid = false;
 	string subpath ( path );
 	if ( e.name == "file" && e.value.size () )
 	{
 		files.push_back ( new File ( FixSeparator ( path + CSEP + e.value ) ) );
+		subs_invalid = true;
 	}
 	else if ( e.name == "library" && e.value.size () )
 	{
-		libraries.push_back ( new Library ( e.value ) );
+		libraries.push_back ( new Library ( e, *this, e.value ) );
+		subs_invalid = true;
 	}
 	else if ( e.name == "directory" )
 	{
@@ -74,18 +90,21 @@
 	}
 	else if ( e.name == "include" )
 	{
-		Include* include = new Include ( project, this, e );
-		includes.push_back ( include );
-		include->ProcessXML ( e );
+		includes.push_back ( new Include ( project, this, e ) );
+		subs_invalid = true;
 	}
 	else if ( e.name == "define" )
 	{
-		Define* define = new Define ( project, this, e );
-		defines.push_back ( define );
-		define->ProcessXML ( e );
+		defines.push_back ( new Define ( project, this, e ) );
+		subs_invalid = true;
 	}
+	if ( subs_invalid && e.subElements.size() )
+		throw InvalidBuildFileException (
+			e.location,
+			"<%s> cannot have sub-elements",
+			e.name.c_str() );
 	for ( size_t i = 0; i < e.subElements.size (); i++ )
-		ProcessXML ( *e.subElements[i], subpath );
+		ProcessXMLSubElement ( *e.subElements[i], subpath );
 }
 
 ModuleType
@@ -102,7 +121,7 @@
 }
 
 string
-Module::GetDefaultModuleExtension ()
+Module::GetDefaultModuleExtension () const
 {
 	switch (type)
 	{
@@ -130,7 +149,27 @@
 }
 
 
-Library::Library ( const string& _name )
-	: name(_name)
+Library::Library ( const XMLElement& _node,
+                   const Module& _module,
+                   const string& _name )
+	: node(_node),
+	  module(_module),
+	  name(_name)
 {
+	if ( module.name == name )
+		throw InvalidBuildFileException (
+			node.location,
+			"module '%s' cannot link against itself",
+			name.c_str() );
 }
+
+void
+Library::ProcessXML()
+{
+	if ( !module.project.LocateModule ( name ) )
+		throw InvalidBuildFileException (
+			node.location,
+			"module '%s' trying to link against non-existant module '%s'",
+			module.name.c_str(),
+			name.c_str() );
+}

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp	2005-01-08 03:37:32 UTC (rev 12879)
@@ -22,7 +22,7 @@
 {
 	for ( size_t i = 0; i < modules.size (); i++ )
 		delete modules[i];
-	delete head;
+	delete node;
 }
 
 void
@@ -32,38 +32,54 @@
 
 	do
 	{
-		head = XMLParse ( xmlfile, path );
-		if ( !head )
-			throw InvalidBuildFileException ( "Document contains no 'project' tag." );
-	} while ( head->name != "project" );
+		node = XMLParse ( xmlfile, path );
+		if ( !node )
+			throw InvalidBuildFileException (
+				node->location,
+				"Document contains no 'project' tag." );
+	} while ( node->name != "project" );
 
-	this->ProcessXML ( *head, "." );
+	this->ProcessXML ( "." );
 }
 
 void
-Project::ProcessXML ( const XMLElement& e, const string& path )
+Project::ProcessXML ( const string& path )
 {
 	const XMLAttribute *att;
+	if ( node->name != "project" )
+		throw Exception ( "internal tool error: Project::ProcessXML() called with non-<project> node" );
+
+	att = node->GetAttribute ( "name", false );
+	if ( !att )
+		name = "Unnamed";
+	else
+		name = att->value;
+
+	att = node->GetAttribute ( "makefile", true );
+	assert(att);
+	makefile = att->value;
+
+	size_t i;
+	for ( i = 0; i < node->subElements.size(); i++ )
+		ProcessXMLSubElement ( *node->subElements[i], path );
+	for ( i = 0; i < modules.size(); i++ )
+		modules[i]->ProcessXML();
+	for ( i = 0; i < includes.size(); i++ )
+		includes[i]->ProcessXML();
+	for ( i = 0; i < defines.size(); i++ )
+		defines[i]->ProcessXML();
+}
+
+void
+Project::ProcessXMLSubElement ( const XMLElement& e, const string& path )
+{
+	bool subs_invalid = false;
 	string subpath(path);
-	if ( e.name == "project" )
+	if ( e.name == "module" )
 	{
-		att = e.GetAttribute ( "name", false );
-		if ( !att )
-			name = "Unnamed";
-		else
-			name = att->value;
-
-		att = e.GetAttribute ( "makefile", true );
-		assert(att);
-		makefile = att->value;
+		modules.push_back ( new Module ( *this, e, path ) );
+		return; // defer processing until later
 	}
-	else if ( e.name == "module" )
-	{
-		Module* module = new Module ( this, e, path );
-		modules.push_back ( module );
-		module->ProcessXML ( e, path );
-		return;
-	}
 	else if ( e.name == "directory" )
 	{
 		const XMLAttribute* att = e.GetAttribute ( "name", true );
@@ -72,22 +88,25 @@
 	}
 	else if ( e.name == "include" )
 	{
-		Include* include = new Include ( this, e );
-		includes.push_back ( include );
-		include->ProcessXML ( e );
+		includes.push_back ( new Include ( *this, e ) );
+		subs_invalid = true;
 	}
 	else if ( e.name == "define" )
 	{
-		Define* define = new Define ( this, e );
-		defines.push_back ( define );
-		define->ProcessXML ( e );
+		defines.push_back ( new Define ( *this, e ) );
+		subs_invalid = true;
 	}
+	if ( subs_invalid && e.subElements.size() )
+		throw InvalidBuildFileException (
+			e.location,
+			"<%s> cannot have sub-elements",
+			e.name.c_str() );
 	for ( size_t i = 0; i < e.subElements.size (); i++ )
-		ProcessXML ( *e.subElements[i], subpath );
+		ProcessXMLSubElement ( *e.subElements[i], subpath );
 }
 
 Module*
-Project::LocateModule ( string name )
+Project::LocateModule ( const string& name )
 {
 	for ( size_t i = 0; i < modules.size (); i++ )
 	{
@@ -97,3 +116,15 @@
 
 	return NULL;
 }
+
+const Module*
+Project::LocateModule ( const string& name ) const
+{
+	for ( size_t i = 0; i < modules.size (); i++ )
+	{
+		if (modules[i]->name == name)
+			return modules[i];
+	}
+
+	return NULL;
+}

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-08 02:33:09 UTC (rev 12878)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-08 03:37:32 UTC (rev 12879)
@@ -40,13 +40,15 @@
 	Project ();
 	Project ( const std::string& filename );
 	~Project ();
-	void ProcessXML ( const XMLElement& e,
-	                  const std::string& path );
-	Module* LocateModule ( std::string name );
+	void ProcessXML ( const std::string& path );
+	Module* LocateModule ( const std::string& name );
+	const Module* LocateModule ( const std::string& name ) const;
 private:
 	void ReadXml ();
 	XMLFile xmlfile;
-	XMLElement* head;
+	XMLElement* node;
+	void ProcessXMLSubElement ( const XMLElement& e,
+	                            const std::string& path );
 };
 
 
@@ -61,7 +63,7 @@
 class Module
 {
 public:
-	Project* project;
+	const Project& project;
 	const XMLElement& node;
 	std::string name;
 	std::string extension;
@@ -72,56 +74,58 @@
 	std::vector<Include*> includes;
 	std::vector<Define*> defines;
 
-	Module ( Project* project,
+	Module ( const Project& project,
 	         const XMLElement& moduleNode,
 	         const std::string& modulePath );
 	~Module ();
 	ModuleType GetModuleType (const XMLAttribute& attribute );
 	std::string GetPath () const;
-	void ProcessXML ( const XMLElement& e, const std::string& path );
+	void ProcessXML();
 private:
-	std::string GetDefaultModuleExtension ();
+	std::string GetDefaultModuleExtension () const;
+	void ProcessXMLSubElement ( const XMLElement& e,
+	                            const std::string& path );
 };
 
 
 class Include
 {
 public:
-	Project* project;
-	Module* module;
+	const Project& project;
+	const Module* module;
 	const XMLElement& node;
 	std::string directory;
 
-	Include ( Project* project,
+	Include ( const Project& project,
 	          const XMLElement& includeNode );
-	Include ( Project* project,
-	          Module* module,
+	Include ( const Project& project,
+	          const Module* module,
 	          const XMLElement& includeNode );
 	~Include ();
-	void ProcessXML ( const XMLElement& e );
+	void ProcessXML();
 private:
-	void Initialize ( const XMLElement& includeNode );
+	void Initialize();
 };
 
 
 class Define
 {
 public:
-	Project* project;
-	Module* module;
+	const Project& project;
+	const Module* module;
 	const XMLElement& node;
 	std::string name;
 	std::string value;
 
-	Define ( Project* project,
+	Define ( const Project& project,
 	         const XMLElement& defineNode );
-	Define ( Project* project,
-	         Module* module,
+	Define ( const Project& project,
+	         const Module* module,
 	         const XMLElement& defineNode );
 	~Define();
-	void ProcessXML ( const XMLElement& e );
+	void ProcessXML();
 private:
-	void Initialize ( const XMLElement& defineNode );
+	void Initialize();
 };
 
 
@@ -137,9 +141,15 @@
 class Library
 {
 public:
+	const XMLElement& node;
+	const Module& module;
 	std::string name;
 
-	Library ( const std::string& _name );
+	Library ( const XMLElement& _node,
+	          const Module& _module,
+	          const std::string& _name );
+
+	void ProcessXML();
 };
 
 extern std::string