Generate MinGW makefile in the backend.
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.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/exception.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.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/tools/rbuild/tests/data/module.xml
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/project.xml
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/projecttest.cpp

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/XML.cpp	2005-01-05 20:59:10 UTC (rev 12837)
@@ -7,6 +7,7 @@
 #include <assert.h>
 
 #include "XML.h"
+#include "rbuild.h"
 
 using std::string;
 using std::vector;
@@ -397,8 +398,8 @@
 	}
 	if ( required )
 	{
-		printf ( "syntax error: attribute '%s' required for <%s>\n",
-			attribute.c_str(), name.c_str() );
+		throw RequiredAttributeNotFoundException ( attribute,
+		                                           name );
 	}
 	return NULL;
 }
@@ -416,8 +417,8 @@
 	}
 	if ( required )
 	{
-		printf ( "syntax error: attribute '%s' required for <%s>\n",
-			attribute.c_str(), name.c_str() );
+		throw RequiredAttributeNotFoundException ( attribute,
+		                                           name );
 	}
 	return NULL;
 }
@@ -462,7 +463,7 @@
 			e->attributes.push_back ( new XMLAttribute ( "top_href", top_file ) );
 			XMLFile fInc;
 			if ( !fInc.open ( file ) )
-				printf ( "xi:include error, couldn't find file '%s'\n", file.c_str() );
+				throw FileNotFoundException ( file );
 			else
 			{
 				Path path2 ( path, att->value );

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-01-05 20:59:10 UTC (rev 12837)
@@ -6,6 +6,36 @@
 using std::string;
 using std::vector;
 
+#ifdef WIN32
+#define EXEPOSTFIX ".exe"
+#define SEP "\\"
+string FixSep ( const string& s )
+{
+	string s2(s);
+	char* p = strchr ( &s2[0], '/' );
+	while ( p )
+	{
+		*p++ = '\\';
+		p = strchr ( p, '/' );
+	}
+	return s2;
+}
+#else
+#define EXEPOSTFIX
+#define SEP "/"
+string FixSep ( const string& s )
+{
+	string s2(s);
+	char* p = strchr ( &s2[0], '\\' );
+	while ( p )
+	{
+		*p++ = '/';
+		p = strchr ( p, '\\' );
+	}
+	return s2;
+}
+#endif
+
 MingwBackend::MingwBackend ( Project& project )
 	: Backend ( project )
 {
@@ -13,18 +43,54 @@
 
 void MingwBackend::Process ()
 {
+	CreateMakefile ();
+	GenerateHeader ();
+	GenerateAllTarget ();
 	for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
 	{
 		Module& module = *ProjectNode.modules[i];
 		ProcessModule ( module );
 	}
+	CloseMakefile ();
 }
 
+void MingwBackend::CreateMakefile ()
+{
+	fMakefile = fopen ( ProjectNode.makefile.c_str (), "w" );
+	if ( !fMakefile )
+		throw AccessDeniedException ( ProjectNode.makefile );
+}
+
+void MingwBackend::CloseMakefile ()
+{
+	if (fMakefile)
+		fclose ( fMakefile );
+}
+
+void MingwBackend::GenerateHeader ()
+{
+	fprintf ( fMakefile, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
+}
+
+void MingwBackend::GenerateAllTarget ()
+{
+	fprintf ( fMakefile, "all: " );
+	for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
+	{
+		Module& module = *ProjectNode.modules[i];
+		fprintf ( fMakefile,
+		          " %s" SEP "%s" EXEPOSTFIX,
+		          FixSep(module.path).c_str (),
+		          module.name.c_str () );
+	}
+	fprintf ( fMakefile, "\n\n" );
+}
+
 void MingwBackend::ProcessModule ( Module& module )
 {
 	MingwModuleHandlerList moduleHandlers;
 	GetModuleHandlers ( moduleHandlers );
-	for (size_t i = 0; i < moduleHandlers.size(); i++)
+	for (size_t i = 0; i < moduleHandlers.size (); i++)
 	{
 		MingwModuleHandler& moduleHandler = *moduleHandlers[i];
 		if (moduleHandler.CanHandleModule ( module ) )

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-01-05 20:59:10 UTC (rev 12837)
@@ -25,6 +25,11 @@
 private:
 	void ProcessModule ( Module& module );
 	void GetModuleHandlers ( MingwModuleHandlerList& moduleHandlers );
+	void CreateMakefile ();
+	void CloseMakefile ();
+	void GenerateHeader ();
+	void GenerateAllTarget ();
+	FILE* fMakefile;
 };
 
 #endif /* MINGW_H */

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp	2005-01-05 20:59:10 UTC (rev 12837)
@@ -40,6 +40,13 @@
 }
 
 
+AccessDeniedException::AccessDeniedException(const string& filename)
+	: Exception ( "Access denied to file '%s'.", filename.c_str() )
+{
+	Filename = filename;
+}
+
+
 InvalidBuildFileException::InvalidBuildFileException(const char* message,
                                                      ...)
 {
@@ -48,3 +55,13 @@
 	SetMessage(message, args);
 	va_end(args);
 }
+
+
+RequiredAttributeNotFoundException::RequiredAttributeNotFoundException(const std::string& attributeName,
+                                                                       const std::string& elementName)
+	: InvalidBuildFileException ( "Required attribute '%s' not found on '%s'.",
+	                              attributeName.c_str (),
+	                              elementName.c_str ())
+{
+	
+}

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/exception.h	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/exception.h	2005-01-05 20:59:10 UTC (rev 12837)
@@ -25,6 +25,14 @@
 };
 
 
+class AccessDeniedException : public Exception
+{
+public:
+	AccessDeniedException(const std::string& filename);
+	std::string Filename;
+};
+
+
 class InvalidBuildFileException : public Exception
 {
 public:
@@ -32,4 +40,12 @@
 	                          ...);
 };
 
+
+class RequiredAttributeNotFoundException : public InvalidBuildFileException
+{
+public:
+	RequiredAttributeNotFoundException(const std::string& attributeName,
+	                                   const std::string& elementName);
+};
+
 #endif /* __EXCEPTION_H */

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/project.cpp	2005-01-05 20:59:10 UTC (rev 12837)
@@ -6,36 +6,6 @@
 using std::string;
 using std::vector;
 
-#ifdef WIN32
-#define EXEPOSTFIX ".exe"
-#define SEP "\\"
-string FixSep ( const string& s )
-{
-	string s2(s);
-	char* p = strchr ( &s2[0], '/' );
-	while ( p )
-	{
-		*p++ = '\\';
-		p = strchr ( p, '/' );
-	}
-	return s2;
-}
-#else
-#define EXEPOSTFIX
-#define SEP "/"
-string FixSep ( const string& s )
-{
-	string s2(s);
-	char* p = strchr ( &s2[0], '\\' );
-	while ( p )
-	{
-		*p++ = '/';
-		p = strchr ( p, '\\' );
-	}
-	return s2;
-}
-#endif
-
 Project::Project()
 {
 }
@@ -83,6 +53,9 @@
 			name = "Unnamed";
 		else
 			name = att->value;
+
+		att = e.GetAttribute ( "makefile", true );
+		makefile = att->value;
 	}
 	else if ( e.name == "module" )
 	{
@@ -105,32 +78,3 @@
 	for ( size_t i = 0; i < e.subElements.size (); i++ )
 		ProcessXML ( *e.subElements[i], subpath );
 }
