- Add specific properties to the keyboardlayout module type. They will assist us...
[reactos.git] / reactos / tools / rbuild / module.cpp
index 904af1e..b2b4958 100644 (file)
@@ -183,6 +183,11 @@ ToLower ( string filename )
        return filename;
 }
 
+IfableData::IfableData( )
+       : asmFiles ( 0 )
+{
+}
+
 void IfableData::ExtractModules( std::vector<Module*> &modules )
 {
        size_t i;
@@ -249,7 +254,7 @@ Module::Module ( const Project& project,
                                                  __LINE__,
                                                  "Module created with non-<module> node" );
 
-       xmlbuildFile = Path::RelativeFromWorkingDirectory ( moduleNode.xmlFile->filename () );
+       xmlbuildFile = FixSeparator ( Path::RelativeFromWorkingDirectory ( moduleNode.xmlFile->filename () ) );
 
        const XMLAttribute* att = moduleNode.GetAttribute ( "name", true );
        assert(att);
@@ -278,10 +283,6 @@ Module::Module ( const Project& project,
        else
                extension = GetDefaultModuleExtension ();
 
-       output = new FileLocation ( GetTargetDirectoryTree (),
-                                   modulePath,
-                                   name + extension );
-
        att = moduleNode.GetAttribute ( "unicode", false );
        if ( att != NULL )
        {
@@ -408,16 +409,22 @@ Module::Module ( const Project& project,
                const XMLAttribute* installbase = moduleNode.GetAttribute ( "installbase", false );
                install = new FileLocation ( InstallDirectory,
                                             installbase ? installbase->value : "",
-                                            att->value );
+                                            att->value,
+                                            &moduleNode );
+
+               output = new FileLocation ( GetTargetDirectoryTree (),
+                                           modulePath,
+                                           att->value,
+                                           &moduleNode );
        }
        else
+       {
                install = NULL;
-
-       att = moduleNode.GetAttribute ( "usewrc", false );
-       if ( att != NULL )
-               useWRC = att->value == "true";
-       else
-               useWRC = true;
+               output = new FileLocation ( GetTargetDirectoryTree (),
+                                           modulePath,
+                                           name + extension,
+                                           &moduleNode );
+       }
 
        att = moduleNode.GetAttribute ( "allowwarnings", false );
        if ( att == NULL )
@@ -459,6 +466,32 @@ Module::Module ( const Project& project,
                }
        }
 
+       att = moduleNode.GetAttribute ( "description", false );
+       if (att != NULL )
+       {
+               description = project.ResolveProperties(att->value);
+       }
+       else
+               description = "";
+
+       att = moduleNode.GetAttribute ( "lcid", false );
+       if (type == KeyboardLayout && att != NULL )
+               lcid = att->value;
+       else
+               lcid = "";
+
+       att = moduleNode.GetAttribute ( "layoutid", false );
+       if (type == KeyboardLayout && att != NULL )
+               layoutId = att->value;
+       else
+               layoutId = "";
+
+       att = moduleNode.GetAttribute ( "layoutnameresid", false );
+       if (type == KeyboardLayout && att != NULL )
+               layoutNameResId = att->value;
+       else
+               layoutNameResId = "";
+
        SetImportLibrary ( NULL );
 }
 
@@ -479,6 +512,20 @@ Module::~Module ()
                delete linkerScript;
        if ( pch )
                delete pch;
+       if ( install )
+               delete install;
+       if ( metadata )
+               delete metadata;
+       if ( bootstrap )
+               delete bootstrap;
+       if ( importLibrary )
+               delete importLibrary;
+       if ( dependency )
+               delete  dependency;
+       if ( autoRegister )
+               delete autoRegister;
+       if ( output )
+               delete output;          
 }
 
 void
@@ -578,7 +625,7 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                                         switches,
                                         false );
                if ( parseContext.compilationUnit )
