mirror of
https://github.com/reactos/reactos.git
synced 2025-08-09 03:03:14 +00:00
xml nodes now store the location they were parsed from; invalidbuildexceptions now required a location of the error; don't allow modules to process xml until all modules are created; don't allow libraries, defines, includes, etc to process xml until all modules have processed; don't allow module to link against itself or a non-existant module; don't allow library to specify non-existant module;
svn path=/branches/xmlbuildsystem/; revision=12879
This commit is contained in:
parent
de7c566b05
commit
774f167e5e
10 changed files with 196 additions and 102 deletions
|
@ -306,8 +306,9 @@ XMLAttribute::XMLAttribute(const string& name_,
|
|||
{
|
||||
}
|
||||
|
||||
XMLElement::XMLElement()
|
||||
: parentElement(NULL)
|
||||
XMLElement::XMLElement ( const string& location_ )
|
||||
: location(location_),
|
||||
parentElement(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -476,7 +477,7 @@ XMLParse(XMLFile& f,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
XMLElement* e = new XMLElement;
|
||||
XMLElement* e = new XMLElement ( f.Location() );
|
||||
bool bNeedEnd = e->Parse ( token, end_tag );
|
||||
|
||||
if ( e->name == "xi:include" )
|
||||
|
|
|
@ -58,13 +58,14 @@ public:
|
|||
class XMLElement
|
||||
{
|
||||
public:
|
||||
std::string location;
|
||||
std::string name;
|
||||
std::vector<XMLAttribute*> attributes;
|
||||
XMLElement* parentElement;
|
||||
std::vector<XMLElement*> subElements;
|
||||
std::string value;
|
||||
|
||||
XMLElement();
|
||||
XMLElement ( const std::string& location_ );
|
||||
~XMLElement();
|
||||
bool Parse(const std::string& token,
|
||||
bool& end_tag);
|
||||
|
|
|
@ -48,7 +48,7 @@ MingwModuleHandler::GetImportLibraryDependencies ( const Module& module ) const
|
|||
{
|
||||
if ( dependencies.size () > 0 )
|
||||
dependencies += " ";
|
||||
Module* importedModule = module.project->LocateModule ( module.libraries[i]->name );
|
||||
const Module* importedModule = module.project.LocateModule ( module.libraries[i]->name );
|
||||
assert ( importedModule != NULL );
|
||||
dependencies += importedModule->GetPath ().c_str ();
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector<Define*
|
|||
string
|
||||
MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const
|
||||
{
|
||||
string parameters = GenerateGccDefineParametersFromVector ( module.project->defines );
|
||||
string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );
|
||||
string s = GenerateGccDefineParametersFromVector ( module.defines );
|
||||
if (s.length () > 0)
|
||||
{
|
||||
|
@ -160,7 +160,7 @@ string
|
|||
MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const
|
||||
{
|
||||
string parameters = GenerateGccIncludeParametersFromVector ( ".",
|
||||
module.project->includes );
|
||||
module.project.includes );
|
||||
string s = GenerateGccIncludeParametersFromVector ( module.path,
|
||||
module.includes );
|
||||
if (s.length () > 0)
|
||||
|
|
|
@ -6,23 +6,23 @@
|
|||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
Define::Define ( Project* project,
|
||||
Define::Define ( const Project& project,
|
||||
const XMLElement& defineNode )
|
||||
: project(project),
|
||||
module(NULL),
|
||||
node(defineNode)
|
||||
{
|
||||
Initialize (defineNode);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Define::Define ( Project* project,
|
||||
Module* module,
|
||||
Define::Define ( const Project& project,
|
||||
const Module* module,
|
||||
const XMLElement& defineNode )
|
||||
: project(project),
|
||||
module(module),
|
||||
node(defineNode)
|
||||
{
|
||||
Initialize (defineNode);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Define::~Define ()
|
||||
|
@ -30,15 +30,15 @@ Define::~Define ()
|
|||
}
|
||||
|
||||
void
|
||||
Define::Initialize ( const XMLElement& defineNode )
|
||||
Define::Initialize()
|
||||
{
|
||||
const XMLAttribute* att = defineNode.GetAttribute ( "name", true );
|
||||
const XMLAttribute* att = node.GetAttribute ( "name", true );
|
||||
assert(att);
|
||||
name = att->value;
|
||||
value = defineNode.value;
|
||||
value = node.value;
|
||||
}
|
||||
|
||||
void
|
||||
Define::ProcessXML ( const XMLElement& e )
|
||||
Define::ProcessXML()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -58,14 +58,14 @@ AccessDeniedException::AccessDeniedException ( const string& filename)
|
|||
}
|
||||
|
||||
|
||||
InvalidBuildFileException::InvalidBuildFileException ( const char* message,
|
||||
InvalidBuildFileException::InvalidBuildFileException ( const string& location,
|
||||
const char* message,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
va_start ( args,
|
||||
message );
|
||||
SetMessage ( message,
|
||||
args );
|
||||
SetLocationMessage ( location, message, args );
|
||||
va_end ( args );
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,13 @@ InvalidBuildFileException::InvalidBuildFileException ()
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
InvalidBuildFileException::SetLocationMessage ( const std::string& location,
|
||||
const char* message,
|
||||
va_list args )
|
||||
{
|
||||
Message = location + ": " + ssvprintf ( message, args );
|
||||
}
|
||||
|
||||
XMLSyntaxErrorException::XMLSyntaxErrorException ( const string& location,
|
||||
const char* message,
|
||||
|
@ -81,7 +88,7 @@ XMLSyntaxErrorException::XMLSyntaxErrorException ( const string& location,
|
|||
va_list args;
|
||||
va_start ( args,
|
||||
message );
|
||||
Message = location + ": " + ssvprintf ( message, args );
|
||||
SetLocationMessage ( location, message, args );
|
||||
va_end ( args );
|
||||
}
|
||||
|
||||
|
|
|
@ -40,12 +40,15 @@ public:
|
|||
std::string Filename;
|
||||
};
|
||||
|
||||
|
||||
class InvalidBuildFileException : public Exception
|
||||
{
|
||||
public:
|
||||
InvalidBuildFileException ( const char* message,
|
||||
InvalidBuildFileException ( const std::string& location,
|
||||
const char* message,
|
||||
...);
|
||||
void SetLocationMessage ( const std::string& location,
|
||||
const char* message,
|
||||
va_list args );
|
||||
protected:
|
||||
InvalidBuildFileException ();
|
||||
};
|
||||
|
|
|
@ -6,21 +6,23 @@
|
|||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
Include::Include ( Project* project,
|
||||
Include::Include ( const Project& project_,
|
||||
const XMLElement& includeNode )
|
||||
: project(project),
|
||||
: project(project_),
|
||||
module(NULL),
|
||||
node(includeNode)
|
||||
{
|
||||
Initialize ( includeNode );
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Include::Include ( Project* project,
|
||||
Module* module,
|
||||
Include::Include ( const Project& project_,
|
||||
const Module* module_,
|
||||
const XMLElement& includeNode )
|
||||
: project(project),
|
||||
: project(project_),
|
||||
module(module_),
|
||||
node(includeNode)
|
||||
{
|
||||
Initialize ( includeNode );
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Include::~Include ()
|
||||
|
@ -28,12 +30,12 @@ Include::~Include ()
|
|||
}
|
||||
|
||||
void
|
||||
Include::Initialize ( const XMLElement& includeNode )
|
||||
Include::Initialize()
|
||||
{
|
||||
directory = FixSeparator ( includeNode.value );
|
||||
directory = FixSeparator ( node.value );
|
||||
}
|
||||
|
||||
void
|
||||
Include::ProcessXML ( const XMLElement& e )
|
||||
Include::ProcessXML()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -21,13 +21,16 @@ FixSeparator ( const string& s )
|
|||
return s2;
|
||||
}
|
||||
|
||||
Module::Module ( Project* project,
|
||||
Module::Module ( const Project& project,
|
||||
const XMLElement& moduleNode,
|
||||
const string& modulePath )
|
||||
: project(project),
|
||||
node(moduleNode)
|
||||
{
|
||||
path = FixSeparator ( modulePath );
|
||||
if ( node.name != "module" )
|
||||
throw Exception ( "internal tool error: Module created with non-<module> node" );
|
||||
|
||||
path = FixSeparator ( modulePath );
|
||||
|
||||
const XMLAttribute* att = moduleNode.GetAttribute ( "name", true );
|
||||
assert(att);
|
||||
|
@ -54,17 +57,30 @@ Module::~Module ()
|
|||
}
|
||||
|
||||
void
|
||||
Module::ProcessXML ( const XMLElement& e,
|
||||
const string& path )
|
||||
Module::ProcessXML()
|
||||
{
|
||||
size_t i;
|
||||
for ( i = 0; i < node.subElements.size(); i++ )
|
||||
ProcessXMLSubElement ( *node.subElements[i], path );
|
||||
for ( i = 0; i < libraries.size(); i++ )
|
||||
libraries[i]->ProcessXML();
|
||||
}
|
||||
|
||||
void
|
||||
Module::ProcessXMLSubElement ( const XMLElement& e,
|
||||
const string& path )
|
||||
{
|
||||
bool subs_invalid = false;
|
||||
string subpath ( path );
|
||||
if ( e.name == "file" && e.value.size () )
|
||||
{
|
||||
files.push_back ( new File ( FixSeparator ( path + CSEP + e.value ) ) );
|
||||
subs_invalid = true;
|
||||
}
|
||||
else if ( e.name == "library" && e.value.size () )
|
||||
{
|
||||
libraries.push_back ( new Library ( e.value ) );
|
||||
libraries.push_back ( new Library ( e, *this, e.value ) );
|
||||
subs_invalid = true;
|
||||
}
|
||||
else if ( e.name == "directory" )
|
||||
{
|
||||
|
@ -74,18 +90,21 @@ Module::ProcessXML ( const XMLElement& e,
|
|||
}
|
||||
else if ( e.name == "include" )
|
||||
{
|
||||
Include* include = new Include ( project, this, e );
|
||||
includes.push_back ( include );
|
||||
include->ProcessXML ( e );
|
||||
includes.push_back ( new Include ( project, this, e ) );
|
||||
subs_invalid = true;
|
||||
}
|
||||
else if ( e.name == "define" )
|
||||
{
|
||||
Define* define = new Define ( project, this, e );
|
||||
defines.push_back ( define );
|
||||
define->ProcessXML ( e );
|
||||
defines.push_back ( new Define ( project, this, e ) );
|
||||
subs_invalid = true;
|
||||
}
|
||||
if ( subs_invalid && e.subElements.size() )
|
||||
throw InvalidBuildFileException (
|
||||
e.location,
|
||||
"<%s> cannot have sub-elements",
|
||||
e.name.c_str() );
|
||||
for ( size_t i = 0; i < e.subElements.size (); i++ )
|
||||
ProcessXML ( *e.subElements[i], subpath );
|
||||
ProcessXMLSubElement ( *e.subElements[i], subpath );
|
||||
}
|
||||
|
||||
ModuleType
|
||||
|
@ -102,7 +121,7 @@ Module::GetModuleType ( const XMLAttribute& attribute )
|
|||
}
|
||||
|
||||
string
|
||||
Module::GetDefaultModuleExtension ()
|
||||
Module::GetDefaultModuleExtension () const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
@ -130,7 +149,27 @@ File::File ( const string& _name )
|
|||
}
|
||||
|
||||
|
||||
Library::Library ( const string& _name )
|
||||
: name(_name)
|
||||
Library::Library ( const XMLElement& _node,
|
||||
const Module& _module,
|
||||
const string& _name )
|
||||
: node(_node),
|
||||
module(_module),
|
||||
name(_name)
|
||||
{
|
||||
if ( module.name == name )
|
||||
throw InvalidBuildFileException (
|
||||
node.location,
|
||||
"module '%s' cannot link against itself",
|
||||
name.c_str() );
|
||||
}
|
||||
|
||||
void
|
||||
Library::ProcessXML()
|
||||
{
|
||||
if ( !module.project.LocateModule ( name ) )
|
||||
throw InvalidBuildFileException (
|
||||
node.location,
|
||||
"module '%s' trying to link against non-existant module '%s'",
|
||||
module.name.c_str(),
|
||||
name.c_str() );
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ Project::~Project ()
|
|||
{
|
||||
for ( size_t i = 0; i < modules.size (); i++ )
|
||||
delete modules[i];
|
||||
delete head;
|
||||
delete node;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -32,37 +32,53 @@ Project::ReadXml ()
|
|||
|
||||
do
|
||||
{
|
||||
head = XMLParse ( xmlfile, path );
|
||||
if ( !head )
|
||||
throw InvalidBuildFileException ( "Document contains no 'project' tag." );
|
||||
} while ( head->name != "project" );
|
||||
node = XMLParse ( xmlfile, path );
|
||||
if ( !node )
|
||||
throw InvalidBuildFileException (
|
||||
node->location,
|
||||
"Document contains no 'project' tag." );
|
||||
} while ( node->name != "project" );
|
||||
|
||||
this->ProcessXML ( *head, "." );
|
||||
this->ProcessXML ( "." );
|
||||
}
|
||||
|
||||
void
|
||||
Project::ProcessXML ( const XMLElement& e, const string& path )
|
||||
Project::ProcessXML ( const string& path )
|
||||
{
|
||||
const XMLAttribute *att;
|
||||
string subpath(path);
|
||||
if ( e.name == "project" )
|
||||
{
|
||||
att = e.GetAttribute ( "name", false );
|
||||
if ( !att )
|
||||
name = "Unnamed";
|
||||
else
|
||||
name = att->value;
|
||||
if ( node->name != "project" )
|
||||
throw Exception ( "internal tool error: Project::ProcessXML() called with non-<project> node" );
|
||||
|
||||
att = e.GetAttribute ( "makefile", true );
|
||||
assert(att);
|
||||
makefile = att->value;
|
||||
}
|
||||
else if ( e.name == "module" )
|
||||
att = node->GetAttribute ( "name", false );
|
||||
if ( !att )
|
||||
name = "Unnamed";
|
||||
else
|
||||
name = att->value;
|
||||
|
||||
att = node->GetAttribute ( "makefile", true );
|
||||
assert(att);
|
||||
makefile = att->value;
|
||||
|
||||
size_t i;
|
||||
for ( i = 0; i < node->subElements.size(); i++ )
|
||||
ProcessXMLSubElement ( *node->subElements[i], path );
|
||||
for ( i = 0; i < modules.size(); i++ )
|
||||
modules[i]->ProcessXML();
|
||||
for ( i = 0; i < includes.size(); i++ )
|
||||
includes[i]->ProcessXML();
|
||||
for ( i = 0; i < defines.size(); i++ )
|
||||
defines[i]->ProcessXML();
|
||||
}
|
||||
|
||||
void
|
||||
Project::ProcessXMLSubElement ( const XMLElement& e, const string& path )
|
||||
{
|
||||
bool subs_invalid = false;
|
||||
string subpath(path);
|
||||
if ( e.name == "module" )
|
||||
{
|
||||
Module* module = new Module ( this, e, path );
|
||||
modules.push_back ( module );
|
||||
module->ProcessXML ( e, path );
|
||||
return;
|
||||
modules.push_back ( new Module ( *this, e, path ) );
|
||||
return; // defer processing until later
|
||||
}
|
||||
else if ( e.name == "directory" )
|
||||
{
|
||||
|
@ -72,22 +88,37 @@ Project::ProcessXML ( const XMLElement& e, const string& path )
|
|||
}
|
||||
else if ( e.name == "include" )
|
||||
{
|
||||
Include* include = new Include ( this, e );
|
||||
includes.push_back ( include );
|
||||
include->ProcessXML ( e );
|
||||
includes.push_back ( new Include ( *this, e ) );
|
||||
subs_invalid = true;
|
||||
}
|
||||
else if ( e.name == "define" )
|
||||
{
|
||||
Define* define = new Define ( this, e );
|
||||
defines.push_back ( define );
|
||||
define->ProcessXML ( e );
|
||||
defines.push_back ( new Define ( *this, e ) );
|
||||
subs_invalid = true;
|
||||
}
|
||||
if ( subs_invalid && e.subElements.size() )
|
||||
throw InvalidBuildFileException (
|
||||
e.location,
|
||||
"<%s> cannot have sub-elements",
|
||||
e.name.c_str() );
|
||||
for ( size_t i = 0; i < e.subElements.size (); i++ )
|
||||
ProcessXML ( *e.subElements[i], subpath );
|
||||
ProcessXMLSubElement ( *e.subElements[i], subpath );
|
||||
}
|
||||
|
||||
Module*
|
||||
Project::LocateModule ( string name )
|
||||
Project::LocateModule ( const string& name )
|
||||
{
|
||||
for ( size_t i = 0; i < modules.size (); i++ )
|
||||
{
|
||||
if (modules[i]->name == name)
|
||||
return modules[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Module*
|
||||
Project::LocateModule ( const string& name ) const
|
||||
{
|
||||
for ( size_t i = 0; i < modules.size (); i++ )
|
||||
{
|
||||
|
|
|
@ -40,13 +40,15 @@ public:
|
|||
Project ();
|
||||
Project ( const std::string& filename );
|
||||
~Project ();
|
||||
void ProcessXML ( const XMLElement& e,
|
||||
const std::string& path );
|
||||
Module* LocateModule ( std::string name );
|
||||
void ProcessXML ( const std::string& path );
|
||||
Module* LocateModule ( const std::string& name );
|
||||
const Module* LocateModule ( const std::string& name ) const;
|
||||
private:
|
||||
void ReadXml ();
|
||||
XMLFile xmlfile;
|
||||
XMLElement* head;
|
||||
XMLElement* node;
|
||||
void ProcessXMLSubElement ( const XMLElement& e,
|
||||
const std::string& path );
|
||||
};
|
||||
|
||||
|
||||
|
@ -61,7 +63,7 @@ enum ModuleType
|
|||
class Module
|
||||
{
|
||||
public:
|
||||
Project* project;
|
||||
const Project& project;
|
||||
const XMLElement& node;
|
||||
std::string name;
|
||||
std::string extension;
|
||||
|
@ -72,56 +74,58 @@ public:
|
|||
std::vector<Include*> includes;
|
||||
std::vector<Define*> defines;
|
||||
|
||||
Module ( Project* project,
|
||||
Module ( const Project& project,
|
||||
const XMLElement& moduleNode,
|
||||
const std::string& modulePath );
|
||||
~Module ();
|
||||
ModuleType GetModuleType (const XMLAttribute& attribute );
|
||||
std::string GetPath () const;
|
||||
void ProcessXML ( const XMLElement& e, const std::string& path );
|
||||
void ProcessXML();
|
||||
private:
|
||||
std::string GetDefaultModuleExtension ();
|
||||
std::string GetDefaultModuleExtension () const;
|
||||
void ProcessXMLSubElement ( const XMLElement& e,
|
||||
const std::string& path );
|
||||
};
|
||||
|
||||
|
||||
class Include
|
||||
{
|
||||
public:
|
||||
Project* project;
|
||||
Module* module;
|
||||
const Project& project;
|
||||
const Module* module;
|
||||
const XMLElement& node;
|
||||
std::string directory;
|
||||
|
||||
Include ( Project* project,
|
||||
Include ( const Project& project,
|
||||
const XMLElement& includeNode );
|
||||
Include ( Project* project,
|
||||
Module* module,
|
||||
Include ( const Project& project,
|
||||
const Module* module,
|
||||
const XMLElement& includeNode );
|
||||
~Include ();
|
||||
void ProcessXML ( const XMLElement& e );
|
||||
void ProcessXML();
|
||||
private:
|
||||
void Initialize ( const XMLElement& includeNode );
|
||||
void Initialize();
|
||||
};
|
||||
|
||||
|
||||
class Define
|
||||
{
|
||||
public:
|
||||
Project* project;
|
||||
Module* module;
|
||||
const Project& project;
|
||||
const Module* module;
|
||||
const XMLElement& node;
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
||||
Define ( Project* project,
|
||||
Define ( const Project& project,
|
||||
const XMLElement& defineNode );
|
||||
Define ( Project* project,
|
||||
Module* module,
|
||||
Define ( const Project& project,
|
||||
const Module* module,
|
||||
const XMLElement& defineNode );
|
||||
~Define();
|
||||
void ProcessXML ( const XMLElement& e );
|
||||
void ProcessXML();
|
||||
private:
|
||||
void Initialize ( const XMLElement& defineNode );
|
||||
void Initialize();
|
||||
};
|
||||
|
||||
|
||||
|
@ -137,9 +141,15 @@ public:
|
|||
class Library
|
||||
{
|
||||
public:
|
||||
const XMLElement& node;
|
||||
const Module& module;
|
||||
std::string name;
|
||||
|
||||
Library ( const std::string& _name );
|
||||
Library ( const XMLElement& _node,
|
||||
const Module& _module,
|
||||
const std::string& _name );
|
||||
|
||||
void ProcessXML();
|
||||
};
|
||||
|
||||
extern std::string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue