xml nodes now store the location they were parsed from; invalidbuildexceptions now...
authorRoyce Mitchell III <royce3@ev1.net>
Sat, 8 Jan 2005 03:37:32 +0000 (03:37 +0000)
committerRoyce Mitchell III <royce3@ev1.net>
Sat, 8 Jan 2005 03:37:32 +0000 (03:37 +0000)
svn path=/branches/xmlbuildsystem/; revision=12879

reactos/tools/rbuild/XML.cpp
reactos/tools/rbuild/XML.h
reactos/tools/rbuild/backend/mingw/modulehandler.cpp
reactos/tools/rbuild/define.cpp
reactos/tools/rbuild/exception.cpp
reactos/tools/rbuild/exception.h
reactos/tools/rbuild/include.cpp
reactos/tools/rbuild/module.cpp
reactos/tools/rbuild/project.cpp
reactos/tools/rbuild/rbuild.h

index df2aa72..833a033 100644 (file)
@@ -306,8 +306,9 @@ XMLAttribute::XMLAttribute(const string& name_,
 {\r
 }\r
 \r
-XMLElement::XMLElement()\r
-       : parentElement(NULL)\r
+XMLElement::XMLElement ( const string& location_ )\r
+       : location(location_),\r
+         parentElement(NULL)\r
 {\r
 }\r
 \r
@@ -476,7 +477,7 @@ XMLParse(XMLFile& f,
                        return NULL;\r
        }\r
 \r
-       XMLElement* e = new XMLElement;\r
+       XMLElement* e = new XMLElement ( f.Location() );\r
        bool bNeedEnd = e->Parse ( token, end_tag );\r
 \r
        if ( e->name == "xi:include" )\r
index d255456..ba55e26 100644 (file)
@@ -58,13 +58,14 @@ public:
 class XMLElement\r
 {\r
 public:\r
+       std::string location;\r
        std::string name;\r
        std::vector<XMLAttribute*> attributes;\r
        XMLElement* parentElement;\r
        std::vector<XMLElement*> subElements;\r
        std::string value;\r
 \r
-       XMLElement();\r
+       XMLElement ( const std::string& location_ );\r
        ~XMLElement();\r
        bool Parse(const std::string& token,\r
                   bool& end_tag);\r
index c7a999f..e3fadca 100644 (file)
@@ -48,7 +48,7 @@ MingwModuleHandler::GetImportLibraryDependencies ( const Module& module ) const
        {\r
                if ( dependencies.size () > 0 )\r
                        dependencies += " ";\r
-               Module* importedModule = module.project->LocateModule ( module.libraries[i]->name );\r
+               const Module* importedModule = module.project.LocateModule ( module.libraries[i]->name );\r
                assert ( importedModule != NULL );\r
                dependencies += importedModule->GetPath ().c_str ();\r
        }\r
@@ -117,7 +117,7 @@ MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector<Define*
 string\r
 MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const\r
 {\r
-       string parameters = GenerateGccDefineParametersFromVector ( module.project->defines );\r
+       string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );\r
        string s = GenerateGccDefineParametersFromVector ( module.defines );\r
        if (s.length () > 0)\r
        {\r
@@ -160,7 +160,7 @@ string
 MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const\r
 {\r
        string parameters = GenerateGccIncludeParametersFromVector ( ".",\r
-                                                                    module.project->includes );\r
+                                                                    module.project.includes );\r
        string s = GenerateGccIncludeParametersFromVector ( module.path,\r
                                                            module.includes );\r
        if (s.length () > 0)\r
index c443d44..2530249 100644 (file)
@@ -6,23 +6,23 @@
 using std::string;\r
 using std::vector;\r
 \r
-Define::Define ( Project* project,\r
+Define::Define ( const Project& project,\r
                  const XMLElement& defineNode )\r
        : project(project),\r
          module(NULL),\r
          node(defineNode)\r
 {\r
-       Initialize (defineNode);\r
+       Initialize();\r
 }\r
 \r
-Define::Define ( Project* project,\r
-                    Module* module,\r
+Define::Define ( const Project& project,\r
+                    const Module* module,\r
                  const XMLElement& defineNode )\r
        : project(project),\r
          module(module),\r
          node(defineNode)\r
 {\r
-       Initialize (defineNode);\r
+       Initialize();\r
 }\r
 \r
 Define::~Define ()\r
@@ -30,15 +30,15 @@ Define::~Define ()
 }\r
 \r
 void\r
-Define::Initialize ( const XMLElement& defineNode )\r
+Define::Initialize()\r
 {\r
-       const XMLAttribute* att = defineNode.GetAttribute ( "name", true );\r
+       const XMLAttribute* att = node.GetAttribute ( "name", true );\r
        assert(att);\r
        name = att->value;\r
-       value = defineNode.value;\r
+       value = node.value;\r
 }\r
 \r
 void\r
-Define::ProcessXML ( const XMLElement& e )\r
+Define::ProcessXML()\r
 {\r
 }\r
index d04014c..f3b3d5b 100644 (file)
@@ -58,14 +58,14 @@ AccessDeniedException::AccessDeniedException ( const string& filename)
 }\r
 \r
 \r
-InvalidBuildFileException::InvalidBuildFileException ( const char* message,\r
+InvalidBuildFileException::InvalidBuildFileException ( const string& location,\r
+                                                       const char* message,\r
                                                        ...)\r
 {\r
        va_list args;\r
        va_start ( args,\r
                   message );\r
-       SetMessage ( message,\r
-                   args );\r
+       SetLocationMessage ( location, message, args );\r
        va_end ( args );\r
 }\r
 \r
@@ -73,6 +73,13 @@ InvalidBuildFileException::InvalidBuildFileException ()
 {\r
 }\r
 \r
+void\r
+InvalidBuildFileException::SetLocationMessage ( const std::string& location,\r
+                                                const char* message,\r
+                                                va_list args )\r
+{\r
+       Message = location + ": " + ssvprintf ( message, args );\r
+}\r
 \r
 XMLSyntaxErrorException::XMLSyntaxErrorException ( const string& location,\r
                                                       const char* message,\r
@@ -81,7 +88,7 @@ XMLSyntaxErrorException::XMLSyntaxErrorException ( const string& location,
        va_list args;\r
        va_start ( args,\r
                  message );\r
-       Message = location + ": " + ssvprintf ( message, args );\r
+       SetLocationMessage ( location, message, args );\r
        va_end ( args );\r
 }\r
 \r
index 1653a0c..50a9510 100644 (file)
@@ -40,12 +40,15 @@ public:
        std::string Filename;\r
 };\r
 \r
-\r
 class InvalidBuildFileException : public Exception\r
 {\r
 public:\r
-       InvalidBuildFileException ( const char* message,\r
+       InvalidBuildFileException ( const std::string& location,\r
+                                   const char* message,\r
                                    ...);\r
+       void SetLocationMessage ( const std::string& location,\r
+                                 const char* message,\r
+                                 va_list args );\r
 protected:\r
        InvalidBuildFileException ();\r
 };\r
index 0141203..b8d7134 100644 (file)
@@ -6,21 +6,23 @@
 using std::string;\r
 using std::vector;\r
 \r
-Include::Include ( Project* project,\r
+Include::Include ( const Project& project_,\r
                    const XMLElement& includeNode )\r
-       : project(project),\r
+       : project(project_),\r
+         module(NULL),\r
          node(includeNode)\r
 {\r
-       Initialize ( includeNode );\r
+       Initialize();\r
 }\r
 \r
-Include::Include ( Project* project,\r
-                      Module* module,\r
+Include::Include ( const Project& project_,\r
+                      const Module* module_,\r
                       const XMLElement& includeNode )\r
-       : project(project),\r
+       : project(project_),\r
+         module(module_),\r
          node(includeNode)\r
 {\r
-       Initialize ( includeNode );\r
+       Initialize();\r
 }\r
 \r
 Include::~Include ()\r
@@ -28,12 +30,12 @@ Include::~Include ()
 }\r
 \r
 void\r
-Include::Initialize ( const XMLElement& includeNode )\r
+Include::Initialize()\r
 {\r
-       directory = FixSeparator ( includeNode.value );\r
+       directory = FixSeparator ( node.value );\r
 }\r
 \r
 void\r
-Include::ProcessXML ( const XMLElement& e )\r
+Include::ProcessXML()\r
 {\r
 }\r
index de767b3..0ca1a65 100644 (file)
@@ -21,13 +21,16 @@ FixSeparator ( const string& s )
        return s2;\r
 }\r
 \r
-Module::Module ( Project* project,\r
+Module::Module ( const Project& project,\r
                  const XMLElement& moduleNode,\r
                  const string& modulePath )\r
        : project(project),\r
          node(moduleNode)\r
 {\r
-       path = FixSeparator ( modulePath );\r
+       if ( node.name != "module" )\r
+               throw Exception ( "internal tool error: Module created with non-<module> node" );\r
+\r
+       path = FixSeparator ( modulePath );\r
 \r
        const XMLAttribute* att = moduleNode.GetAttribute ( "name", true );\r
        assert(att);\r
@@ -54,17 +57,30 @@ Module::~Module ()
 }\r
 \r
 void\r
-Module::ProcessXML ( const XMLElement& e,\r
-                     const string& path )\r
+Module::ProcessXML()\r
+{\r
+       size_t i;\r
+       for ( i = 0; i < node.subElements.size(); i++ )\r
+               ProcessXMLSubElement ( *node.subElements[i], path );\r
+       for ( i = 0; i < libraries.size(); i++ )\r
+               libraries[i]->ProcessXML();\r
+}\r
+\r
+void\r
+Module::ProcessXMLSubElement ( const XMLElement& e,\r
+                               const string& path )\r
 {\r
+       bool subs_invalid = false;\r
        string subpath ( path );\r
        if ( e.name == "file" && e.value.size () )\r
        {\r
                files.push_back ( new File ( FixSeparator ( path + CSEP + e.value ) ) );\r
+               subs_invalid = true;\r
        }\r
        else if ( e.name == "library" && e.value.size () )\r
        {\r
-               libraries.push_back ( new Library ( e.value ) );\r
+               libraries.push_back ( new Library ( e, *this, e.value ) );\r
+               subs_invalid = true;\r
        }\r
        else if ( e.name == "directory" )\r
        {\r
@@ -74,18 +90,21 @@ Module::ProcessXML ( const XMLElement& e,
        }\r
        else if ( e.name == "include" )\r
        {\r
-               Include* include = new Include ( project, this, e );\r
-               includes.push_back ( include );\r
-               include->ProcessXML ( e );\r
+               includes.push_back ( new Include ( project, this, e ) );\r
+               subs_invalid = true;\r
        }\r
        else if ( e.name == "define" )\r
        {\r
-               Define* define = new Define ( project, this, e );\r
-               defines.push_back ( define );\r
-               define->ProcessXML ( e );\r
+               defines.push_back ( new Define ( project, this, e ) );\r
+               subs_invalid = true;\r
        }\r
+       if ( subs_invalid && e.subElements.size() )\r
+               throw InvalidBuildFileException (\r
+                       e.location,\r
+                       "<%s> cannot have sub-elements",\r
+                       e.name.c_str() );\r
        for ( size_t i = 0; i < e.subElements.size (); i++ )\r
-               ProcessXML ( *e.subElements[i], subpath );\r
+               ProcessXMLSubElement ( *e.subElements[i], subpath );\r
 }\r
 \r
 ModuleType\r
@@ -102,7 +121,7 @@ Module::GetModuleType ( const XMLAttribute& attribute )
 }\r
 \r
 string\r
-Module::GetDefaultModuleExtension ()\r
+Module::GetDefaultModuleExtension () const\r
 {\r
        switch (type)\r
        {\r
@@ -130,7 +149,27 @@ File::File ( const string& _name )
 }\r
 \r
 \r
-Library::Library ( const string& _name )\r
-       : name(_name)\r
+Library::Library ( const XMLElement& _node,\r
+                   const Module& _module,\r
+                   const string& _name )\r
+       : node(_node),\r
+         module(_module),\r
+         name(_name)\r
+{\r
+       if ( module.name == name )\r
+               throw InvalidBuildFileException (\r
+                       node.location,\r
+                       "module '%s' cannot link against itself",\r
+                       name.c_str() );\r
+}\r
+\r
+void\r
+Library::ProcessXML()\r
 {\r
+       if ( !module.project.LocateModule ( name ) )\r
+               throw InvalidBuildFileException (\r
+                       node.location,\r
+                       "module '%s' trying to link against non-existant module '%s'",\r
+                       module.name.c_str(),\r
+                       name.c_str() );\r
 }\r
index fcd3f5f..ec5a692 100644 (file)
@@ -22,7 +22,7 @@ Project::~Project ()
 {\r
        for ( size_t i = 0; i < modules.size (); i++ )\r
                delete modules[i];\r
-       delete head;\r
+       delete node;\r
 }\r
 \r
 void\r
@@ -32,37 +32,53 @@ Project::ReadXml ()
 \r
        do\r
        {\r
-               head = XMLParse ( xmlfile, path );\r
-               if ( !head )\r
-                       throw InvalidBuildFileException ( "Document contains no 'project' tag." );\r
-       } while ( head->name != "project" );\r
+               node = XMLParse ( xmlfile, path );\r
+               if ( !node )\r
+                       throw InvalidBuildFileException (\r
+                               node->location,\r
+                               "Document contains no 'project' tag." );\r
+       } while ( node->name != "project" );\r
 \r
-       this->ProcessXML ( *head, "." );\r
+       this->ProcessXML ( "." );\r
 }\r
 \r
 void\r
-Project::ProcessXML ( const XMLElement& e, const string& path )\r
+Project::ProcessXML ( const string& path )\r
 {\r
        const XMLAttribute *att;\r
-       string subpath(path);\r
-       if ( e.name == "project" )\r
-       {\r
-               att = e.GetAttribute ( "name", false );\r
-               if ( !att )\r
-                       name = "Unnamed";\r
-               else\r
-                       name = att->value;\r
+       if ( node->name != "project" )\r
+               throw Exception ( "internal tool error: Project::ProcessXML() called with non-<project> node" );\r
 \r
-               att = e.GetAttribute ( "makefile", true );\r
-               assert(att);\r
-               makefile = att->value;\r
-       }\r
-       else if ( e.name == "module" )\r
+       att = node->GetAttribute ( "name", false );\r
+       if ( !att )\r
+               name = "Unnamed";\r
+       else\r
+               name = att->value;\r
+\r
+       att = node->GetAttribute ( "makefile", true );\r
+       assert(att);\r
+       makefile = att->value;\r
+\r
+       size_t i;\r
+       for ( i = 0; i < node->subElements.size(); i++ )\r
+               ProcessXMLSubElement ( *node->subElements[i], path );\r
+       for ( i = 0; i < modules.size(); i++ )\r
+               modules[i]->ProcessXML();\r
+       for ( i = 0; i < includes.size(); i++ )\r
+               includes[i]->ProcessXML();\r
+       for ( i = 0; i < defines.size(); i++ )\r
+               defines[i]->ProcessXML();\r
+}\r
+\r
+void\r
+Project::ProcessXMLSubElement ( const XMLElement& e, const string& path )\r
+{\r
+       bool subs_invalid = false;\r
+       string subpath(path);\r
+       if ( e.name == "module" )\r
        {\r
-               Module* module = new Module ( this, e, path );\r
-               modules.push_back ( module );\r
-               module->ProcessXML ( e, path );\r
-               return;\r
+               modules.push_back ( new Module ( *this, e, path ) );\r
+               return; // defer processing until later\r
        }\r
        else if ( e.name == "directory" )\r
        {\r
@@ -72,22 +88,37 @@ Project::ProcessXML ( const XMLElement& e, const string& path )
        }\r
        else if ( e.name == "include" )\r
        {\r
-               Include* include = new Include ( this, e );\r
-               includes.push_back ( include );\r
-               include->ProcessXML ( e );\r
+               includes.push_back ( new Include ( *this, e ) );\r
+               subs_invalid = true;\r
        }\r
        else if ( e.name == "define" )\r
        {\r
-               Define* define = new Define ( this, e );\r
-               defines.push_back ( define );\r
-               define->ProcessXML ( e );\r
+               defines.push_back ( new Define ( *this, e ) );\r
+               subs_invalid = true;\r
        }\r
+       if ( subs_invalid && e.subElements.size() )\r
+               throw InvalidBuildFileException (\r
+                       e.location,\r
+                       "<%s> cannot have sub-elements",\r
+                       e.name.c_str() );\r
        for ( size_t i = 0; i < e.subElements.size (); i++ )\r
-               ProcessXML ( *e.subElements[i], subpath );\r
+               ProcessXMLSubElement ( *e.subElements[i], subpath );\r
 }\r
 \r
 Module*\r
-Project::LocateModule ( string name )\r
+Project::LocateModule ( const string& name )\r
+{\r
+       for ( size_t i = 0; i < modules.size (); i++ )\r
+       {\r
+               if (modules[i]->name == name)\r
+                       return modules[i];\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+const Module*\r
+Project::LocateModule ( const string& name ) const\r
 {\r
        for ( size_t i = 0; i < modules.size (); i++ )\r
        {\r
index 22285b0..7844a1e 100644 (file)
@@ -40,13 +40,15 @@ public:
        Project ();\r
        Project ( const std::string& filename );\r
        ~Project ();\r
-       void ProcessXML ( const XMLElement& e,\r
-                         const std::string& path );\r
-       Module* LocateModule ( std::string name );\r
+       void ProcessXML ( const std::string& path );\r
+       Module* LocateModule ( const std::string& name );\r
+       const Module* LocateModule ( const std::string& name ) const;\r
 private:\r
        void ReadXml ();\r
        XMLFile xmlfile;\r
-       XMLElement* head;\r
+       XMLElement* node;\r
+       void ProcessXMLSubElement ( const XMLElement& e,\r
+                                   const std::string& path );\r
 };\r
 \r
 \r
@@ -61,7 +63,7 @@ enum ModuleType
 class Module\r
 {\r
 public:\r
-       Project* project;\r
+       const Project& project;\r
        const XMLElement& node;\r
        std::string name;\r
        std::string extension;\r
@@ -72,56 +74,58 @@ public:
        std::vector<Include*> includes;\r
        std::vector<Define*> defines;\r
 \r
-       Module ( Project* project,\r
+       Module ( const Project& project,\r
                 const XMLElement& moduleNode,\r
                 const std::string& modulePath );\r
        ~Module ();\r
        ModuleType GetModuleType (const XMLAttribute& attribute );\r
        std::string GetPath () const;\r
-       void ProcessXML ( const XMLElement& e, const std::string& path );\r
+       void ProcessXML();\r
 private:\r
-       std::string GetDefaultModuleExtension ();\r
+       std::string GetDefaultModuleExtension () const;\r
+       void ProcessXMLSubElement ( const XMLElement& e,\r
+                                   const std::string& path );\r
 };\r
 \r
 \r
 class Include\r
 {\r
 public:\r
-       Project* project;\r
-       Module* module;\r
+       const Project& project;\r
+       const Module* module;\r
        const XMLElement& node;\r
        std::string directory;\r
 \r
-       Include ( Project* project,\r
+       Include ( const Project& project,\r
                  const XMLElement& includeNode );\r
-       Include ( Project* project,\r
-                 Module* module,\r
+       Include ( const Project& project,\r
+                 const Module* module,\r
                  const XMLElement& includeNode );\r
        ~Include ();\r
-       void ProcessXML ( const XMLElement& e );\r
+       void ProcessXML();\r
 private:\r
-       void Initialize ( const XMLElement& includeNode );\r
+       void Initialize();\r
 };\r
 \r
 \r
 class Define\r
 {\r
 public:\r
-       Project* project;\r
-       Module* module;\r
+       const Project& project;\r
+       const Module* module;\r
        const XMLElement& node;\r
        std::string name;\r
        std::string value;\r
 \r
-       Define ( Project* project,\r
+       Define ( const Project& project,\r
                 const XMLElement& defineNode );\r
-       Define ( Project* project,\r
-                Module* module,\r
+       Define ( const Project& project,\r
+                const Module* module,\r
                 const XMLElement& defineNode );\r
        ~Define();\r
-       void ProcessXML ( const XMLElement& e );\r
+       void ProcessXML();\r
 private:\r
-       void Initialize ( const XMLElement& defineNode );\r
+       void Initialize();\r
 };\r
 \r
 \r
@@ -137,9 +141,15 @@ public:
 class Library\r
 {\r
 public:\r
+       const XMLElement& node;\r
+       const Module& module;\r
        std::string name;\r
 \r
-       Library ( const std::string& _name );\r
+       Library ( const XMLElement& _node,\r
+                 const Module& _module,\r
+                 const std::string& _name );\r
+\r
+       void ProcessXML();\r
 };\r
 \r
 extern std::string\r