Have rbuild create the output directories
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/backend/mingw/modulehandler.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.h

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-04-02 16:18:09 UTC (rev 14448)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-04-02 16:46:08 UTC (rev 14449)
@@ -3,8 +3,15 @@
 
 #include "mingw.h"
 #include <assert.h>
+#include <dirent.h>
 #include "modulehandler.h"
 
+#ifdef WIN32
+#define MKDIR(s) mkdir(s)
+#else
+#define MKDIR(s) mkdir(s, 0755)
+#endif
+
 using std::string;
 using std::vector;
 using std::set;
@@ -20,7 +27,17 @@
 	directory_map subdirs;
 	Directory ( const string& name );
 	void Add ( const char* subdir );
-	void CreateRule ( FILE* f, const string& parent );
+	void GenerateTree ( const string& parent );
+private:
+	bool mkdir_p ( const char* path );
+	string ReplaceVariable ( string name,
+	                         string value,
+	                         string path );
+	string GetIntermediatePath ();
+	string GetOutputPath ();
+	void ResolveVariablesInPath ( char* buf,
+	                              string path );
+	bool CreateDirectory ( string path );
 };
 
 Directory::Directory ( const string& name_ )
@@ -30,6 +47,16 @@
 
 void Directory::Add ( const char* subdir )
 {
+	size_t i;
+	string s1 = string ( subdir );
+	if ( ( i = s1.find ( '$' ) ) != string::npos )
+	{
+		throw InvalidOperationException ( __FILE__,
+		                                  __LINE__,
+		                                  "No environment variables can be used here. Path was %s",
+		                                  subdir );
+	}
+
 	const char* p = strpbrk ( subdir, "/\\" );
 	if ( !p )
 		p = subdir + strlen(subdir);
@@ -40,27 +67,90 @@
 		subdirs[s]->Add ( p );
 }
 
+bool
+Directory::mkdir_p ( const char* path )
+{
+	DIR *directory;
+	directory = opendir ( path );
+	if ( directory != NULL )
+	{
+		closedir ( directory );
+		return false;
+	}
+
+	if ( MKDIR ( path ) != 0 )
+		throw AccessDeniedException ( string ( path ) );
+	return true;
+}
+
+bool
+Directory::CreateDirectory ( string path )
+{
+	size_t index = 0;
+	size_t nextIndex;
+	if ( isalpha ( path[0] ) && path[1] == ':' && path[2] == CSEP )
+	{
+		nextIndex = path.find ( CSEP, 3);
+	}
+	else
+		nextIndex = path.find ( CSEP );
+
+	bool directoryWasCreated = false;
+	while ( nextIndex != string::npos )
+	{
+		nextIndex = path.find ( CSEP, index + 1 );
+		directoryWasCreated = mkdir_p ( path.substr ( 0, nextIndex ).c_str () );
+		index = nextIndex;
+	}
+	return directoryWasCreated;
+}
+
+string
+Directory::ReplaceVariable ( string name,
+	                         string value,
+	                         string path )
+{
+	size_t i = path.find ( name );
+	if ( i != string::npos )
+		return path.replace ( i, name.length (), value );
+	else
+		return path;
+}
+
+string
+Directory::GetIntermediatePath ()
+{
+	return "obj-i386";
+}
+
+string
+Directory::GetOutputPath ()
+{
+	return "output-i386";
+}
+
 void
-Directory::CreateRule ( FILE* f, const string& parent )
+Directory::ResolveVariablesInPath ( char* buf,
+	                                string path )
 {
+	string s = ReplaceVariable ( "$(INTERMEDIATE)", GetIntermediatePath (), path );
+	s = ReplaceVariable ( "$(OUTPUT)", GetOutputPath (), s );
+	strcpy ( buf, s.c_str () );
+}
+
+void
+Directory::GenerateTree ( const string& parent )
+{
 	string path;
 
 	if ( parent.size() )
 	{
-		fprintf ( f,
-			"%s%c%s: %s\n",
-			parent.c_str (),
-			CSEP,
-			name.c_str (),
-			parent.c_str () );
-
-		fprintf ( f,
-			"\t$(ECHO_MKDIR)\n" );
-
-		fprintf ( f,
-			"\t${mkdir} $@\n" );
-
+		char buf[256];
+		
 		path = parent + SSEP + name;
+		ResolveVariablesInPath ( buf, path );
+		if ( CreateDirectory ( buf ) )
+			printf ( "Created %s\n", buf );
 	}
 	else
 		path = name;
@@ -69,7 +159,7 @@
 		i != subdirs.end();
 		++i )
 	{
-		i->second->CreateRule ( f, path );
+		i->second->GenerateTree ( path );
 	}
 }
 