-                       parseContext.compilationUnit->files.push_back ( pFile );
+                       parseContext.compilationUnit->AddFile ( pFile );
                else
                {
                        CompilationUnit* pCompilationUnit = new CompilationUnit ( pFile );
@@ -586,11 +633,27 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                                parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
                        else
                        {
-                               string ext = GetExtension ( e.value );
-                               if ( !stricmp ( ext.c_str(), ".idl" ) )
-                                       non_if_data.compilationUnits.insert ( non_if_data.compilationUnits.begin(), pCompilationUnit );
-                               else
+                               string ext = ToLower ( GetExtension ( e.value ) );
+                               if ( ext == ".idl" )
+                               {
+                                       // put .idl files at the start of the module
+                                       non_if_data.compilationUnits.insert (
+                                               non_if_data.compilationUnits.begin(),
+                                               pCompilationUnit );
+                               }
+                               else if ( ext == ".asm" || ext == ".s" )
+                               {
+                                       // put .asm files at the end of the module
                                        non_if_data.compilationUnits.push_back ( pCompilationUnit );
+                                       non_if_data.asmFiles++;
+                               }
+                               else
+                               {
+                                       // put other files in the middle
+                                       non_if_data.compilationUnits.insert (
+                                               non_if_data.compilationUnits.end() - non_if_data.asmFiles,
+                                               pCompilationUnit );
+                               }
                        }
                }
                if ( parseContext.ifData )
@@ -731,13 +794,31 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
        }
        else if ( e.name == "linkerscript" )
        {
+               if ( parseContext.ifData )
+               {
+                       throw XMLInvalidBuildFileException (
+                               e.location,
+                               "<linkerscript> is not a valid sub-element of <if>" );
+               }
                if ( linkerScript )
                {
                        throw XMLInvalidBuildFileException (
                                e.location,
                                "Only one <linkerscript> is valid per module" );
                }
-               linkerScript = new LinkerScript ( project, this, e );
+               size_t pos = e.value.find_last_of ( "/\\" );
+               if ( pos == string::npos )
+               {
+                       linkerScript = new LinkerScript (
+                               e, *this, new FileLocation ( SourceDirectory, relative_path, e.value, &e ) );
+               }
+               else
+               {
+                       string dir = e.value.substr ( 0, pos );
+                       string name = e.value.substr ( pos + 1);
+                       linkerScript = new LinkerScript (
+                               e, *this, new FileLocation ( SourceDirectory, relative_path + sSep + dir, name, &e ) );
+               }
                subs_invalid = true;
        }
        else if ( e.name == "component" )
@@ -774,14 +855,14 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                if ( pos == string::npos )
                {
                        pch = new PchFile (
-                               e, *this, FileLocation ( SourceDirectory, relative_path, e.value ) );
+                               e, *this, new FileLocation ( SourceDirectory, relative_path, e.value, &e ) );
                }
                else
                {
                        string dir = e.value.substr ( 0, pos );
                        string name = e.value.substr ( pos + 1);
                        pch = new PchFile (
-                               e, *this, FileLocation ( SourceDirectory, relative_path + sSep + dir, name ) );
+                               e, *this, new FileLocation ( SourceDirectory, relative_path + sSep + dir, name, &e ) );
                }
                subs_invalid = true;
        }
@@ -830,6 +911,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return BuildTool;
        if ( attribute.value == "staticlibrary" )
                return StaticLibrary;
+       if ( attribute.value == "hoststaticlibrary" )
+               return HostStaticLibrary;
        if ( attribute.value == "objectlibrary" )
                return ObjectLibrary;
        if ( attribute.value == "kernel" )
@@ -842,6 +925,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return NativeDLL;
        if ( attribute.value == "nativecui" )
                return NativeCUI;
+       if ( attribute.value == "keyboardlayout" )
+               return KeyboardLayout;
        if ( attribute.value == "win32dll" )
                return Win32DLL;
        if ( attribute.value == "win32ocx" )
@@ -872,6 +957,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return RpcServer;
        if ( attribute.value == "rpcclient" )
                return RpcClient;
+       if ( attribute.value == "rpcproxy" )
+               return RpcProxy;
        if ( attribute.value == "alias" )
                return Alias;
        if ( attribute.value == "idlheader" )
@@ -880,6 +967,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return EmbeddedTypeLib;
        if ( attribute.value == "elfexecutable" )
                return ElfExecutable;
+       if ( attribute.value == "cabinet" )
+               return Cabinet;
        throw InvalidAttributeValueException ( location,
                                               attribute.name,
                                               attribute.value );
