* Implement <autoregister>
[reactos.git] / reactos / tools / rbuild / module.cpp
index dea3023..3bd1a5e 100644 (file)
@@ -52,18 +52,26 @@ Replace ( const string& s, const string& find, const string& with )
 }
 
 string
-FixSeparator ( const string& s )
+ChangeSeparator ( const string& s,
+                  const char fromSeparator,
+                  const char toSeparator )
 {
        string s2(s);
-       char* p = strchr ( &s2[0], cBadSep );
+       char* p = strchr ( &s2[0], fromSeparator );
        while ( p )
        {
-               *p++ = cSep;
-               p = strchr ( p, cBadSep );
+               *p++ = toSeparator;
+               p = strchr ( p, fromSeparator );
        }
        return s2;
 }
 
+string
+FixSeparator ( const string& s )
+{
+       return ChangeSeparator ( s, cBadSep, cSep );
+}
+
 string
 FixSeparatorForSystemCommand ( const string& s )
 {
@@ -179,11 +187,17 @@ GetBooleanValue ( const string& value )
                return false;
 }
 
+string
+ToLower ( string filename )
+{
+       for ( size_t i = 1; i < filename.length (); i++ )
+               filename[i] = tolower ( filename[i] );
+       return filename;
+}
+
 IfableData::~IfableData()
 {
        size_t i;
-       for ( i = 0; i < files.size (); i++ )
-               delete files[i];
        for ( i = 0; i < includes.size (); i++ )
                delete includes[i];
        for ( i = 0; i < defines.size (); i++ )
@@ -203,8 +217,6 @@ IfableData::~IfableData()
 void IfableData::ProcessXML ()
 {
        size_t i;
-       for ( i = 0; i < files.size (); i++ )
-               files[i]->ProcessXML ();
        for ( i = 0; i < includes.size (); i++ )
                includes[i]->ProcessXML ();
        for ( i = 0; i < defines.size (); i++ )
@@ -228,6 +240,7 @@ Module::Module ( const Project& project,
          node (moduleNode),
          importLibrary (NULL),
          bootstrap (NULL),
+         autoRegister(NULL),
          linkerScript (NULL),
          pch (NULL),
          cplusplus (false),
@@ -436,6 +449,8 @@ Module::ProcessXML()
                linkerScript->ProcessXML();
        if ( pch )
                pch->ProcessXML();
+       if ( autoRegister )
+               autoRegister->ProcessXML();
 }
 
 void
@@ -444,6 +459,7 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                                ParseContext& parseContext )
 {
        If* pOldIf = parseContext.ifData;
+       CompilationUnit* pOldCompilationUnit = parseContext.compilationUnit;
        bool subs_invalid = false;
        string subpath ( path );
        if ( e.name == "file" && e.value.size () > 0 )
@@ -478,12 +494,20 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                                         first,
                                         switches,
                                         false );
+               if ( parseContext.compilationUnit )
+                       parseContext.compilationUnit->files.push_back ( pFile );
+               else
+               {
+                       CompilationUnit* pCompilationUnit = new CompilationUnit ( pFile );
+                       if ( parseContext.ifData )
+                               parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
+                       else
+                               non_if_data.compilationUnits.push_back ( pCompilationUnit );
+               }
                if ( parseContext.ifData )
                        parseContext.ifData->data.files.push_back ( pFile );
                else
                        non_if_data.files.push_back ( pFile );
-               if ( parseContext.compilationUnit )
-                       parseContext.compilationUnit->files.push_back ( pFile );
                subs_invalid = true;
        }
        else if ( e.name == "library" && e.value.size () )
@@ -623,14 +647,28 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
        }
        else if ( e.name == "compilationunit" )
        {
-               CompilationUnit* pCompilationUnit = new CompilationUnit ( project, this, e );
-               if ( parseContext.ifData )
-                       parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
-               else
-                       non_if_data.compilationUnits.push_back ( pCompilationUnit );
-               parseContext.compilationUnit = pCompilationUnit;
+               if ( project.configuration.CompilationUnitsEnabled )
+               {
+                       CompilationUnit* pCompilationUnit = new CompilationUnit ( &project, this, &e );
+                       if ( parseContext.ifData )
+                               parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
+                       else
+                               non_if_data.compilationUnits.push_back ( pCompilationUnit );
+                       parseContext.compilationUnit = pCompilationUnit;
+               }
                subs_invalid = false;
        }
