+/*
+ * Copyright (C) 2005 Casper S. Hornstrup
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
#include "pch.h"
#include <assert.h>
using std::string;
using std::vector;
+string
+Replace ( const string& s, const string& find, const string& with )
+{
+ string ret;
+ const char* p = s.c_str();
+ while ( p )
+ {
+ const char* p2 = strstr ( p, find.c_str() );
+ if ( !p2 )
+ break;
+ if ( p2 > p )
+ ret += string ( p, p2-p );
+ ret += with;
+ p = p2 + find.size();
+ }
+ if ( *p )
+ ret += p;
+ return ret;
+}
+
string
FixSeparator ( const string& s )
{
return s2;
}
+string
+DosSeparator ( const string& s )
+{
+ string s2(s);
+ char* p = strchr ( &s2[0], '/' );
+ while ( p )
+ {
+ *p++ = '\\';
+ p = strchr ( p, '/' );
+ }
+ return s2;
+}
+
string
ReplaceExtension (
const string& filename,
return FixSeparator ( relativeNormalizedPath );
}
+bool
+GetBooleanValue ( const string& value )
+{
+ if ( value == "1" )
+ return true;
+ else
+ return false;
+}
+
IfableData::~IfableData()
{
size_t i;
__LINE__,
"Module created with non-<module> node" );
- xmlbuildFile = Path::RelativeFromWorkingDirectory ( moduleNode.xmlFile->filename() );
+ xmlbuildFile = Path::RelativeFromWorkingDirectory ( moduleNode.xmlFile->filename () );
path = FixSeparator ( modulePath );
- const XMLAttribute* att = moduleNode.GetAttribute ( "name", true );
+ enabled = true;
+
+ const XMLAttribute* att = moduleNode.GetAttribute ( "if", false );
+ if ( att != NULL )
+ enabled = GetBooleanValue ( project.ResolveProperties ( att->value ) );
+
+ att = moduleNode.GetAttribute ( "ifnot", false );
+ if ( att != NULL )
+ enabled = !GetBooleanValue ( project.ResolveProperties ( att->value ) );
+
+ att = moduleNode.GetAttribute ( "name", true );
assert(att);
name = att->value;
enableWarnings = att->value == "true";
else
enableWarnings = false;
+
+ att = moduleNode.GetAttribute ( "aliasof", false );
+ if ( type == Alias && att != NULL )
+ aliasedModuleName = att->value;
+ else
+ aliasedModuleName = "";
}
Module::~Module ()
void
Module::ProcessXML()
{
+ if ( type == Alias )
+ {
+ if ( aliasedModuleName == name )
+ throw InvalidBuildFileException (
+ node.location,
+ "module '%s' cannot link against itself",
+ name.c_str() );
+ const Module* m = project.LocateModule ( aliasedModuleName );
+ if ( !m )
+ throw InvalidBuildFileException (
+ node.location,
+ "module '%s' trying to alias non-existant module '%s'",
+ name.c_str(),
+ aliasedModuleName.c_str() );
+ }
+
size_t i;
for ( i = 0; i < node.subElements.size(); i++ )
ProcessXMLSubElement ( *node.subElements[i], path );
}
else if ( e.name == "include" )
{
- Include* include = new Include ( project, this, e );
+ Include* include = new Include ( project, this, &e );
if ( pIf )
pIf->data.includes.push_back ( include );
else
non_if_data.ifs.push_back ( pIf );
subs_invalid = false;
}
+ else if ( e.name == "ifnot" )
+ {
+ If* pOldIf = pIf;
+ pIf = new If ( e, project, this, true );
+ if ( pOldIf )
+ pOldIf->data.ifs.push_back ( pIf );
+ else
+ non_if_data.ifs.push_back ( pIf );
+ subs_invalid = false;
+ }
else if ( e.name == "compilerflag" )
{
CompilerFlag* pCompilerFlag = new CompilerFlag ( project, this, e );
return RpcServer;
if ( attribute.value == "rpcclient" )
return RpcClient;
+ if ( attribute.value == "alias" )
+ return Alias;
throw InvalidAttributeValueException ( location,
attribute.name,
attribute.value );
return ".o";
case RpcClient:
return ".o";
+ case Alias:
+ return "";
}
throw InvalidOperationException ( __FILE__,
__LINE__ );
case LiveIso:
case RpcServer:
case RpcClient:
+ case Alias:
return "";
}
throw InvalidOperationException ( __FILE__,
switch ( type )
{
case Kernel:
- return "0xc0000000";
+ return "0x80000000";
case Win32DLL:
return "0x10000000";
case NativeDLL:
case LiveIso:
case RpcServer:
case RpcClient:
+ case Alias:
return "";
}
throw InvalidOperationException ( __FILE__,
case LiveIso:
case RpcServer:
case RpcClient:
+ case Alias:
+ return false;
+ }
+ throw InvalidOperationException ( __FILE__,
+ __LINE__ );
+}
+
+bool
+Module::GenerateInOutputTree () const
+{
+ switch ( type )
+ {
+ case Kernel:
+ case KernelModeDLL:
+ case NativeDLL:
+ case Win32DLL:
+ case KernelModeDriver:
+ case NativeCUI:
+ case Win32CUI:
+ case Test:
+ case Win32GUI:
+ case BuildTool:
+ case BootLoader:
+ case BootSector:
+ case Iso:
+ case LiveIso:
+ return true;
+ case StaticLibrary:
+ case ObjectLibrary:
+ case RpcServer:
+ case RpcClient:
+ case Alias:
return false;
}
throw InvalidOperationException ( __FILE__,
: node(_node),
module(_module),
name(_name),
- imported_module(_module.project.LocateModule(_name))
+ importedModule(_module.project.LocateModule(_name))
{
if ( module.name == name )
throw InvalidBuildFileException (
node.location,
"module '%s' cannot link against itself",
name.c_str() );
- if ( !imported_module )
+ if ( !importedModule )
throw InvalidBuildFileException (
node.location,
"module '%s' trying to import non-existant module '%s'",
If::If ( const XMLElement& node_,
const Project& project_,
- const Module* module_ )
- : node(node_), project(project_), module(module_)
+ const Module* module_,
+ const bool negated_ )
+ : node(node_), project(project_), module(module_), negated(negated_)
{
const XMLAttribute* att;