diff --git a/reactos/tools/rbuild/XML.cpp b/reactos/tools/rbuild/XML.cpp index 3f7cf7e0b5b..d2354851aba 100644 --- a/reactos/tools/rbuild/XML.cpp +++ b/reactos/tools/rbuild/XML.cpp @@ -7,6 +7,7 @@ #include #include "XML.h" +#include "rbuild.h" using std::string; using std::vector; @@ -397,8 +398,8 @@ XMLElement::GetAttribute ( const string& attribute, } 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 @@ XMLElement::GetAttribute ( const string& attribute, } 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 @@ XMLParse(XMLFile& f, 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 ); diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index df619398126..83d999e4325 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -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 @@ MingwBackend::MingwBackend ( Project& project ) 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 ) ) diff --git a/reactos/tools/rbuild/backend/mingw/mingw.h b/reactos/tools/rbuild/backend/mingw/mingw.h index d720620c799..ebdf7fbe086 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.h +++ b/reactos/tools/rbuild/backend/mingw/mingw.h @@ -25,6 +25,11 @@ public: private: void ProcessModule ( Module& module ); void GetModuleHandlers ( MingwModuleHandlerList& moduleHandlers ); + void CreateMakefile (); + void CloseMakefile (); + void GenerateHeader (); + void GenerateAllTarget (); + FILE* fMakefile; }; #endif /* MINGW_H */ diff --git a/reactos/tools/rbuild/exception.cpp b/reactos/tools/rbuild/exception.cpp index 8895f0dbca7..97f4a98ad9e 100644 --- a/reactos/tools/rbuild/exception.cpp +++ b/reactos/tools/rbuild/exception.cpp @@ -40,6 +40,13 @@ FileNotFoundException::FileNotFoundException(const string& filename) } +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 @@ InvalidBuildFileException::InvalidBuildFileException(const char* message, 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 ()) +{ + +} diff --git a/reactos/tools/rbuild/exception.h b/reactos/tools/rbuild/exception.h index bd6525db11f..4e26e1ffdaf 100644 --- a/reactos/tools/rbuild/exception.h +++ b/reactos/tools/rbuild/exception.h @@ -25,6 +25,14 @@ public: }; +class AccessDeniedException : public Exception +{ +public: + AccessDeniedException(const std::string& filename); + std::string Filename; +}; + + class InvalidBuildFileException : public Exception { public: @@ -32,4 +40,12 @@ public: ...); }; + +class RequiredAttributeNotFoundException : public InvalidBuildFileException +{ +public: + RequiredAttributeNotFoundException(const std::string& attributeName, + const std::string& elementName); +}; + #endif /* __EXCEPTION_H */ diff --git a/reactos/tools/rbuild/project.cpp b/reactos/tools/rbuild/project.cpp index eb33343d652..19b59390f12 100644 --- a/reactos/tools/rbuild/project.cpp +++ b/reactos/tools/rbuild/project.cpp @@ -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 @@ Project::ProcessXML ( const XMLElement& e, const string& path ) name = "Unnamed"; else name = att->value; + + att = e.GetAttribute ( "makefile", true ); + makefile = att->value; } else if ( e.name == "module" ) { @@ -105,32 +78,3 @@ Project::ProcessXML ( const XMLElement& e, const string& path ) 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; -} diff --git a/reactos/tools/rbuild/rbuild.cpp b/reactos/tools/rbuild/rbuild.cpp index 9e335b41d5a..2999e957849 100644 --- a/reactos/tools/rbuild/rbuild.cpp +++ b/reactos/tools/rbuild/rbuild.cpp @@ -20,9 +20,10 @@ main ( int argc, char** argv ) 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 diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index c78114a6a3e..ca061679b7e 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -15,6 +15,7 @@ class Project { public: std::string name; + std::string makefile; std::vector modules; Project (); @@ -22,13 +23,13 @@ public: ~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 @@ public: void ProcessXML ( const XMLElement& e, const std::string& path ); }; + class File { public: diff --git a/reactos/tools/rbuild/tests/data/module.xml b/reactos/tools/rbuild/tests/data/module.xml index 19eb169058a..7c43f1dfbe1 100644 --- a/reactos/tools/rbuild/tests/data/module.xml +++ b/reactos/tools/rbuild/tests/data/module.xml @@ -1,4 +1,4 @@ - + file1.c diff --git a/reactos/tools/rbuild/tests/data/project.xml b/reactos/tools/rbuild/tests/data/project.xml index f43930a4cc3..2413b601ae3 100644 --- a/reactos/tools/rbuild/tests/data/project.xml +++ b/reactos/tools/rbuild/tests/data/project.xml @@ -1,4 +1,4 @@ - + diff --git a/reactos/tools/rbuild/tests/moduletest.cpp b/reactos/tools/rbuild/tests/moduletest.cpp index ec7a5788c02..2ac7377b138 100644 --- a/reactos/tools/rbuild/tests/moduletest.cpp +++ b/reactos/tools/rbuild/tests/moduletest.cpp @@ -5,15 +5,15 @@ using std::string; 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); diff --git a/reactos/tools/rbuild/tests/projecttest.cpp b/reactos/tools/rbuild/tests/projecttest.cpp index 314304f8902..6b66b8764d6 100644 --- a/reactos/tools/rbuild/tests/projecttest.cpp +++ b/reactos/tools/rbuild/tests/projecttest.cpp @@ -5,6 +5,6 @@ using std::string; 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()); }