{\r
}\r
\r
-XMLElement::XMLElement()\r
- : parentElement(NULL)\r
+XMLElement::XMLElement ( const string& location_ )\r
+ : location(location_),\r
+ parentElement(NULL)\r
{\r
}\r
\r
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
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
{\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
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
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
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
}\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
}\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
{\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
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
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
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
}\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
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
}\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
}\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
}\r
\r
string\r
-Module::GetDefaultModuleExtension ()\r
+Module::GetDefaultModuleExtension () const\r
{\r
switch (type)\r
{\r
}\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
{\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
\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
}\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
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
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
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
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