@@ -164,7 +254,7 @@
 		delete v[i];
 	}
 
-	GenerateDirectoryTargets ();
+	GenerateDirectories ();
 	CheckAutomaticDependencies ();
 	CloseMakefile ();
 }
@@ -412,16 +502,10 @@
 }
 
 void
-MingwBackend::GenerateDirectoryTargets ()
+MingwBackend::GenerateDirectories ()
 {
-	// TODO FIXME - write new directory creation
-	for ( int i = 0; i < 2; i++ )
-	{
-		Directory& d = *(!i ? int_directories : out_directories);
-		if ( i ) fprintf ( fMakefile, "ifneq ($(INTERMEDIATE),$(OUTPUT))\n" );
-		d.CreateRule ( fMakefile, "" );
-		if ( i ) fprintf ( fMakefile, "endif\n" );
-	}
+	int_directories->GenerateTree ( "" );
+	out_directories->GenerateTree ( "" );
 }
 
 string

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-04-02 16:18:09 UTC (rev 14448)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-04-02 16:46:08 UTC (rev 14449)
@@ -22,7 +22,7 @@
 	void GenerateGlobalCFlagsAndProperties ( const char* op,
 	                                         IfableData& data ) const;
 	std::string GenerateProjectLFLAGS () const;
-	void GenerateDirectoryTargets ();
+	void GenerateDirectories ();
 	void GenerateGlobalVariables () const;
 	bool IncludeInAllTarget ( const Module& module ) const;
 	void GenerateAllTarget ( const std::vector<MingwModuleHandler*>& handlers ) const;

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-04-02 16:18:09 UTC (rev 14448)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-04-02 16:46:08 UTC (rev 14449)
@@ -100,11 +100,29 @@
 	use_pch = b;
 }
 
+/* static*/ string
+MingwModuleHandler::RemoveVariables ( string path)
+{
+	size_t i = path.find ( '$' );
+	if ( i != string::npos )
+	{
+		size_t j = path.find ( ')', i );
+		if ( j != string::npos )
+		{
+			if ( j + 2 < path.length () && path[j + 1] == CSEP )
+				return path.substr ( j + 2);
+			else
+				return path.substr ( j + 1);
+		}
+	}
+	return path;
+}
+	
 /*static*/ string
 MingwModuleHandler::PassThruCacheDirectory (
 	const string &file, bool out )
 {
-	string directory ( GetDirectory ( file ) );
+	string directory ( GetDirectory ( RemoveVariables ( file ) ) );
 	string generatedFilesDirectory = backend->AddDirectoryTarget ( directory, out );
 	if ( directory.find ( generatedFilesDirectory ) != string::npos )
 		/* This path already includes the generated files directory variable */
@@ -347,10 +365,9 @@
 	else
 		newExtension = ".o";
 	string obj_file = PassThruCacheDirectory (
-		FixupTargetFilename (
-			ReplaceExtension (
-				sourceFilename,
-				newExtension ) ),
+		FixupTargetFilename ( ReplaceExtension (
+			RemoveVariables ( sourceFilename ),
+			                  newExtension ) ),
 			false );
 	if ( pclean_files )
 	{

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-04-02 16:18:09 UTC (rev 14448)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-04-02 16:46:08 UTC (rev 14449)
@@ -146,6 +146,7 @@
 	void GetInvocationDependencies ( const Module& module, string_list& dependencies );
 	bool IsWineModule () const;
 	std::string GetDefinitionFilename () const;
+	static std::string RemoveVariables ( std::string path);
 public:
 	const Module& module;
 	string_list clean_files;

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp	2005-04-02 16:18:09 UTC (rev 14448)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/exception.cpp	2005-04-02 16:46:08 UTC (rev 14449)
@@ -75,7 +75,7 @@
 
 
 AccessDeniedException::AccessDeniedException ( const string& filename)
-	: Exception ( "Access denied to file '%s'.",
+	: Exception ( "Access denied to file or directory '%s'.",
 	             filename.c_str() )
 {
 	Filename = filename;

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/exception.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/exception.h	2005-04-02 16:18:09 UTC (rev 14448)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/exception.h	2005-04-02 16:46:08 UTC (rev 14449)
@@ -13,7 +13,7 @@
 protected:
 	Exception ();
 	void SetMessage ( const char* message,
-	                  va_list args);
+	                  va_list args );
 };