@@ -892,6 +981,7 @@ Module::GetTargetDirectoryTree () const
        {
                case Kernel:
                case KernelModeDLL:
+               case KeyboardLayout:
                case NativeDLL:
                case Win32DLL:
                case Win32OCX:
@@ -909,16 +999,21 @@ Module::GetTargetDirectoryTree () const
                case LiveIso:
                case IsoRegTest:
                case LiveIsoRegTest:
-               case EmbeddedTypeLib:
                case ElfExecutable:
+               case Cabinet:
                        return OutputDirectory;
+               case EmbeddedTypeLib:
                case StaticLibrary:
+               case HostStaticLibrary:
                case ObjectLibrary:
                case RpcServer:
                case RpcClient:
+               case RpcProxy:
                case Alias:
                case IdlHeader:
                        return IntermediateDirectory;
+               case TypeDontCare:
+                       break;
        }
        throw InvalidOperationException ( __FILE__,
                                          __LINE__,
@@ -935,6 +1030,7 @@ Module::GetDefaultModuleExtension () const
                        return ExePostfix;
                case BootProgram:
                case StaticLibrary:
+               case HostStaticLibrary:
                        return ".a";
                case ObjectLibrary:
                        return ".o";
@@ -948,6 +1044,7 @@ Module::GetDefaultModuleExtension () const
 
                case KernelModeDLL:
                case NativeDLL:
+               case KeyboardLayout:
                case Win32DLL:
                        return ".dll";
                case Win32OCX:
@@ -955,6 +1052,8 @@ Module::GetDefaultModuleExtension () const
                case KernelModeDriver:
                case BootLoader:
                        return ".sys";
+               case Cabinet:
+                       return ".cab";
                case BootSector:
                        return ".o";
                case Iso:
@@ -965,8 +1064,8 @@ Module::GetDefaultModuleExtension () const
                case Test:
                        return ".exe";
                case RpcServer:
-                       return ".o";
                case RpcClient:
+               case RpcProxy:
                        return ".o";
                case Alias:
                case ElfExecutable:
@@ -974,6 +1073,8 @@ Module::GetDefaultModuleExtension () const
                        return "";
                case EmbeddedTypeLib:
                        return ".tlb";
+               case TypeDontCare:
+                       break;
        }
        throw InvalidOperationException ( __FILE__,
                                          __LINE__ );
@@ -985,7 +1086,8 @@ Module::GetDefaultModuleEntrypoint () const
        switch ( type )
        {
                case Kernel:
-                       return "NtProcessStartup";
+                       return "KiSystemStartup";
+               case KeyboardLayout:
                case KernelModeDLL:
                case KernelModeDriver:
                        return "DriverEntry@8";
@@ -1010,6 +1112,7 @@ Module::GetDefaultModuleEntrypoint () const
                                return "WinMainCRTStartup";
                case BuildTool:
                case StaticLibrary:
+               case HostStaticLibrary:
                case ObjectLibrary:
                case BootLoader:
                case BootSector:
@@ -1019,12 +1122,16 @@ Module::GetDefaultModuleEntrypoint () const
                case LiveIsoRegTest:
                case RpcServer:
                case RpcClient:
+               case RpcProxy:
                case Alias:
                case BootProgram:
                case IdlHeader:
                case ElfExecutable:
                case EmbeddedTypeLib:
+               case Cabinet:
                        return "";
+               case TypeDontCare:
+                       break;
        }
        throw InvalidOperationException ( __FILE__,
                                          __LINE__ );
@@ -1048,6 +1155,7 @@ Module::GetDefaultModuleBaseaddress () const
                case Win32SCR:
                case Win32GUI:
                        return "0x00400000";
+               case KeyboardLayout:
                case KernelModeDLL:
                case KernelModeDriver:
                        return "0x00010000";
@@ -1055,6 +1163,7 @@ Module::GetDefaultModuleBaseaddress () const
                        return "0xe00000";
                case BuildTool:
                case StaticLibrary:
+               case HostStaticLibrary:
                case ObjectLibrary:
                case BootLoader:
                case BootSector:
@@ -1064,11 +1173,15 @@ Module::GetDefaultModuleBaseaddress () const
                case LiveIsoRegTest:
                case RpcServer:
                case RpcClient:
+               case RpcProxy:
                case Alias:
                case BootProgram:
                case IdlHeader:
                case EmbeddedTypeLib:
+               case Cabinet:
                        return "";