-
-bool
-Project::GenerateOutput()
-{
-	const XMLAttribute* att;
-	size_t i;
-
-	att = head->GetAttribute ( "makefile", true );
-	if ( !att )
-		return false;
-	FILE* f = fopen ( att->value.c_str(), "w" );
-	if ( !f )
-	{
-		throw Exception ( "Unable to open '%s' for output", att->value.c_str() );
-		return false;
-	}
-	fprintf ( f, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
-
-	// generate module list:
-	fprintf ( f, "all: " );
-	for ( i = 0; i < modules.size(); i++ )
-	{
-		Module& m = *modules[i];
-		fprintf ( f, " %s" SEP "%s" EXEPOSTFIX, FixSep(m.path).c_str(), m.name.c_str() );
-	}
-	fprintf ( f, "\n\n" );
-
-	return true;
-}

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp	2005-01-05 20:59:10 UTC (rev 12837)
@@ -20,9 +20,10 @@
 	try
 	{
 		string projectFilename ( "ReactOS.xml" );
-		Project project = Project ( projectFilename );
+		Project project ( projectFilename );
 		Backend* backend = new MingwBackend ( project );
 		backend->Process ();
+		delete backend;
 		
 		// REM TODO FIXME actually do something with Project object...
 #if 0

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-05 20:59:10 UTC (rev 12837)
@@ -15,6 +15,7 @@
 {
 public:
 	std::string name;
+	std::string makefile;
 	std::vector<Module*> modules;
 
 	Project ();
@@ -22,13 +23,13 @@
 	~Project ();
 	void ProcessXML ( const XMLElement& e,
 	                  const std::string& path );
-	bool GenerateOutput();
 private:
 	void ReadXml ();
 	XMLFile xmlfile;
 	XMLElement* head;
 };
 
+
 class Module
 {
 public:
@@ -46,6 +47,7 @@
 	void ProcessXML ( const XMLElement& e, const std::string& path );
 };
 
+
 class File
 {
 public:

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/module.xml
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/module.xml	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/module.xml	2005-01-05 20:59:10 UTC (rev 12837)
@@ -1,4 +1,4 @@
-<project name="Project">
+<project name="Project" makefile="Makefile">
 	<directory name="dir1">
 		<module name="module1" type="buildtool">
 			<file>file1.c</file>

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/project.xml
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/project.xml	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/data/project.xml	2005-01-05 20:59:10 UTC (rev 12837)
@@ -1,4 +1,4 @@
-<project name="Project">
+<project name="Project" makefile="Makefile">
 	<directory name="dir1">
 		<module name="module1" type="buildtool">
 		</module>

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp	2005-01-05 20:59:10 UTC (rev 12837)
@@ -5,15 +5,15 @@
 void ModuleTest::Run()
 {
 	string projectFilename ( "tests/data/module.xml" );
-	Project* project = new Project( projectFilename );
-	ARE_EQUAL(2, project->modules.size());
+	Project project ( projectFilename );
+	ARE_EQUAL(2, project.modules.size());
 
-	Module& module1 = *project->modules[0];
+	Module& module1 = *project.modules[0];
 	ARE_EQUAL(2, module1.files.size());
 	ARE_EQUAL("./dir1/file1.c", module1.files[0]->name);
 	ARE_EQUAL("./dir1/file2.c", module1.files[1]->name);
 	
-	Module& module2 = *project->modules[1];
+	Module& module2 = *project.modules[1];
 	ARE_EQUAL(2, module2.files.size());
 	ARE_EQUAL("./dir2/file3.c", module2.files[0]->name);
 	ARE_EQUAL("./dir2/file4.c", module2.files[1]->name);

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/projecttest.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/projecttest.cpp	2005-01-05 19:47:10 UTC (rev 12836)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/projecttest.cpp	2005-01-05 20:59:10 UTC (rev 12837)
@@ -5,6 +5,6 @@
 void ProjectTest::Run()
 {
 	string projectFilename ( "tests/data/project.xml" );
-	Project* project = new Project( projectFilename );
-	ARE_EQUAL(2, project->modules.size());
+	Project project( projectFilename );
+	ARE_EQUAL(2, project.modules.size());
 }