+       else if ( e.name == "autoregister" )
+       {
+               if ( autoRegister != NULL)
+               {
+                       throw InvalidBuildFileException ( e.location,
+                                                         "there can be only one <%s> element for a module",
+                                                         e.name.c_str() );
+               }
+               autoRegister = new AutoRegister ( project, this, e );
+               subs_invalid = true;
+       }
        if ( subs_invalid && e.subElements.size() > 0 )
                throw InvalidBuildFileException (
                        e.location,
@@ -639,6 +677,7 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
        for ( size_t i = 0; i < e.subElements.size (); i++ )
                ProcessXMLSubElement ( *e.subElements[i], subpath, parseContext );
        parseContext.ifData = pOldIf;
+       parseContext.compilationUnit = pOldCompilationUnit;
 }
 
 ModuleType
@@ -925,11 +964,10 @@ Module::HasFileWithExtension (
        const std::string& extension ) const
 {
        size_t i;
-       for ( i = 0; i < data.files.size (); i++ )
+       for ( i = 0; i < data.compilationUnits.size (); i++ )
        {
-               File& file = *data.files[i];
-               string file_ext = GetExtension ( file.name );
-               if ( !stricmp ( file_ext.c_str (), extension.c_str () ) )
+               CompilationUnit* compilationUnit = data.compilationUnits[i];
+               if ( compilationUnit->HasFileWithExtension ( extension ) )
                        return true;
        }
        for ( i = 0; i < data.ifs.size (); i++ )
@@ -971,13 +1009,6 @@ File::ProcessXML()
 {
 }
 
-bool
-File::IsGeneratedFile () const
-{
-       string extension = GetExtension ( name );
-       return ( extension == ".spec" || extension == ".SPEC" );
-}
-
 
 Library::Library ( const XMLElement& _node,
                    const Module& _module,
@@ -1251,3 +1282,85 @@ void
 PchFile::ProcessXML()
 {
 }
+
+
+AutoRegister::AutoRegister ( const Project& project_,
+                             const Module* module_,
+                             const XMLElement& node_ )
+       : project(project_),
+         module(module_),
+         node(node_)
+{
+       Initialize();
+}
+
+AutoRegister::~AutoRegister ()
+{
+}
+
+bool
+AutoRegister::IsSupportedModuleType ( ModuleType type )
+{
+       switch ( type )
+       {
+               case Win32DLL:
+                       return true;
+               case Kernel:
+               case KernelModeDLL:
+               case NativeDLL:
+               case NativeCUI:
+               case Win32CUI:
+               case Win32GUI:
+               case KernelModeDriver:
+               case BootSector:
+               case BootLoader:
+               case BuildTool:
+               case StaticLibrary:
+               case ObjectLibrary:
+               case Iso:
+               case LiveIso:
+               case Test:
+               case RpcServer:
+               case RpcClient:
+               case Alias:
+                       return false;
+       }
+       throw InvalidOperationException ( __FILE__,
+                                         __LINE__ );
+}
+
+AutoRegisterType
+AutoRegister::GetAutoRegisterType( string type )
+{
+       if ( type == "DllRegisterServer" )
+               return DllRegisterServer;
+       if ( type == "DllInstall" )
+               return DllInstall;
+       if ( type == "Both" )
+               return Both;
+       throw InvalidBuildFileException (
+               node.location,
+               "<autoregister> type attribute must be DllRegisterServer, DllInstall or Both." );
+}
+
+void
+AutoRegister::Initialize ()
+{
+       if ( !IsSupportedModuleType ( module->type ) )
+       {
+               throw InvalidBuildFileException (
+                       node.location,
+                       "<autoregister> is not applicable for this module type." );
+       }
+
+       const XMLAttribute* att = node.GetAttribute ( "infsection", true );
+       infSection = att->value;
+
+       att = node.GetAttribute ( "type", true );
+       type = GetAutoRegisterType ( att->value );
+}
+
+void
+AutoRegister::ProcessXML()
+{
+}