+               case TypeDontCare:
+                       break;
        }
        throw InvalidOperationException ( __FILE__,
                                          __LINE__ );
@@ -1077,7 +1190,7 @@ Module::GetDefaultModuleBaseaddress () const
 bool
 Module::HasImportLibrary () const
 {
-       return importLibrary != NULL && type != StaticLibrary;
+       return importLibrary != NULL && type != StaticLibrary && type != HostStaticLibrary;
 }
 
 bool
@@ -1088,6 +1201,7 @@ Module::IsDLL () const
                case Kernel:
                case KernelModeDLL:
                case NativeDLL:
+               case KeyboardLayout:
                case Win32DLL:
                case Win32OCX:
                case KernelModeDriver:
@@ -1099,6 +1213,7 @@ Module::IsDLL () const
                case Win32GUI:
                case BuildTool:
                case StaticLibrary:
+               case HostStaticLibrary:
                case ObjectLibrary:
                case BootLoader:
                case BootSector:
@@ -1109,11 +1224,15 @@ Module::IsDLL () const
                case LiveIsoRegTest:
                case RpcServer:
                case RpcClient:
+               case RpcProxy:
                case Alias:
                case IdlHeader:
                case EmbeddedTypeLib:
                case ElfExecutable:
+               case Cabinet:
                        return false;
+               case TypeDontCare:
+                       break;
        }
        throw InvalidOperationException ( __FILE__,
                                          __LINE__ );
@@ -1199,7 +1318,7 @@ void
 Module::SetImportLibrary ( ImportLibrary* importLibrary )
 {
        this->importLibrary = importLibrary;
-       dependency = new FileLocation ( IntermediateDirectory,
+       dependency = new FileLocation ( HasImportLibrary () ? IntermediateDirectory : output->directory,
                                        output->relative_path,
                                        HasImportLibrary () ? "lib" + name + ".a" : output->name );
 }
@@ -1529,6 +1648,12 @@ Metadata::Metadata ( const XMLElement& _node,
 }
 
 
+ImportLibrary::~ImportLibrary ()
+{
+       delete source;
+}
+
+
 ImportLibrary::ImportLibrary ( const Project& project,
                                const XMLElement& node,
                                const Module& module )
@@ -1541,7 +1666,7 @@ ImportLibrary::ImportLibrary ( const Project& project,
 
        if ( dllname )
                this->dllname = dllname->value;
-       else if ( module.type == StaticLibrary )
+       else if ( module.type == StaticLibrary || module.type == HostStaticLibrary )
                throw XMLInvalidBuildFileException (
                    node.location,
                    "<importlibrary> dllname attribute required." );
@@ -1556,7 +1681,8 @@ ImportLibrary::ImportLibrary ( const Project& project,
        {
                source = new FileLocation ( directory,
                                            module.output->relative_path,
-                                           definition->value );
+                                           definition->value,
+                                           &node );
        }
        else
        {
@@ -1564,7 +1690,8 @@ ImportLibrary::ImportLibrary ( const Project& project,
                string name = definition->value.substr ( index + 1);
                source = new FileLocation ( directory,
                                            NormalizeFilename ( module.output->relative_path + sSep + dir ),
-                                           name );
+                                           name,
+                                           &node );
        }
 }
 
@@ -1611,6 +1738,25 @@ Property::Property ( const XMLElement& node_,
        att = node_.GetAttribute ( "value", true );
        assert(att);
        value = att->value;
+
+       att = node_.GetAttribute ( "internal", false );
+       if ( att != NULL )
+       {
+               const char* p = att->value.c_str();
+               if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
+                       isInternal = true;
+               else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
+                       isInternal = false;
+               else
+               {
+                       throw InvalidAttributeValueException (
+                               node_.location,
+                               "internal",
+                               att->value );
+               }
+       }
+       else
+               isInternal = false;
 }
 
 Property::Property ( const Project& project_,
@@ -1630,11 +1776,16 @@ Property::ProcessXML()
 PchFile::PchFile (
        const XMLElement& node_,
        const Module& module_,
-       const FileLocationfile_ )
+       const FileLocation *file_ )
        : node(node_), module(module_), file(file_)
 {
 }
 
+PchFile::~PchFile()
+{
+       delete file;
+}
+
 void
 PchFile::ProcessXML()
 {