Replace() bugfix #2 - forgot to insert replacement text ( yes yes I suck you can...
[reactos.git] / reactos / tools / rbuild / module.cpp
index 9c994ee..b114b7a 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * 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>
 
@@ -6,6 +23,26 @@
 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 )
 {
@@ -19,6 +56,19 @@ 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,
@@ -265,6 +315,12 @@ Module::Module ( const Project& project,
                enableWarnings = att->value == "true";
        else
                enableWarnings = false;
+
+       att = moduleNode.GetAttribute ( "aliasof", false );
+       if ( type == Alias && att != NULL )
+               aliasedModuleName = att->value;
+       else
+               aliasedModuleName = "";
 }
 
 Module::~Module ()
@@ -287,6 +343,22 @@ 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 );
@@ -526,6 +598,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return RpcServer;
        if ( attribute.value == "rpcclient" )
                return RpcClient;
+       if ( attribute.value == "alias" )
+               return Alias;
        throw InvalidAttributeValueException ( location,
                                               attribute.name,
                                               attribute.value );
@@ -565,6 +639,8 @@ Module::GetDefaultModuleExtension () const
                        return ".o";
                case RpcClient:
                        return ".o";
+               case Alias:
+                       return "";
        }
        throw InvalidOperationException ( __FILE__,
                                          __LINE__ );
@@ -601,6 +677,7 @@ Module::GetDefaultModuleEntrypoint () const
                case LiveIso:
                case RpcServer:
                case RpcClient:
+               case Alias:
                        return "";
        }
        throw InvalidOperationException ( __FILE__,
@@ -635,6 +712,7 @@ Module::GetDefaultModuleBaseaddress () const
                case LiveIso:
                case RpcServer:
                case RpcClient:
+               case Alias:
                        return "";
        }
        throw InvalidOperationException ( __FILE__,
@@ -671,6 +749,7 @@ Module::IsDLL () const
                case LiveIso:
                case RpcServer:
                case RpcClient:
+               case Alias:
                        return false;
        }
        throw InvalidOperationException ( __FILE__,
@@ -701,6 +780,7 @@ Module::GenerateInOutputTree () const
                case ObjectLibrary:
                case RpcServer:
                case RpcClient:
+               case Alias:
                        return false;
        }
        throw InvalidOperationException ( __FILE__,