Factories for Backend creation

svn path=/branches/xmlbuildsystem/; revision=12845
This commit is contained in:
Royce Mitchell III 2005-01-06 02:55:11 +00:00
parent 8051633a4c
commit 477157b4d4
11 changed files with 176 additions and 46 deletions

View file

@ -4,6 +4,35 @@
#include "../Rbuild.h" #include "../Rbuild.h"
#include "backend.h" #include "backend.h"
#include "mingw/mingw.h"
using std::string;
using std::vector;
vector<Backend::Factory*> Backend::factories;
/*static*/ void
Backend::InitFactories()
{
factories.push_back ( new Factory ( "mingw", MingwBackend::Factory ) );
}
/*static*/ Backend*
Backend::Create ( const std::string& name, Project& project )
{
string sname ( name );
strlwr ( &sname[0] );
if ( !factories.size() )
throw Exception ( "internal tool error: no registered factories" );
for ( size_t i = 0; i < factories.size(); i++ )
{
if ( sname == factories[i]->name )
return (factories[i]->factory) ( project );
}
throw UnknownBackendException ( sname );
return NULL;
}
Backend::Backend ( Project& project ) Backend::Backend ( Project& project )
: ProjectNode ( project ) : ProjectNode ( project )
{ {

View file

@ -3,11 +3,36 @@
#include "../rbuild.h" #include "../rbuild.h"
class Backend;
typedef Backend* BackendFactory ( Project& project );
class Backend class Backend
{
class Factory
{ {
public: public:
std::string name;
BackendFactory* factory;
Factory ( const std::string& name_, BackendFactory* factory_ )
: name(name_), factory(factory_)
{
}
};
static std::vector<Factory*> factories;
public:
static void InitFactories();
static Backend* Create ( const std::string& name, Project& project );
protected:
Backend ( Project& project ); Backend ( Project& project );
public:
virtual void Process () = 0; virtual void Process () = 0;
protected: protected:
Project& ProjectNode; Project& ProjectNode;
}; };

View file

@ -6,10 +6,17 @@
using std::string; using std::string;
using std::vector; using std::vector;
Backend*
MingwBackend::Factory ( Project& project )
{
return new MingwBackend ( project );
}
#ifdef WIN32 #ifdef WIN32
#define EXEPOSTFIX ".exe" #define EXEPOSTFIX ".exe"
#define SEP "\\" #define SEP "\\"
string FixSep ( const string& s ) string
FixSep ( const string& s )
{ {
string s2(s); string s2(s);
char* p = strchr ( &s2[0], '/' ); char* p = strchr ( &s2[0], '/' );
@ -23,7 +30,8 @@ string FixSep ( const string& s )
#else #else
#define EXEPOSTFIX #define EXEPOSTFIX
#define SEP "/" #define SEP "/"
string FixSep ( const string& s ) string
FixSep ( const string& s )
{ {
string s2(s); string s2(s);
char* p = strchr ( &s2[0], '\\' ); char* p = strchr ( &s2[0], '\\' );
@ -41,7 +49,8 @@ MingwBackend::MingwBackend ( Project& project )
{ {
} }
void MingwBackend::Process () void
MingwBackend::Process ()
{ {
CreateMakefile (); CreateMakefile ();
GenerateHeader (); GenerateHeader ();
@ -54,25 +63,29 @@ void MingwBackend::Process ()
CloseMakefile (); CloseMakefile ();
} }
void MingwBackend::CreateMakefile () void
MingwBackend::CreateMakefile ()
{ {
fMakefile = fopen ( ProjectNode.makefile.c_str (), "w" ); fMakefile = fopen ( ProjectNode.makefile.c_str (), "w" );
if ( !fMakefile ) if ( !fMakefile )
throw AccessDeniedException ( ProjectNode.makefile ); throw AccessDeniedException ( ProjectNode.makefile );
} }
void MingwBackend::CloseMakefile () void
MingwBackend::CloseMakefile ()
{ {
if (fMakefile) if (fMakefile)
fclose ( fMakefile ); fclose ( fMakefile );
} }
void MingwBackend::GenerateHeader () void
MingwBackend::GenerateHeader ()
{ {
fprintf ( fMakefile, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" ); fprintf ( fMakefile, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
} }
void MingwBackend::GenerateAllTarget () void
MingwBackend::GenerateAllTarget ()
{ {
fprintf ( fMakefile, "all: " ); fprintf ( fMakefile, "all: " );
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ ) for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
@ -86,7 +99,8 @@ void MingwBackend::GenerateAllTarget ()
fprintf ( fMakefile, "\n\n" ); fprintf ( fMakefile, "\n\n" );
} }
void MingwBackend::ProcessModule ( Module& module ) void
MingwBackend::ProcessModule ( Module& module )
{ {
MingwModuleHandlerList moduleHandlers; MingwModuleHandlerList moduleHandlers;
GetModuleHandlers ( moduleHandlers ); GetModuleHandlers ( moduleHandlers );
@ -101,7 +115,8 @@ void MingwBackend::ProcessModule ( Module& module )
} }
} }
void MingwBackend::GetModuleHandlers ( MingwModuleHandlerList& moduleHandlers ) void
MingwBackend::GetModuleHandlers ( MingwModuleHandlerList& moduleHandlers )
{ {
moduleHandlers.push_back ( new MingwKernelModuleHandler ( fMakefile ) ); moduleHandlers.push_back ( new MingwKernelModuleHandler ( fMakefile ) );
} }

View file

@ -20,7 +20,10 @@ public:
class MingwBackend : public Backend class MingwBackend : public Backend
{ {
public: public:
static Backend* Factory ( Project& project );
protected:
MingwBackend ( Project& project ); MingwBackend ( Project& project );
public:
virtual void Process (); virtual void Process ();
private: private:
void ProcessModule ( Module& module ); void ProcessModule ( Module& module );

View file

@ -12,15 +12,17 @@ MingwModuleHandler::MingwModuleHandler ( FILE* fMakefile )
{ {
} }
string MingwModuleHandler::GetModuleDependencies ( Module& module ) string
MingwModuleHandler::GetModuleDependencies ( Module& module )
{ {
string dependencies ( "" ); if ( !module.libraries.size() )
return "";
for ( size_t i = 0; i < module.libraries.size(); i++ ) string dependencies ( module.libraries[0]->name );
for ( size_t i = 1; i < module.libraries.size(); i++ )
{ {
if (dependencies.size () > 0) dependencies += " " + module.libraries[i]->name;
dependencies += " ";
dependencies += module.libraries[i]->name;
} }
return dependencies; return dependencies;
} }
@ -31,17 +33,20 @@ MingwKernelModuleHandler::MingwKernelModuleHandler ( FILE* fMakefile )
{ {
} }
bool MingwKernelModuleHandler::CanHandleModule ( Module& module ) bool
MingwKernelModuleHandler::CanHandleModule ( Module& module )
{ {
return true; return true;
} }
void MingwKernelModuleHandler::Process ( Module& module ) void
MingwKernelModuleHandler::Process ( Module& module )
{ {
GenerateKernelModuleTarget ( module ); GenerateKernelModuleTarget ( module );
} }
void MingwKernelModuleHandler::GenerateKernelModuleTarget ( Module& module ) void
MingwKernelModuleHandler::GenerateKernelModuleTarget ( Module& module )
{ {
fprintf ( fMakefile, "%s: %s", fprintf ( fMakefile, "%s: %s",
module.name.c_str (), module.name.c_str (),

View file

@ -61,7 +61,7 @@ InvalidBuildFileException::InvalidBuildFileException()
} }
XMLSyntaxErrorException::XMLSyntaxErrorException ( const std::string& location, XMLSyntaxErrorException::XMLSyntaxErrorException ( const string& location,
const char* message, const char* message,
... ) ... )
{ {
@ -72,19 +72,30 @@ XMLSyntaxErrorException::XMLSyntaxErrorException ( const std::string& location,
} }
RequiredAttributeNotFoundException::RequiredAttributeNotFoundException(const std::string& attributeName, RequiredAttributeNotFoundException::RequiredAttributeNotFoundException(const string& attributeName,
const std::string& elementName) const string& elementName)
: InvalidBuildFileException ( "Required attribute '%s' not found on '%s'.", : InvalidBuildFileException ( "Required attribute '%s' not found on '%s'.",
attributeName.c_str (), attributeName.c_str (),
elementName.c_str ()) elementName.c_str ())
{ {
} }
InvalidAttributeValueException::InvalidAttributeValueException(const std::string& name, InvalidAttributeValueException::InvalidAttributeValueException(const string& name,
const std::string& value) const string& value)
: InvalidBuildFileException ( "Attribute '%s' has an invalid value '%s'.", : InvalidBuildFileException ( "Attribute '%s' has an invalid value '%s'.",
name.c_str (), name.c_str (),
value.c_str ()) value.c_str ())
{ {
} }
BackendNameConflictException::BackendNameConflictException ( const string& name )
: Exception ( "Backend name conflict: '%s'", name.c_str() )
{
}
UnknownBackendException::UnknownBackendException ( const string& name )
: Exception ( "Unknown Backend requested: '%s'", name.c_str() )
{
}

View file

@ -67,4 +67,18 @@ public:
const std::string& value); const std::string& value);
}; };
class BackendNameConflictException : public Exception
{
public:
BackendNameConflictException ( const std::string& name );
};
class UnknownBackendException : public Exception
{
public:
UnknownBackendException ( const std::string& name );
};
#endif /* __EXCEPTION_H */ #endif /* __EXCEPTION_H */

View file

@ -27,7 +27,8 @@ Module::~Module ()
delete libraries[i]; delete libraries[i];
} }
void Module::ProcessXML ( const XMLElement& e, void
Module::ProcessXML ( const XMLElement& e,
const string& path ) const string& path )
{ {
string subpath ( path ); string subpath ( path );
@ -49,7 +50,8 @@ void Module::ProcessXML ( const XMLElement& e,
ProcessXML ( *e.subElements[i], subpath ); ProcessXML ( *e.subElements[i], subpath );
} }
ModuleType Module::GetModuleType ( const XMLAttribute& attribute ) ModuleType
Module::GetModuleType ( const XMLAttribute& attribute )
{ {
if ( attribute.value == "buildtool" ) if ( attribute.value == "buildtool" )
return BuildTool; return BuildTool;

View file

@ -25,7 +25,8 @@ Project::~Project ()
delete head; delete head;
} }
void Project::ReadXml () void
Project::ReadXml ()
{ {
Path path; Path path;

View file

@ -17,11 +17,19 @@ using std::vector;
int int
main ( int argc, char** argv ) main ( int argc, char** argv )
{ {
Backend::InitFactories();
if ( argc != 2 )
{
printf ( "syntax: rbuild {buildtarget}\n" );
return 1;
}
string buildtarget ( argv[1] );
strlwr ( &buildtarget[0] );
try try
{ {
string projectFilename ( "ReactOS.xml" ); string projectFilename ( "ReactOS.xml" );
Project project ( projectFilename ); Project project ( projectFilename );
Backend* backend = new MingwBackend ( project ); Backend* backend = Backend::Create ( buildtarget, project );
backend->Process (); backend->Process ();
delete backend; delete backend;

View file

@ -34,7 +34,8 @@ typedef struct {
unsigned int empty:16; unsigned int empty:16;
} ieee_long_double_t; } ieee_long_double_t;
std::string ssprintf ( const char* fmt, ... ) std::string
ssprintf ( const char* fmt, ... )
{ {
va_list arg; va_list arg;
va_start(arg, fmt); va_start(arg, fmt);
@ -43,7 +44,8 @@ std::string ssprintf ( const char* fmt, ... )
return f; return f;
} }
std::wstring sswprintf ( const wchar_t* fmt, ... ) std::wstring
sswprintf ( const wchar_t* fmt, ... )
{ {
va_list arg; va_list arg;
va_start(arg, fmt); va_start(arg, fmt);
@ -62,7 +64,8 @@ std::wstring sswprintf ( const wchar_t* fmt, ... )
#define ZEROTRUNC 128 /* truncate zero 's */ #define ZEROTRUNC 128 /* truncate zero 's */
static int skip_atoi(const char **s) static int
skip_atoi(const char **s)
{ {
int i=0; int i=0;
@ -71,7 +74,8 @@ static int skip_atoi(const char **s)
return i; return i;
} }
static int skip_wtoi(const wchar_t **s) static int
skip_wtoi(const wchar_t **s)
{ {
int i=0; int i=0;
@ -81,7 +85,8 @@ static int skip_wtoi(const wchar_t **s)
} }
static int do_div(LONGLONG *n,int base) static int
do_div(LONGLONG *n,int base)
{ {
int __res = ((ULONGLONG) *n) % (unsigned) base; int __res = ((ULONGLONG) *n) % (unsigned) base;
*n = ((ULONGLONG) *n) / (unsigned) base; *n = ((ULONGLONG) *n) / (unsigned) base;
@ -89,7 +94,8 @@ static int do_div(LONGLONG *n,int base)
} }
static bool number(std::string& f, LONGLONG num, int base, int size, int precision ,int type) static bool
number(std::string& f, LONGLONG num, int base, int size, int precision ,int type)
{ {
char c,sign,tmp[66]; char c,sign,tmp[66];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
@ -165,7 +171,8 @@ static bool number(std::string& f, LONGLONG num, int base, int size, int precisi
return true; return true;
} }
static bool wnumber(std::wstring& f, LONGLONG num, int base, int size, int precision ,int type) static bool
wnumber(std::wstring& f, LONGLONG num, int base, int size, int precision ,int type)
{ {
wchar_t c,sign,tmp[66]; wchar_t c,sign,tmp[66];
const wchar_t *digits = L"0123456789abcdefghijklmnopqrstuvwxyz"; const wchar_t *digits = L"0123456789abcdefghijklmnopqrstuvwxyz";
@ -242,7 +249,8 @@ static bool wnumber(std::wstring& f, LONGLONG num, int base, int size, int preci
} }
static bool numberf(std::string& f, double __n, char exp_sign, int size, int precision, int type) static bool
numberf(std::string& f, double __n, char exp_sign, int size, int precision, int type)
{ {
double exponent = 0.0; double exponent = 0.0;
double e; double e;
@ -435,7 +443,8 @@ static bool numberf(std::string& f, double __n, char exp_sign, int size, int pr
return true; return true;
} }
static bool wnumberf(std::wstring& f, double __n, wchar_t exp_sign, int size, int precision, int type) static bool
wnumberf(std::wstring& f, double __n, wchar_t exp_sign, int size, int precision, int type)
{ {
double exponent = 0.0; double exponent = 0.0;
double e; double e;
@ -628,7 +637,8 @@ static bool wnumberf(std::wstring& f, double __n, wchar_t exp_sign, int size, i
return true; return true;
} }
static bool numberfl(std::string& f, long double __n, char exp_sign, int size, int precision, int type) static bool
numberfl(std::string& f, long double __n, char exp_sign, int size, int precision, int type)
{ {
long double exponent = 0.0; long double exponent = 0.0;
long double e; long double e;
@ -834,7 +844,8 @@ static bool numberfl(std::string& f, long double __n, char exp_sign, int size,
return true; return true;
} }
static bool wnumberfl(std::wstring& f, long double __n, wchar_t exp_sign, int size, int precision, int type) static bool
wnumberfl(std::wstring& f, long double __n, wchar_t exp_sign, int size, int precision, int type)
{ {
long double exponent = 0.0; long double exponent = 0.0;
long double e; long double e;
@ -1035,7 +1046,8 @@ static bool wnumberfl(std::wstring& f, long double __n, wchar_t exp_sign, int s
return true; return true;
} }
static int do_string(std::string& f, const char* s, int len, int field_width, int precision, int flags) static int
do_string(std::string& f, const char* s, int len, int field_width, int precision, int flags)
{ {
int i, done = 0; int i, done = 0;
if (s == NULL) if (s == NULL)
@ -1076,7 +1088,8 @@ static int do_string(std::string& f, const char* s, int len, int field_width, in
return done; return done;
} }
static int do_wstring(std::wstring& f, const wchar_t* s, int len, int field_width, int precision, int flags) static int
do_wstring(std::wstring& f, const wchar_t* s, int len, int field_width, int precision, int flags)
{ {
int i, done = 0; int i, done = 0;
if (s == NULL) if (s == NULL)
@ -1117,7 +1130,8 @@ static int do_wstring(std::wstring& f, const wchar_t* s, int len, int field_widt
return done; return done;
} }
static int stringw(std::string& f, const wchar_t* sw, int len, int field_width, int precision, int flags) static int
stringw(std::string& f, const wchar_t* sw, int len, int field_width, int precision, int flags)
{ {
int i, done = 0; int i, done = 0;
if (sw == NULL) if (sw == NULL)
@ -1169,7 +1183,8 @@ static int stringw(std::string& f, const wchar_t* sw, int len, int field_width,
return done; return done;
} }
static int wstringa(std::wstring& f, const char* sa, int len, int field_width, int precision, int flags) static int
wstringa(std::wstring& f, const char* sa, int len, int field_width, int precision, int flags)
{ {
int i, done = 0; int i, done = 0;
if (sa == NULL) if (sa == NULL)
@ -1219,7 +1234,8 @@ static int wstringa(std::wstring& f, const char* sa, int len, int field_width, i
#define _isnanl _isnan #define _isnanl _isnan
#define _finitel _finite #define _finitel _finite
std::string ssvprintf ( const char *fmt, va_list args ) std::string
ssvprintf ( const char *fmt, va_list args )
{ {
ULONGLONG num; ULONGLONG num;
int base; int base;
@ -1569,7 +1585,8 @@ std::string ssvprintf ( const char *fmt, va_list args )
return f; return f;
} }
std::wstring sswvprintf ( const wchar_t* fmt, va_list args ) std::wstring
sswvprintf ( const wchar_t* fmt, va_list args )
{ {
ULONGLONG num; ULONGLONG num;
int base; int base;