qmake/generators/win32/msvc_objectmodel.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the qmake application of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "msvc_objectmodel.h"
       
    43 #include "msvc_vcproj.h"
       
    44 #include <qstringlist.h>
       
    45 #include <qfileinfo.h>
       
    46 
       
    47 QT_BEGIN_NAMESPACE
       
    48 
       
    49 // XML Tags ---------------------------------------------------------
       
    50 const char _Configuration[]                     = "Configuration";
       
    51 const char _Configurations[]                    = "Configurations";
       
    52 const char q_File[]                              = "File";
       
    53 const char _FileConfiguration[]                 = "FileConfiguration";
       
    54 const char q_Files[]                             = "Files";
       
    55 const char _Filter[]                            = "Filter";
       
    56 const char _Globals[]                           = "Globals";
       
    57 const char _Platform[]                          = "Platform";
       
    58 const char _Platforms[]                         = "Platforms";
       
    59 const char _Tool[]                              = "Tool";
       
    60 const char _VisualStudioProject[]               = "VisualStudioProject";
       
    61 
       
    62 // XML Properties ---------------------------------------------------
       
    63 const char _AddModuleNamesToAssembly[]          = "AddModuleNamesToAssembly";
       
    64 const char _AdditionalDependencies[]            = "AdditionalDependencies";
       
    65 const char _AdditionalFiles[]                   = "AdditionalFiles";
       
    66 const char _AdditionalIncludeDirectories[]      = "AdditionalIncludeDirectories";
       
    67 const char _AdditionalLibraryDirectories[]      = "AdditionalLibraryDirectories";
       
    68 const char _AdditionalOptions[]                 = "AdditionalOptions";
       
    69 const char _AdditionalUsingDirectories[]        = "AdditionalUsingDirectories";
       
    70 const char _AssemblerListingLocation[]          = "AssemblerListingLocation";
       
    71 const char _AssemblerOutput[]                   = "AssemblerOutput";
       
    72 const char _ATLMinimizesCRunTimeLibraryUsage[]  = "ATLMinimizesCRunTimeLibraryUsage";
       
    73 const char _BaseAddress[]                       = "BaseAddress";
       
    74 const char _BasicRuntimeChecks[]                = "BasicRuntimeChecks";
       
    75 const char _BrowseInformation[]                 = "BrowseInformation";
       
    76 const char _BrowseInformationFile[]             = "BrowseInformationFile";
       
    77 const char _BufferSecurityCheck[]               = "BufferSecurityCheck";
       
    78 const char _BuildBrowserInformation[]           = "BuildBrowserInformation";
       
    79 const char _CPreprocessOptions[]                = "CPreprocessOptions";
       
    80 const char _CallingConvention[]                 = "CallingConvention";
       
    81 const char _CharacterSet[]                      = "CharacterSet";
       
    82 const char _CommandLine[]                       = "CommandLine";
       
    83 const char _CompileAs[]                         = "CompileAs";
       
    84 const char _CompileAsManaged[]                  = "CompileAsManaged";
       
    85 const char _CompileOnly[]                       = "CompileOnly";
       
    86 const char _ConfigurationType[]                 = "ConfigurationType";
       
    87 const char _Culture[]                           = "Culture";
       
    88 const char _DLLDataFileName[]                   = "DLLDataFileName";
       
    89 const char _DebugInformationFormat[]            = "DebugInformationFormat";
       
    90 const char _DefaultCharIsUnsigned[]             = "DefaultCharIsUnsigned";
       
    91 const char _DefaultCharType[]                   = "DefaultCharType";
       
    92 const char _DelayLoadDLLs[]                     = "DelayLoadDLLs";
       
    93 const char _DeleteExtensionsOnClean[]           = "DeleteExtensionsOnClean";
       
    94 const char _Description[]                       = "Description";
       
    95 const char _Detect64BitPortabilityProblems[]    = "Detect64BitPortabilityProblems";
       
    96 const char _DisableLanguageExtensions[]         = "DisableLanguageExtensions";
       
    97 const char _DisableSpecificWarnings[]           = "DisableSpecificWarnings";
       
    98 const char _EnableCOMDATFolding[]               = "EnableCOMDATFolding";
       
    99 const char _EnableErrorChecks[]                 = "EnableErrorChecks";
       
   100 const char _EnableEnhancedInstructionSet[]      = "EnableEnhancedInstructionSet";
       
   101 const char _EnableFiberSafeOptimizations[]      = "EnableFiberSafeOptimizations";
       
   102 const char _EnableFunctionLevelLinking[]        = "EnableFunctionLevelLinking";
       
   103 const char _EnableIntrinsicFunctions[]          = "EnableIntrinsicFunctions";
       
   104 const char _EntryPointSymbol[]                  = "EntryPointSymbol";
       
   105 const char _ErrorCheckAllocations[]             = "ErrorCheckAllocations";
       
   106 const char _ErrorCheckBounds[]                  = "ErrorCheckBounds";
       
   107 const char _ErrorCheckEnumRange[]               = "ErrorCheckEnumRange";
       
   108 const char _ErrorCheckRefPointers[]             = "ErrorCheckRefPointers";
       
   109 const char _ErrorCheckStubData[]                = "ErrorCheckStubData";
       
   110 const char _ExceptionHandling[]                 = "ExceptionHandling";
       
   111 const char _ExcludedFromBuild[]                 = "ExcludedFromBuild";
       
   112 const char _ExpandAttributedSource[]            = "ExpandAttributedSource";
       
   113 const char _ExportNamedFunctions[]              = "ExportNamedFunctions";
       
   114 const char _FavorSizeOrSpeed[]                  = "FavorSizeOrSpeed";
       
   115 const char _FloatingPointModel[]                = "FloatingPointModel";
       
   116 const char _FloatingPointExceptions[]           = "FloatingPointExceptions";
       
   117 const char _ForceConformanceInForLoopScope[]    = "ForceConformanceInForLoopScope";
       
   118 const char _ForceSymbolReferences[]             = "ForceSymbolReferences";
       
   119 const char _ForcedIncludeFiles[]                = "ForcedIncludeFiles";
       
   120 const char _ForcedUsingFiles[]                  = "ForcedUsingFiles";
       
   121 const char _FullIncludePath[]                   = "FullIncludePath";
       
   122 const char _FunctionOrder[]                     = "FunctionOrder";
       
   123 const char _GenerateDebugInformation[]          = "GenerateDebugInformation";
       
   124 const char _GenerateMapFile[]                   = "GenerateMapFile";
       
   125 const char _GeneratePreprocessedFile[]          = "GeneratePreprocessedFile";
       
   126 const char _GenerateStublessProxies[]           = "GenerateStublessProxies";
       
   127 const char _GenerateTypeLibrary[]               = "GenerateTypeLibrary";
       
   128 const char _GlobalOptimizations[]               = "GlobalOptimizations";
       
   129 const char _HeaderFileName[]                    = "HeaderFileName";
       
   130 const char _HeapCommitSize[]                    = "HeapCommitSize";
       
   131 const char _HeapReserveSize[]                   = "HeapReserveSize";
       
   132 const char _IgnoreAllDefaultLibraries[]         = "IgnoreAllDefaultLibraries";
       
   133 const char _IgnoreDefaultLibraryNames[]         = "IgnoreDefaultLibraryNames";
       
   134 const char _IgnoreEmbeddedIDL[]                 = "IgnoreEmbeddedIDL";
       
   135 const char _IgnoreImportLibrary[]               = "IgnoreImportLibrary";
       
   136 const char _IgnoreStandardIncludePath[]         = "IgnoreStandardIncludePath";
       
   137 const char _ImportLibrary[]                     = "ImportLibrary";
       
   138 const char _ImproveFloatingPointConsistency[]   = "ImproveFloatingPointConsistency";
       
   139 const char _InlineFunctionExpansion[]           = "InlineFunctionExpansion";
       
   140 const char _InterfaceIdentifierFileName[]       = "InterfaceIdentifierFileName";
       
   141 const char _IntermediateDirectory[]             = "IntermediateDirectory";
       
   142 const char _KeepComments[]                      = "KeepComments";
       
   143 const char _LargeAddressAware[]                 = "LargeAddressAware";
       
   144 const char _LinkDLL[]                           = "LinkDLL";
       
   145 const char _LinkIncremental[]                   = "LinkIncremental";
       
   146 const char _LinkTimeCodeGeneration[]            = "LinkTimeCodeGeneration";
       
   147 const char _LinkToManagedResourceFile[]         = "LinkToManagedResourceFile";
       
   148 const char _MapExports[]                        = "MapExports";
       
   149 const char _MapFileName[]                       = "MapFileName";
       
   150 const char _MapLines[]                          = "MapLines ";
       
   151 const char _MergeSections[]                     = "MergeSections";
       
   152 const char _MergedIDLBaseFileName[]             = "MergedIDLBaseFileName";
       
   153 const char _MidlCommandFile[]                   = "MidlCommandFile";
       
   154 const char _MinimalRebuild[]                    = "MinimalRebuild";
       
   155 const char _MkTypLibCompatible[]                = "MkTypLibCompatible";
       
   156 const char _ModuleDefinitionFile[]              = "ModuleDefinitionFile";
       
   157 const char _Name[]                              = "Name";
       
   158 const char _ObjectFile[]                        = "ObjectFile";
       
   159 const char _OmitFramePointers[]                 = "OmitFramePointers";
       
   160 const char _OpenMP[]                            = "OpenMP";
       
   161 const char _Optimization[]                      = "Optimization ";
       
   162 const char _OptimizeForProcessor[]              = "OptimizeForProcessor";
       
   163 const char _OptimizeForWindows98[]              = "OptimizeForWindows98";
       
   164 const char _OptimizeForWindowsApplication[]     = "OptimizeForWindowsApplication";
       
   165 const char _OptimizeReferences[]                = "OptimizeReferences";
       
   166 const char _OutputDirectory[]                   = "OutputDirectory";
       
   167 const char _OutputFile[]                        = "OutputFile";
       
   168 const char _Outputs[]                           = "Outputs";
       
   169 const char _ParseFiles[]                        = "ParseFiles";
       
   170 const char _PrecompiledHeaderFile[]             = "PrecompiledHeaderFile";
       
   171 const char _PrecompiledHeaderThrough[]          = "PrecompiledHeaderThrough";
       
   172 const char _PreprocessorDefinitions[]           = "PreprocessorDefinitions";
       
   173 const char _PrimaryOutput[]                     = "PrimaryOutput";
       
   174 const char _ProjectGUID[]                       = "ProjectGUID";
       
   175 const char _Keyword[]                           = "Keyword";
       
   176 const char _ProjectType[]                       = "ProjectType";
       
   177 const char _ProgramDatabase[]                   = "ProgramDatabase";
       
   178 const char _ProgramDataBaseFileName[]           = "ProgramDataBaseFileName";
       
   179 const char _ProgramDatabaseFile[]               = "ProgramDatabaseFile";
       
   180 const char _ProxyFileName[]                     = "ProxyFileName";
       
   181 const char _RedirectOutputAndErrors[]           = "RedirectOutputAndErrors";
       
   182 const char _RegisterOutput[]                    = "RegisterOutput";
       
   183 const char _RelativePath[]                      = "RelativePath";
       
   184 const char _RemoteDirectory[]                   = "RemoteDirectory";
       
   185 const char _ResourceOnlyDLL[]                   = "ResourceOnlyDLL";
       
   186 const char _ResourceOutputFileName[]            = "ResourceOutputFileName";
       
   187 const char _RuntimeLibrary[]                    = "RuntimeLibrary";
       
   188 const char _RuntimeTypeInfo[]                   = "RuntimeTypeInfo";
       
   189 const char _SccProjectName[]                    = "SccProjectName";
       
   190 const char _SccLocalPath[]                      = "SccLocalPath";
       
   191 const char _SetChecksum[]                       = "SetChecksum";
       
   192 const char _ShowIncludes[]                      = "ShowIncludes";
       
   193 const char _ShowProgress[]                      = "ShowProgress";
       
   194 const char _SmallerTypeCheck[]                  = "SmallerTypeCheck";
       
   195 const char _StackCommitSize[]                   = "StackCommitSize";
       
   196 const char _StackReserveSize[]                  = "StackReserveSize";
       
   197 const char _StringPooling[]                     = "StringPooling";
       
   198 const char _StripPrivateSymbols[]               = "StripPrivateSymbols";
       
   199 const char _StructMemberAlignment[]             = "StructMemberAlignment";
       
   200 const char _SubSystem[]                         = "SubSystem";
       
   201 const char _SupportUnloadOfDelayLoadedDLL[]     = "SupportUnloadOfDelayLoadedDLL";
       
   202 const char _SuppressStartupBanner[]             = "SuppressStartupBanner";
       
   203 const char _SwapRunFromCD[]                     = "SwapRunFromCD";
       
   204 const char _SwapRunFromNet[]                    = "SwapRunFromNet";
       
   205 const char _TargetEnvironment[]                 = "TargetEnvironment";
       
   206 const char _TargetMachine[]                     = "TargetMachine";
       
   207 const char _TerminalServerAware[]               = "TerminalServerAware";
       
   208 const char _Path[]                              = "Path";
       
   209 const char _TreatWChar_tAsBuiltInType[]         = "TreatWChar_tAsBuiltInType";
       
   210 const char _TurnOffAssemblyGeneration[]         = "TurnOffAssemblyGeneration";
       
   211 const char _TypeLibraryFile[]                   = "TypeLibraryFile";
       
   212 const char _TypeLibraryName[]                   = "TypeLibraryName";
       
   213 const char _TypeLibraryResourceID[]             = "TypeLibraryResourceID";
       
   214 const char _UndefineAllPreprocessorDefinitions[]= "UndefineAllPreprocessorDefinitions";
       
   215 const char _UndefinePreprocessorDefinitions[]   = "UndefinePreprocessorDefinitions";
       
   216 const char _UniqueIdentifier[]                  = "UniqueIdentifier";
       
   217 const char _UseOfATL[]                          = "UseOfATL";
       
   218 const char _UseOfMfc[]                          = "UseOfMfc";
       
   219 const char _UsePrecompiledHeader[]              = "UsePrecompiledHeader";
       
   220 const char _ValidateParameters[]                = "ValidateParameters";
       
   221 const char _VCCLCompilerTool[]                  = "VCCLCompilerTool";
       
   222 const char _VCLibrarianTool[]                   = "VCLibrarianTool";
       
   223 const char _VCLinkerTool[]                      = "VCLinkerTool";
       
   224 const char _VCCustomBuildTool[]                 = "VCCustomBuildTool";
       
   225 const char _VCResourceCompilerTool[]            = "VCResourceCompilerTool";
       
   226 const char _VCMIDLTool[]                        = "VCMIDLTool";
       
   227 const char _Version[]                           = "Version";
       
   228 const char _WarnAsError[]                       = "WarnAsError";
       
   229 const char _WarningLevel[]                      = "WarningLevel";
       
   230 const char _WholeProgramOptimization[]          = "WholeProgramOptimization";
       
   231 const char _CompileForArchitecture[]            = "CompileForArchitecture";
       
   232 const char _InterworkCalls[]                    = "InterworkCalls";
       
   233 
       
   234 // XmlOutput stream functions ------------------------------
       
   235 inline XmlOutput::xml_output attrT(const char *name, const triState v)
       
   236 {
       
   237     if(v == unset)
       
   238         return noxml();
       
   239     return attr(name, (v == _True ? "true" : "false"));
       
   240 }
       
   241 
       
   242 inline XmlOutput::xml_output attrE(const char *name, int v)
       
   243 {
       
   244     return attr(name, QString::number(v));
       
   245 }
       
   246 
       
   247 /*ifNot version*/
       
   248 inline XmlOutput::xml_output attrE(const char *name, int v, int ifn)
       
   249 {
       
   250     if (v == ifn)
       
   251         return noxml();
       
   252     return attr(name, QString::number(v));
       
   253 }
       
   254 
       
   255 inline XmlOutput::xml_output attrL(const char *name, qint64 v)
       
   256 {
       
   257     return attr(name, QString::number(v));
       
   258 }
       
   259 
       
   260 /*ifNot version*/
       
   261 inline XmlOutput::xml_output attrL(const char *name, qint64 v, qint64 ifn)
       
   262 {
       
   263     if (v == ifn)
       
   264         return noxml();
       
   265     return attr(name, QString::number(v));
       
   266 }
       
   267 
       
   268 inline XmlOutput::xml_output attrS(const char *name, const QString &v)
       
   269 {
       
   270     if(v.isEmpty())
       
   271         return noxml();
       
   272     return attr(name, v);
       
   273 }
       
   274 
       
   275 inline XmlOutput::xml_output attrX(const char *name, const QStringList &v, const char *s = ",")
       
   276 {
       
   277     if(v.isEmpty())
       
   278         return noxml();
       
   279     return attr(name, v.join(s));
       
   280 }
       
   281 
       
   282 // VCCLCompilerTool -------------------------------------------------
       
   283 VCCLCompilerTool::VCCLCompilerTool()
       
   284     :        AssemblerOutput(asmListingNone),
       
   285         BasicRuntimeChecks(runtimeBasicCheckNone),
       
   286         BrowseInformation(brInfoNone),
       
   287         BufferSecurityCheck(_False),
       
   288         CallingConvention(callConventionDefault),
       
   289         CompileAs(compileAsDefault),
       
   290         CompileAsManaged(managedDefault),
       
   291         CompileOnly(unset),
       
   292         DebugInformationFormat(debugDisabled),
       
   293         DefaultCharIsUnsigned(unset),
       
   294         Detect64BitPortabilityProblems(unset),
       
   295         DisableLanguageExtensions(unset),
       
   296         EnableEnhancedInstructionSet(archNotSet),
       
   297         EnableFiberSafeOptimizations(unset),
       
   298         EnableFunctionLevelLinking(unset),
       
   299         EnableIntrinsicFunctions(unset),
       
   300         ExceptionHandling(ehDefault),
       
   301         ExpandAttributedSource(unset),
       
   302         FavorSizeOrSpeed(favorNone),
       
   303         FloatingPointModel(floatingPointNotSet),
       
   304         FloatingPointExceptions(unset),
       
   305         ForceConformanceInForLoopScope(unset),
       
   306         GeneratePreprocessedFile(preprocessNo),
       
   307         GlobalOptimizations(unset),
       
   308         IgnoreStandardIncludePath(unset),
       
   309         ImproveFloatingPointConsistency(unset),
       
   310         InlineFunctionExpansion(expandDefault),
       
   311         KeepComments(unset),
       
   312         MinimalRebuild(unset),
       
   313         OmitFramePointers(unset),
       
   314         OpenMP(unset),
       
   315         Optimization(optimizeCustom),
       
   316         OptimizeForProcessor(procOptimizeBlended),
       
   317         OptimizeForWindowsApplication(unset),
       
   318         ProgramDataBaseFileName(""),
       
   319         RuntimeLibrary(rtMultiThreaded),
       
   320         RuntimeTypeInfo(unset),
       
   321         ShowIncludes(unset),
       
   322         SmallerTypeCheck(unset),
       
   323         StringPooling(unset),
       
   324         StructMemberAlignment(alignNotSet),
       
   325         SuppressStartupBanner(unset),
       
   326         TreatWChar_tAsBuiltInType(unset),
       
   327         TurnOffAssemblyGeneration(unset),
       
   328         UndefineAllPreprocessorDefinitions(unset),
       
   329         UsePrecompiledHeader(pchNone),
       
   330         WarnAsError(unset),
       
   331         WarningLevel(warningLevel_0),
       
   332         WholeProgramOptimization(unset),
       
   333         CompileForArchitecture(archUnknown),
       
   334         InterworkCalls(unset)
       
   335 {
       
   336 }
       
   337 
       
   338 /*
       
   339  * Some values for the attribute UsePrecompiledHeader have changed from VS 2003 to VS 2005,
       
   340  * see the following chart, so we need a function that transforms those values if we are
       
   341  * using NET2005:
       
   342  *
       
   343  * Meaning                      2003    2005
       
   344  * -----------------------------------------
       
   345  * Don't use PCH                0       0
       
   346  * Create PCH (/Yc)             1       1
       
   347  * Automatically generate (/YX) 2       (seems that it was removed)
       
   348  * Use specific PCH (/Yu)       3       2
       
   349  *
       
   350  */
       
   351 inline XmlOutput::xml_output xformUsePrecompiledHeaderForNET2005(pchOption whatPch, DotNET compilerVersion)
       
   352 {
       
   353     if (compilerVersion >= NET2005) {
       
   354         if (whatPch ==  pchGenerateAuto) whatPch = (pchOption)0;
       
   355         if (whatPch ==  pchUseUsingSpecific) whatPch = (pchOption)2;
       
   356     }
       
   357     return attrE(_UsePrecompiledHeader, whatPch);
       
   358 }
       
   359 
       
   360 inline XmlOutput::xml_output xformExceptionHandlingNET2005(exceptionHandling eh, DotNET compilerVersion)
       
   361 {
       
   362     if (eh == ehDefault)
       
   363         return noxml();
       
   364 
       
   365     if (compilerVersion >= NET2005)
       
   366         return attrE(_ExceptionHandling, eh);
       
   367 
       
   368     return attrS(_ExceptionHandling, (eh == ehNoSEH ? "true" : "false"));
       
   369 }
       
   370 
       
   371 XmlOutput &operator<<(XmlOutput &xml, const VCCLCompilerTool &tool)
       
   372 {
       
   373     return xml
       
   374         << tag(_Tool)
       
   375             << attrS(_Name, _VCCLCompilerTool)
       
   376             << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
       
   377             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
   378             << attrX(_AdditionalUsingDirectories, tool.AdditionalUsingDirectories)
       
   379             << attrS(_AssemblerListingLocation, tool.AssemblerListingLocation)
       
   380             << attrE(_AssemblerOutput, tool.AssemblerOutput, /*ifNot*/ asmListingNone)
       
   381             << attrE(_BasicRuntimeChecks, tool.BasicRuntimeChecks, /*ifNot*/ runtimeBasicCheckNone)
       
   382             << attrE(_BrowseInformation, tool.BrowseInformation, /*ifNot*/ brInfoNone)
       
   383             << attrS(_BrowseInformationFile, tool.BrowseInformationFile)
       
   384             << attrT(_BufferSecurityCheck, tool.BufferSecurityCheck)
       
   385             << attrE(_CallingConvention, tool.CallingConvention, /*ifNot*/ callConventionDefault)
       
   386             << attrE(_CompileAs, tool.CompileAs, compileAsDefault)
       
   387             << attrE(_CompileAsManaged, tool.CompileAsManaged, /*ifNot*/ managedDefault)
       
   388             << attrT(_CompileOnly, tool.CompileOnly)
       
   389             << attrE(_DebugInformationFormat, tool.DebugInformationFormat, /*ifNot*/ debugUnknown)
       
   390             << attrT(_DefaultCharIsUnsigned, tool.DefaultCharIsUnsigned)
       
   391             << attrT(_Detect64BitPortabilityProblems, tool.Detect64BitPortabilityProblems)
       
   392             << attrT(_DisableLanguageExtensions, tool.DisableLanguageExtensions)
       
   393             << attrX(_DisableSpecificWarnings, tool.DisableSpecificWarnings)
       
   394             << attrE(_EnableEnhancedInstructionSet, tool.EnableEnhancedInstructionSet, /*ifnot*/ archNotSet)
       
   395             << attrT(_EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations)
       
   396             << attrT(_EnableFunctionLevelLinking, tool.EnableFunctionLevelLinking)
       
   397             << attrT(_EnableIntrinsicFunctions, tool.EnableIntrinsicFunctions)
       
   398             << xformExceptionHandlingNET2005(tool.ExceptionHandling, tool.config->CompilerVersion)
       
   399             << attrT(_ExpandAttributedSource, tool.ExpandAttributedSource)
       
   400             << attrE(_FavorSizeOrSpeed, tool.FavorSizeOrSpeed, /*ifNot*/ favorNone)
       
   401 
       
   402             << attrE(_FloatingPointModel, tool.FloatingPointModel, /*ifNot*/ floatingPointNotSet)
       
   403             << attrT(_FloatingPointExceptions, tool.FloatingPointExceptions)
       
   404 
       
   405             << attrT(_ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope)
       
   406             << attrX(_ForcedIncludeFiles, tool.ForcedIncludeFiles)
       
   407             << attrX(_ForcedUsingFiles, tool.ForcedUsingFiles)
       
   408             << attrE(_GeneratePreprocessedFile, tool.GeneratePreprocessedFile, /*ifNot*/ preprocessUnknown)
       
   409             << attrT(_GlobalOptimizations, tool.GlobalOptimizations)
       
   410             << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
       
   411             << attrT(_ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency)
       
   412             << attrE(_InlineFunctionExpansion, tool.InlineFunctionExpansion, /*ifNot*/ expandDefault)
       
   413             << attrT(_KeepComments, tool.KeepComments)
       
   414             << attrT(_MinimalRebuild, tool.MinimalRebuild)
       
   415             << attrS(_ObjectFile, tool.ObjectFile)
       
   416             << attrT(_OmitFramePointers, tool.OmitFramePointers)
       
   417             << attrT(_OpenMP, tool.OpenMP)
       
   418             << attrE(_Optimization, tool.Optimization, /*ifNot*/ optimizeDefault)
       
   419             << attrE(_OptimizeForProcessor, tool.OptimizeForProcessor, /*ifNot*/ procOptimizeBlended)
       
   420             << attrT(_OptimizeForWindowsApplication, tool.OptimizeForWindowsApplication)
       
   421             << attrS(_OutputFile, tool.OutputFile)
       
   422             << attrS(_PrecompiledHeaderFile, tool.PrecompiledHeaderFile)
       
   423             << attrS(_PrecompiledHeaderThrough, tool.PrecompiledHeaderThrough)
       
   424             << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
       
   425             << (tool.ProgramDataBaseFileName.isNull() ? noxml() : attr(_ProgramDataBaseFileName, tool.ProgramDataBaseFileName))
       
   426             << attrE(_RuntimeLibrary, tool.RuntimeLibrary, /*ifNot*/ rtUnknown)
       
   427             << attrT(_RuntimeTypeInfo, tool.RuntimeTypeInfo)
       
   428             << attrT(_ShowIncludes, tool.ShowIncludes)
       
   429             << attrT(_SmallerTypeCheck, tool.SmallerTypeCheck)
       
   430             << attrT(_StringPooling, tool.StringPooling)
       
   431             << attrE(_StructMemberAlignment, tool.StructMemberAlignment, /*ifNot*/ alignNotSet)
       
   432             << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
       
   433             << attrT(_TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType)
       
   434             << attrT(_TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration)
       
   435             << attrT(_UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions)
       
   436             << attrX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions)
       
   437             << (!tool.PrecompiledHeaderFile.isEmpty() || !tool.PrecompiledHeaderThrough.isEmpty() ? xformUsePrecompiledHeaderForNET2005(tool.UsePrecompiledHeader, tool.config->CompilerVersion) : noxml())
       
   438             << attrT(_WarnAsError, tool.WarnAsError)
       
   439             << attrE(_WarningLevel, tool.WarningLevel, /*ifNot*/ warningLevelUnknown)
       
   440             << attrT(_WholeProgramOptimization, tool.WholeProgramOptimization)
       
   441             << attrE(_CompileForArchitecture, tool.CompileForArchitecture, /*ifNot*/ archUnknown)
       
   442             << attrT(_InterworkCalls, tool.InterworkCalls)
       
   443 
       
   444         << closetag(_Tool);
       
   445 }
       
   446 
       
   447 bool VCCLCompilerTool::parseOption(const char* option)
       
   448 {
       
   449     // skip index 0 ('/' or '-')
       
   450     char first  = option[1];
       
   451     char second = option[2];
       
   452     char third  = option[3];
       
   453     char fourth = option[4];
       
   454     bool found = true;
       
   455 
       
   456     switch (first) {
       
   457     case '?':
       
   458     case 'h':
       
   459         qWarning("Generator: Option '/?', '/help': MSVC.NET projects do not support outputting help info");
       
   460         found = false;
       
   461         break;
       
   462     case '@':
       
   463         qWarning("Generator: Option '/@': MSVC.NET projects do not support the use of a response file");
       
   464         found = false;
       
   465         break;
       
   466     case 'l':
       
   467         qWarning("Generator: Option '/link': qmake generator does not support passing link options through the compiler tool");
       
   468         found = false;
       
   469         break;
       
   470     case 'A':
       
   471         if(second != 'I') {
       
   472             found = false; break;
       
   473         }
       
   474         AdditionalUsingDirectories += option+3;
       
   475         break;
       
   476     case 'C':
       
   477         KeepComments = _True;
       
   478         break;
       
   479     case 'D':
       
   480         PreprocessorDefinitions += option+2;
       
   481         break;
       
   482     case 'E':
       
   483         if(second == 'H') {
       
   484             QString opt(option);
       
   485             if (opt.contains('a') && !opt.contains('s') && !opt.contains('c'))
       
   486                 ExceptionHandling = ehSEH;
       
   487             else if (!opt.contains('a') && opt.contains("s-") && opt.contains("c-"))
       
   488                 ExceptionHandling = ehNone;
       
   489             else if (!opt.contains('a') && opt.contains('s') && opt.contains('c'))
       
   490                 ExceptionHandling = ehNoSEH;
       
   491             else {
       
   492                 // ExceptionHandling must be false, or it will override
       
   493                 // with an /EHsc option
       
   494                 ExceptionHandling = ehNone;
       
   495                 AdditionalOptions += option;
       
   496             }
       
   497             if (config->CompilerVersion < NET2005
       
   498                 && ExceptionHandling == ehSEH) {
       
   499                 ExceptionHandling = ehNone;
       
   500                 AdditionalOptions += option;
       
   501             }
       
   502             break;
       
   503         }
       
   504         GeneratePreprocessedFile = preprocessYes;
       
   505         break;
       
   506     case 'F':
       
   507         if(second <= '9' && second >= '0') {
       
   508             AdditionalOptions += option;
       
   509             break;
       
   510         } else {
       
   511             switch (second) {
       
   512             case 'A':
       
   513                 if(third == 'c') {
       
   514                     AssemblerOutput = asmListingAsmMachine;
       
   515                     if(fourth == 's')
       
   516                         AssemblerOutput = asmListingAsmMachineSrc;
       
   517                 } else if(third == 's') {
       
   518                     AssemblerOutput = asmListingAsmSrc;
       
   519                 } else {
       
   520                     AssemblerOutput = asmListingAssemblyOnly;
       
   521                 }
       
   522                 break;
       
   523             case 'a':
       
   524                 AssemblerListingLocation = option+3;
       
   525                 break;
       
   526             case 'I':
       
   527                 ForcedIncludeFiles += option+3;
       
   528                 break;
       
   529             case 'R':
       
   530                 BrowseInformation = brAllInfo;
       
   531                 BrowseInformationFile = option+3;
       
   532                 break;
       
   533             case 'r':
       
   534                 BrowseInformation = brNoLocalSymbols;
       
   535                 BrowseInformationFile = option+3;
       
   536                 break;
       
   537             case 'U':
       
   538                 ForcedUsingFiles += option+3;
       
   539                 break;
       
   540             case 'd':
       
   541                 ProgramDataBaseFileName = option+3;
       
   542                 break;
       
   543             case 'e':
       
   544                 OutputFile = option+3;
       
   545                 break;
       
   546             case 'm':
       
   547                 AdditionalOptions += option;
       
   548                 break;
       
   549             case 'o':
       
   550                 ObjectFile = option+3;
       
   551                 break;
       
   552             case 'p':
       
   553                 PrecompiledHeaderFile = option+3;
       
   554                 break;
       
   555             case 'x':
       
   556                 ExpandAttributedSource = _True;
       
   557                 break;
       
   558             default:
       
   559                 found = false; break;
       
   560             }
       
   561         }
       
   562         break;
       
   563     case 'G':
       
   564         switch (second) {
       
   565         case '3':
       
   566         case '4':
       
   567             qWarning("Option '/G3' and '/G4' were phased out in Visual C++ 5.0");
       
   568             found = false; break;
       
   569         case '5':
       
   570             OptimizeForProcessor = procOptimizePentium;
       
   571             break;
       
   572         case '6':
       
   573         case 'B':
       
   574             OptimizeForProcessor = procOptimizePentiumProAndAbove;
       
   575             break;
       
   576         case '7':
       
   577             OptimizeForProcessor = procOptimizePentium4AndAbove;
       
   578             break;
       
   579         case 'A':
       
   580             OptimizeForWindowsApplication = _True;
       
   581             break;
       
   582         case 'F':
       
   583             StringPooling = _True;
       
   584             break;
       
   585         case 'H':
       
   586             AdditionalOptions += option;
       
   587             break;
       
   588         case 'L':
       
   589             WholeProgramOptimization = _True;
       
   590             if(third == '-')
       
   591                 WholeProgramOptimization = _False;
       
   592             break;
       
   593         case 'R':
       
   594             RuntimeTypeInfo = _True;
       
   595             if(third == '-')
       
   596                 RuntimeTypeInfo = _False;
       
   597             break;
       
   598         case 'S':
       
   599             BufferSecurityCheck = _True;
       
   600             break;
       
   601         case 'T':
       
   602             EnableFiberSafeOptimizations = _True;
       
   603             break;
       
   604         case 'X':
       
   605             // Same as the /EHsc option, which is Exception Handling without SEH
       
   606             ExceptionHandling = ehNoSEH;
       
   607             if (third == '-')
       
   608                 ExceptionHandling = ehNone;
       
   609             break;
       
   610         case 'Z':
       
   611         case 'e':
       
   612         case 'h':
       
   613             AdditionalOptions += option;
       
   614             break;
       
   615         case 'd':
       
   616             CallingConvention = callConventionCDecl;
       
   617             break;
       
   618         case 'f':
       
   619             StringPooling = _True;
       
   620             AdditionalOptions += option;
       
   621             break;
       
   622         case 'm':
       
   623             MinimalRebuild = _True;
       
   624             if(third == '-')
       
   625                 MinimalRebuild = _False;
       
   626             break;
       
   627         case 'r':
       
   628             CallingConvention = callConventionFastCall;
       
   629             break;
       
   630         case 's':
       
   631             // Warning: following [num] is not used,
       
   632             // were should we put it?
       
   633             BufferSecurityCheck = _True;
       
   634             break;
       
   635         case 'y':
       
   636             EnableFunctionLevelLinking = _True;
       
   637             break;
       
   638         case 'z':
       
   639             CallingConvention = callConventionStdCall;
       
   640             break;
       
   641         default:
       
   642             found = false; break;
       
   643         }
       
   644         break;
       
   645     case 'H':
       
   646         AdditionalOptions += option;
       
   647         break;
       
   648     case 'I':
       
   649         AdditionalIncludeDirectories += option+2;
       
   650         break;
       
   651     case 'J':
       
   652         DefaultCharIsUnsigned = _True;
       
   653         break;
       
   654     case 'L':
       
   655         if(second == 'D') {
       
   656             AdditionalOptions += option;
       
   657             break;
       
   658         }
       
   659         found = false; break;
       
   660     case 'M':
       
   661         if(second == 'D') {
       
   662             RuntimeLibrary = rtMultiThreadedDLL;
       
   663             if(third == 'd')
       
   664                 RuntimeLibrary = rtMultiThreadedDebugDLL;
       
   665             break;
       
   666         } else if(second == 'L') {
       
   667             RuntimeLibrary = rtSingleThreaded;
       
   668             if(third == 'd')
       
   669                 RuntimeLibrary = rtSingleThreadedDebug;
       
   670             break;
       
   671         } else if(second == 'T') {
       
   672             RuntimeLibrary = rtMultiThreaded;
       
   673             if(third == 'd')
       
   674                 RuntimeLibrary = rtMultiThreadedDebug;
       
   675             break;
       
   676         }
       
   677         found = false; break;
       
   678     case 'O':
       
   679         switch (second) {
       
   680         case '1':
       
   681             Optimization = optimizeMinSpace;
       
   682             break;
       
   683         case '2':
       
   684             Optimization = optimizeMaxSpeed;
       
   685             break;
       
   686         case 'a':
       
   687             AdditionalOptions += option;
       
   688             break;
       
   689         case 'b':
       
   690             if(third == '0')
       
   691                 InlineFunctionExpansion = expandDisable;
       
   692             else if(third == '1')
       
   693                 InlineFunctionExpansion = expandOnlyInline;
       
   694             else if(third == '2')
       
   695                 InlineFunctionExpansion = expandAnySuitable;
       
   696             else
       
   697                 found = false;
       
   698             break;
       
   699         case 'd':
       
   700             Optimization = optimizeDisabled;
       
   701             break;
       
   702         case 'g':
       
   703             GlobalOptimizations = _True;
       
   704             break;
       
   705         case 'i':
       
   706             EnableIntrinsicFunctions = _True;
       
   707             break;
       
   708         case 'p':
       
   709             ImproveFloatingPointConsistency = _True;
       
   710             if(third == '-')
       
   711                 ImproveFloatingPointConsistency = _False;
       
   712             break;
       
   713         case 's':
       
   714             FavorSizeOrSpeed = favorSize;
       
   715             break;
       
   716         case 't':
       
   717             FavorSizeOrSpeed = favorSpeed;
       
   718             break;
       
   719         case 'w':
       
   720             AdditionalOptions += option;
       
   721             break;
       
   722         case 'x':
       
   723             Optimization = optimizeFull;
       
   724             break;
       
   725         case 'y':
       
   726             OmitFramePointers = _True;
       
   727             if(third == '-')
       
   728                 OmitFramePointers = _False;
       
   729             break;
       
   730         default:
       
   731             found = false; break;
       
   732         }
       
   733         break;
       
   734     case 'P':
       
   735         GeneratePreprocessedFile = preprocessYes;
       
   736         break;
       
   737     case 'Q':
       
   738         if(second == 'I') {
       
   739             AdditionalOptions += option;
       
   740             break;
       
   741         } else if (second == 'R') {
       
   742             QString opt = option + 3;
       
   743             if (opt == "interwork-return") {
       
   744                 InterworkCalls = _True;
       
   745                 break;
       
   746             } else if (opt == "arch4") {
       
   747                 CompileForArchitecture = archArmv4;
       
   748                 break;
       
   749             } else if (opt == "arch5") {
       
   750                 CompileForArchitecture = archArmv5;
       
   751                 break;
       
   752             } else if (opt == "arch4T") {
       
   753                 CompileForArchitecture = archArmv4T;
       
   754                 break;
       
   755             } else if (opt == "arch5T") {
       
   756                 CompileForArchitecture = archArmv5T;
       
   757                 break;
       
   758             }
       
   759         } else if (second == 'M') {
       
   760             QString opt = option + 3;
       
   761             if (opt == "mips1") {
       
   762                 CompileForArchitecture = archMips1;
       
   763                 break;
       
   764             }
       
   765             else if (opt == "mips2") {
       
   766                 CompileForArchitecture = archMips2;
       
   767                 break;
       
   768             }
       
   769             else if (opt == "mips3") {
       
   770                 CompileForArchitecture = archMips3;
       
   771                 break;
       
   772             }
       
   773             else if (opt == "mips4") {
       
   774                 CompileForArchitecture = archMips4;
       
   775                 break;
       
   776             }
       
   777             else if (opt == "mips5") {
       
   778                 CompileForArchitecture = archMips5;
       
   779                 break;
       
   780             }
       
   781             else if (opt == "mips16") {
       
   782                 CompileForArchitecture = archMips16;
       
   783                 break;
       
   784             }
       
   785             else if (opt == "mips32") {
       
   786                 CompileForArchitecture = archMips32;
       
   787                 break;
       
   788             }
       
   789             else if (opt == "mips64") {
       
   790                 CompileForArchitecture = archMips64;
       
   791                 break;
       
   792             }
       
   793         }
       
   794         found = false; break;
       
   795     case 'R':
       
   796         if(second == 'T' && third == 'C') {
       
   797             if(fourth == '1')
       
   798                 BasicRuntimeChecks = runtimeBasicCheckAll;
       
   799             else if(fourth == 'c')
       
   800                 SmallerTypeCheck = _True;
       
   801             else if(fourth == 's')
       
   802                 BasicRuntimeChecks = runtimeCheckStackFrame;
       
   803             else if(fourth == 'u')
       
   804                 BasicRuntimeChecks = runtimeCheckUninitVariables;
       
   805             else
       
   806                 found = false; break;
       
   807         }
       
   808         break;
       
   809     case 'T':
       
   810         if(second == 'C') {
       
   811             CompileAs = compileAsC;
       
   812         } else if(second == 'P') {
       
   813             CompileAs = compileAsCPlusPlus;
       
   814         } else {
       
   815             qWarning("Generator: Options '/Tp<filename>' and '/Tc<filename>' are not supported by qmake");
       
   816             found = false; break;
       
   817         }
       
   818         break;
       
   819     case 'U':
       
   820         UndefinePreprocessorDefinitions += option+2;
       
   821         break;
       
   822     case 'V':
       
   823         AdditionalOptions += option;
       
   824         break;
       
   825     case 'W':
       
   826         switch (second) {
       
   827         case 'a':
       
   828         case '4':
       
   829             WarningLevel = warningLevel_4;
       
   830             break;
       
   831         case '3':
       
   832             WarningLevel = warningLevel_3;
       
   833             break;
       
   834         case '2':
       
   835             WarningLevel = warningLevel_2;
       
   836             break;
       
   837         case '1':
       
   838             WarningLevel = warningLevel_1;
       
   839             break;
       
   840         case '0':
       
   841             WarningLevel = warningLevel_0;
       
   842             break;
       
   843         case 'L':
       
   844             AdditionalOptions += option;
       
   845             break;
       
   846         case 'X':
       
   847             WarnAsError = _True;
       
   848             break;
       
   849         case 'p':
       
   850             if(third == '6' && fourth == '4') {
       
   851                 Detect64BitPortabilityProblems = _True;
       
   852                 break;
       
   853             }
       
   854             // Fallthrough
       
   855         default:
       
   856             found = false; break;
       
   857         }
       
   858         break;
       
   859     case 'X':
       
   860         IgnoreStandardIncludePath = _True;
       
   861         break;
       
   862     case 'Y':
       
   863         switch (second) {
       
   864         case '\0':
       
   865         case '-':
       
   866             AdditionalOptions += option;
       
   867             break;
       
   868         case 'X':
       
   869             UsePrecompiledHeader = pchGenerateAuto;
       
   870             PrecompiledHeaderFile = option+3;
       
   871             break;
       
   872         case 'c':
       
   873             UsePrecompiledHeader = pchCreateUsingSpecific;
       
   874             PrecompiledHeaderFile = option+3;
       
   875             break;
       
   876         case 'd':
       
   877         case 'l':
       
   878             AdditionalOptions += option;
       
   879             break;
       
   880         case 'u':
       
   881             UsePrecompiledHeader = pchUseUsingSpecific;
       
   882             PrecompiledHeaderFile = option+3;
       
   883             break;
       
   884         default:
       
   885             found = false; break;
       
   886         }
       
   887         break;
       
   888     case 'Z':
       
   889         switch (second) {
       
   890         case '7':
       
   891             DebugInformationFormat = debugOldStyleInfo;
       
   892             break;
       
   893         case 'I':
       
   894             DebugInformationFormat = debugEditAndContinue;
       
   895             break;
       
   896         case 'd':
       
   897             DebugInformationFormat = debugLineInfoOnly;
       
   898             break;
       
   899         case 'i':
       
   900             DebugInformationFormat = debugEnabled;
       
   901             break;
       
   902         case 'l':
       
   903             DebugInformationFormat = debugEditAndContinue;
       
   904             break;
       
   905         case 'a':
       
   906             DisableLanguageExtensions = _True;
       
   907             break;
       
   908         case 'e':
       
   909             DisableLanguageExtensions = _False;
       
   910             break;
       
   911         case 'c':
       
   912             if(third == ':') {
       
   913                 const char *c = option + 4;
       
   914                 // Go to the end of the option
       
   915                 while ( *c != '\0' && *c != ' ' && *c != '-')
       
   916                     ++c;
       
   917                 if(fourth == 'f')
       
   918                     ForceConformanceInForLoopScope = ((*c) == '-' ? _False : _True);
       
   919                 else if(fourth == 'w')
       
   920                     TreatWChar_tAsBuiltInType = ((*c) == '-' ? _False : _True);
       
   921                 else
       
   922                     found = false;
       
   923             } else {
       
   924                 found = false; break;
       
   925             }
       
   926             break;
       
   927         case 'g':
       
   928         case 'm':
       
   929         case 's':
       
   930             AdditionalOptions += option;
       
   931             break;
       
   932         case 'p':
       
   933             switch (third)
       
   934             {
       
   935             case '\0':
       
   936             case '1':
       
   937                 StructMemberAlignment = alignSingleByte;
       
   938                 if(fourth == '6')
       
   939                     StructMemberAlignment = alignSixteenBytes;
       
   940                 break;
       
   941             case '2':
       
   942                 StructMemberAlignment = alignTwoBytes;
       
   943                 break;
       
   944             case '4':
       
   945                 StructMemberAlignment = alignFourBytes;
       
   946                 break;
       
   947             case '8':
       
   948                 StructMemberAlignment = alignEightBytes;
       
   949                 break;
       
   950             default:
       
   951                 found = false; break;
       
   952             }
       
   953             break;
       
   954         default:
       
   955             found = false; break;
       
   956         }
       
   957         break;
       
   958     case 'a':
       
   959         if (second == 'r' && third == 'c' && fourth == 'h') {
       
   960             if (option[5] == ':') {
       
   961                 const char *o = option;
       
   962                 if (o[6] == 'S' && o[7] == 'S' && o[8] == 'E') {
       
   963                     EnableEnhancedInstructionSet = o[9] == '2' ? archSSE2 : archSSE;
       
   964                     break;
       
   965                 }
       
   966             }
       
   967         }
       
   968         found = false;
       
   969         break;
       
   970     case 'b':   // see http://msdn2.microsoft.com/en-us/library/ms173499.aspx
       
   971         if (second == 'i' && third == 'g' && fourth == 'o') {
       
   972             const char *o = option;
       
   973             if (o[5] == 'b' && o[6] == 'j') {
       
   974                 AdditionalOptions += option;
       
   975                 break;
       
   976             }
       
   977         }
       
   978         found = false;
       
   979         break;
       
   980     case 'c':
       
   981         if(second == '\0') {
       
   982             CompileOnly = _True;
       
   983         } else if(second == 'l') {
       
   984             if (config->CompilerVersion < NET2005) {
       
   985                 if(*(option+5) == 'n') {
       
   986                     CompileAsManaged = managedAssemblyPure;
       
   987                     TurnOffAssemblyGeneration = _True;
       
   988                 } else if(*(option+5) == 'p') {
       
   989                     CompileAsManaged = managedAssemblyPure;
       
   990                     warn_msg(WarnLogic, "/clr:pure option only for .NET >= 2005, using /clr");
       
   991                 } else if(*(option+5) == 's') {
       
   992                     CompileAsManaged = managedAssemblyPure;
       
   993                     warn_msg(WarnLogic, "/clr:safe option only for .NET >= 2005, using /clr");
       
   994                 } else if(*(option+5) == 'o') {
       
   995                     CompileAsManaged = managedAssemblyPure;
       
   996                     warn_msg(WarnLogic, "/clr:oldSyntax option only for .NET >= 2005, using /clr");
       
   997                 } else if(*(option+5) == 'i') {
       
   998                     CompileAsManaged = managedAssemblyPure;
       
   999                     warn_msg(WarnLogic, "initialAppDomain enum value unknown, using /crl");
       
  1000                 } else {
       
  1001                     CompileAsManaged = managedAssemblyPure;
       
  1002                 }
       
  1003             } else {
       
  1004                 if(*(option+5) == 'n') {
       
  1005                     CompileAsManaged = managedAssembly;
       
  1006                     TurnOffAssemblyGeneration = _True;
       
  1007                 } else if(*(option+5) == 'p') {
       
  1008                     CompileAsManaged = managedAssemblyPure;
       
  1009                 } else if(*(option+5) == 's') {
       
  1010                     CompileAsManaged = managedAssemblySafe;
       
  1011                 } else if(*(option+5) == 'o') {
       
  1012                     CompileAsManaged = managedAssemblyOldSyntax;
       
  1013                 } else if(*(option+5) == 'i') {
       
  1014                     CompileAsManaged = managedAssembly;
       
  1015                     warn_msg(WarnLogic, "initialAppDomain enum value unknown, using /crl default");
       
  1016                 } else {
       
  1017                     CompileAsManaged = managedAssembly;
       
  1018                 }
       
  1019             }
       
  1020         } else {
       
  1021             found = false; break;
       
  1022         }
       
  1023         break;
       
  1024     case 'd':
       
  1025         if(second != 'r') {
       
  1026             found = false; break;
       
  1027         }
       
  1028         CompileAsManaged = managedAssembly;
       
  1029         break;
       
  1030     case 'f':
       
  1031         if(second == 'p' && third == ':') {
       
  1032             // Go to the end of the option
       
  1033             const char *c = option + 4;
       
  1034             while (*c != '\0' && *c != ' ' && *c != '-')
       
  1035                 ++c;
       
  1036             switch (fourth) {
       
  1037             case 'e':
       
  1038                 FloatingPointExceptions = ((*c) == '-' ? _False : _True);
       
  1039                 break;
       
  1040             case 'f':
       
  1041                 FloatingPointModel = floatingPointFast;
       
  1042                 break;
       
  1043             case 'p':
       
  1044                 FloatingPointModel = floatingPointPrecise;
       
  1045                 break;
       
  1046             case 's':
       
  1047                 FloatingPointModel = floatingPointStrict;
       
  1048                 break;
       
  1049             default:
       
  1050                 found = false;
       
  1051                 break;
       
  1052             }
       
  1053         }
       
  1054         break;
       
  1055     case 'n':
       
  1056         if(second == 'o' && third == 'B' && fourth == 'o') {
       
  1057             AdditionalOptions += "/noBool";
       
  1058             break;
       
  1059         }
       
  1060         if(second == 'o' && third == 'l' && fourth == 'o') {
       
  1061             SuppressStartupBanner = _True;
       
  1062             break;
       
  1063         }
       
  1064         found = false; break;
       
  1065     case 'o':
       
  1066         if (second == 'p' && third == 'e' && fourth == 'n') {
       
  1067             OpenMP = _True;
       
  1068             break;
       
  1069         }
       
  1070         found = false; break;
       
  1071     case 's':
       
  1072         if(second == 'h' && third == 'o' && fourth == 'w') {
       
  1073             ShowIncludes = _True;
       
  1074             break;
       
  1075         }
       
  1076         found = false; break;
       
  1077     case 'u':
       
  1078         UndefineAllPreprocessorDefinitions = _True;
       
  1079         break;
       
  1080     case 'v':
       
  1081         if(second == 'd' || second == 'm') {
       
  1082             AdditionalOptions += option;
       
  1083             break;
       
  1084         }
       
  1085         found = false; break;
       
  1086     case 'w':
       
  1087         switch (second) {
       
  1088         case '\0':
       
  1089             WarningLevel = warningLevel_0;
       
  1090             break;
       
  1091         case 'd':
       
  1092             DisableSpecificWarnings += option+3;
       
  1093             break;
       
  1094         default:
       
  1095             AdditionalOptions += option;
       
  1096         }
       
  1097         break;
       
  1098     default:
       
  1099         AdditionalOptions += option;
       
  1100         break;
       
  1101     }
       
  1102     if(!found) {
       
  1103         warn_msg(WarnLogic, "Could not parse Compiler option: %s, added as AdditionalOption", option);
       
  1104         AdditionalOptions += option;
       
  1105     }
       
  1106     return true;
       
  1107 }
       
  1108 
       
  1109 // VCLinkerTool -----------------------------------------------------
       
  1110 VCLinkerTool::VCLinkerTool()
       
  1111     :        EnableCOMDATFolding(optFoldingDefault),
       
  1112         GenerateDebugInformation(unset),
       
  1113         GenerateMapFile(unset),
       
  1114         HeapCommitSize(-1),
       
  1115         HeapReserveSize(-1),
       
  1116         IgnoreAllDefaultLibraries(unset),
       
  1117         IgnoreEmbeddedIDL(unset),
       
  1118         IgnoreImportLibrary(_True),
       
  1119         LargeAddressAware(addrAwareDefault),
       
  1120         LinkDLL(unset),
       
  1121         LinkIncremental(linkIncrementalDefault),
       
  1122         LinkTimeCodeGeneration(optLTCGDefault),
       
  1123         MapExports(unset),
       
  1124         MapLines(unset),
       
  1125         OptimizeForWindows98(optWin98Default),
       
  1126         OptimizeReferences(optReferencesDefault),
       
  1127         RegisterOutput(unset),
       
  1128         ResourceOnlyDLL(unset),
       
  1129         SetChecksum(unset),
       
  1130         ShowProgress(linkProgressNotSet),
       
  1131         StackCommitSize(-1),
       
  1132         StackReserveSize(-1),
       
  1133         SubSystem(subSystemNotSet),
       
  1134         SupportUnloadOfDelayLoadedDLL(unset),
       
  1135         SuppressStartupBanner(unset),
       
  1136         SwapRunFromCD(unset),
       
  1137         SwapRunFromNet(unset),
       
  1138         TargetMachine(machineNotSet),
       
  1139         TerminalServerAware(termSvrAwareDefault),
       
  1140         TurnOffAssemblyGeneration(unset),
       
  1141         TypeLibraryResourceID(0)
       
  1142 {
       
  1143 }
       
  1144 
       
  1145 XmlOutput &operator<<(XmlOutput &xml, const VCLinkerTool &tool)
       
  1146 {
       
  1147     return xml
       
  1148         << tag(_Tool)
       
  1149             << attrS(_Name, _VCLinkerTool)
       
  1150             << attrX(_AdditionalDependencies, tool.AdditionalDependencies, " ")
       
  1151             << attrX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories)
       
  1152             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
  1153             << attrX(_AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly)
       
  1154             << attrS(_BaseAddress, tool.BaseAddress)
       
  1155             << attrX(_DelayLoadDLLs, tool.DelayLoadDLLs)
       
  1156             << attrE(_EnableCOMDATFolding, tool.EnableCOMDATFolding, /*ifNot*/ optFoldingDefault)
       
  1157             << attrS(_EntryPointSymbol, tool.EntryPointSymbol)
       
  1158             << attrX(_ForceSymbolReferences, tool.ForceSymbolReferences)
       
  1159             << attrS(_FunctionOrder, tool.FunctionOrder)
       
  1160             << attrT(_GenerateDebugInformation, tool.GenerateDebugInformation)
       
  1161             << attrT(_GenerateMapFile, tool.GenerateMapFile)
       
  1162             << attrL(_HeapCommitSize, tool.HeapCommitSize, /*ifNot*/ -1)
       
  1163             << attrL(_HeapReserveSize, tool.HeapReserveSize, /*ifNot*/ -1)
       
  1164             << attrT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
       
  1165             << attrX(_IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames)
       
  1166             << attrT(_IgnoreEmbeddedIDL, tool.IgnoreEmbeddedIDL)
       
  1167             << attrT(_IgnoreImportLibrary, tool.IgnoreImportLibrary)
       
  1168             << attrS(_ImportLibrary, tool.ImportLibrary)
       
  1169             << attrE(_LargeAddressAware, tool.LargeAddressAware, /*ifNot*/ addrAwareDefault)
       
  1170             << attrT(_LinkDLL, tool.LinkDLL)
       
  1171             << attrE(_LinkIncremental, tool.LinkIncremental, /*ifNot*/ linkIncrementalDefault)
       
  1172             << attrE(_LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration)
       
  1173             << attrS(_LinkToManagedResourceFile, tool.LinkToManagedResourceFile)
       
  1174             << attrT(_MapExports, tool.MapExports)
       
  1175             << attrS(_MapFileName, tool.MapFileName)
       
  1176             << attrT(_MapLines, tool.MapLines)
       
  1177             << attrS(_MergedIDLBaseFileName, tool.MergedIDLBaseFileName)
       
  1178             << attrS(_MergeSections, tool.MergeSections)
       
  1179             << attrS(_MidlCommandFile, tool.MidlCommandFile)
       
  1180             << attrS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
       
  1181             << attrE(_OptimizeForWindows98, tool.OptimizeForWindows98, /*ifNot*/ optWin98Default)
       
  1182             << attrE(_OptimizeReferences, tool.OptimizeReferences, /*ifNot*/ optReferencesDefault)
       
  1183             << attrS(_OutputFile, tool.OutputFile)
       
  1184             << attr(_ProgramDatabaseFile, tool.ProgramDatabaseFile)
       
  1185             << attrT(_RegisterOutput, tool.RegisterOutput)
       
  1186             << attrT(_ResourceOnlyDLL, tool.ResourceOnlyDLL)
       
  1187             << attrT(_SetChecksum, tool.SetChecksum)
       
  1188             << attrE(_ShowProgress, tool.ShowProgress, /*ifNot*/ linkProgressNotSet)
       
  1189             << attrL(_StackCommitSize, tool.StackCommitSize, /*ifNot*/ -1)
       
  1190             << attrL(_StackReserveSize, tool.StackReserveSize, /*ifNot*/ -1)
       
  1191             << attrS(_StripPrivateSymbols, tool.StripPrivateSymbols)
       
  1192             << attrE(_SubSystem, tool.SubSystem)
       
  1193             << attrT(_SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL)
       
  1194             << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
       
  1195             << attrT(_SwapRunFromCD, tool.SwapRunFromCD)
       
  1196             << attrT(_SwapRunFromNet, tool.SwapRunFromNet)
       
  1197             << attrE(_TargetMachine, tool.TargetMachine, /*ifNot*/ machineNotSet)
       
  1198             << attrE(_TerminalServerAware, tool.TerminalServerAware, /*ifNot*/ termSvrAwareDefault)
       
  1199             << attrT(_TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration)
       
  1200             << attrS(_TypeLibraryFile, tool.TypeLibraryFile)
       
  1201             << attrL(_TypeLibraryResourceID, tool.TypeLibraryResourceID, /*ifNot*/ rcUseDefault)
       
  1202             << attrS(_Version, tool.Version)
       
  1203         << closetag(_Tool);
       
  1204 }
       
  1205 
       
  1206 // Hashing routine to do fast option lookups ----
       
  1207 // Slightly rewritten to stop on ':' ',' and '\0'
       
  1208 // Original routine in qtranslator.cpp ----------
       
  1209 static uint elfHash(const char* name)
       
  1210 {
       
  1211     const uchar *k;
       
  1212     uint h = 0;
       
  1213     uint g;
       
  1214 
       
  1215     if(name) {
       
  1216         k = (const uchar *) name;
       
  1217         while((*k) &&
       
  1218                 (*k)!= ':' &&
       
  1219                 (*k)!=',' &&
       
  1220                 (*k)!=' ') {
       
  1221             h = (h << 4) + *k++;
       
  1222             if((g = (h & 0xf0000000)) != 0)
       
  1223                 h ^= g >> 24;
       
  1224             h &= ~g;
       
  1225         }
       
  1226     }
       
  1227     if(!h)
       
  1228         h = 1;
       
  1229     return h;
       
  1230 }
       
  1231 
       
  1232 //#define USE_DISPLAY_HASH
       
  1233 #ifdef USE_DISPLAY_HASH
       
  1234 static void displayHash(const char* str)
       
  1235 {
       
  1236     printf("case 0x%07x: // %s\n    break;\n", elfHash(str), str);
       
  1237 }
       
  1238 #endif
       
  1239 
       
  1240 bool VCLinkerTool::parseOption(const char* option)
       
  1241 {
       
  1242 #ifdef USE_DISPLAY_HASH
       
  1243     // Main options
       
  1244     displayHash("/ALIGN"); displayHash("/ALLOWBIND"); displayHash("/ASSEMBLYMODULE");
       
  1245     displayHash("/ASSEMBLYRESOURCE"); displayHash("/BASE"); displayHash("/DEBUG");
       
  1246     displayHash("/DEF"); displayHash("/DEFAULTLIB"); displayHash("/DELAY");
       
  1247     displayHash("/DELAYLOAD"); displayHash("/DLL"); displayHash("/DRIVER");
       
  1248     displayHash("/ENTRY"); displayHash("/EXETYPE"); displayHash("/EXPORT");
       
  1249     displayHash("/FIXED"); displayHash("/FORCE"); displayHash("/HEAP");
       
  1250     displayHash("/IDLOUT"); displayHash("/IGNORE"); displayHash("/IGNOREIDL"); displayHash("/IMPLIB");
       
  1251     displayHash("/INCLUDE"); displayHash("/INCREMENTAL"); displayHash("/LARGEADDRESSAWARE");
       
  1252     displayHash("/LIBPATH"); displayHash("/LTCG"); displayHash("/MACHINE");
       
  1253     displayHash("/MAP"); displayHash("/MAPINFO"); displayHash("/MERGE");
       
  1254     displayHash("/MIDL"); displayHash("/NOASSEMBLY"); displayHash("/NODEFAULTLIB");
       
  1255     displayHash("/NOENTRY"); displayHash("/NOLOGO"); displayHash("/OPT");
       
  1256     displayHash("/ORDER"); displayHash("/OUT"); displayHash("/PDB");
       
  1257     displayHash("/PDBSTRIPPED"); displayHash("/RELEASE"); displayHash("/SECTION");
       
  1258     displayHash("/STACK"); displayHash("/STUB"); displayHash("/SUBSYSTEM");
       
  1259     displayHash("/SWAPRUN"); displayHash("/TLBID"); displayHash("/TLBOUT");
       
  1260     displayHash("/TSAWARE"); displayHash("/VERBOSE"); displayHash("/VERSION");
       
  1261     displayHash("/VXD"); displayHash("/WS "); displayHash("/libpath");
       
  1262 
       
  1263 #endif
       
  1264 #ifdef USE_DISPLAY_HASH
       
  1265     // Sub options
       
  1266     displayHash("UNLOAD"); displayHash("NOBIND"); displayHash("no"); displayHash("NOSTATUS"); displayHash("STATUS");
       
  1267     displayHash("AM33"); displayHash("ARM"); displayHash("CEE"); displayHash("EBC"); displayHash("IA64"); displayHash("X86"); displayHash("X64"); displayHash("M32R");
       
  1268     displayHash("MIPS"); displayHash("MIPS16"); displayHash("MIPSFPU"); displayHash("MIPSFPU16"); displayHash("MIPSR41XX"); displayHash("PPC");
       
  1269     displayHash("SH3"); displayHash("SH3DSP"); displayHash("SH4"); displayHash("SH5"); displayHash("THUMB"); displayHash("TRICORE"); displayHash("EXPORTS");
       
  1270     displayHash("LINES"); displayHash("REF"); displayHash("NOREF"); displayHash("ICF"); displayHash("WIN98"); displayHash("NOWIN98");
       
  1271     displayHash("CONSOLE"); displayHash("EFI_APPLICATION"); displayHash("EFI_BOOT_SERVICE_DRIVER"); displayHash("EFI_ROM"); displayHash("EFI_RUNTIME_DRIVER"); displayHash("NATIVE");
       
  1272     displayHash("POSIX"); displayHash("WINDOWS"); displayHash("WINDOWSCE"); displayHash("NET"); displayHash("CD"); displayHash("NO");
       
  1273 #endif
       
  1274     bool found = true;
       
  1275     switch (elfHash(option)) {
       
  1276     case 0x3360dbe: // /ALIGN[:number]
       
  1277     case 0x1485c34: // /ALLOWBIND[:NO]
       
  1278     case 0x6b21972: // /DEFAULTLIB:library
       
  1279     case 0x396ea92: // /DRIVER[:UPONLY | :WDM]
       
  1280     case 0xaca9d75: // /EXETYPE[:DYNAMIC | :DEV386]
       
  1281     case 0x3ad5444: // /EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
       
  1282     case 0x33aec94: // /FIXED[:NO]
       
  1283     case 0x33b4675: // /FORCE:[MULTIPLE|UNRESOLVED]
       
  1284     case 0x3dc3455: // /IGNORE:number,number,number,number  ### NOTE: This one is undocumented, but it is even used by Microsoft.
       
  1285                     //                                      In recent versions of the Microsoft linker they have disabled this undocumented feature.
       
  1286     case 0x7988f7e: // /SECTION:name,[E][R][W][S][D][K][L][P][X][,ALIGN=#]
       
  1287     case 0x0348992: // /STUB:filename
       
  1288     case 0x0034bc4: // /VXD
       
  1289     case 0x0034c50: // /WS
       
  1290         AdditionalOptions += option;
       
  1291         break;
       
  1292     case 0x679c075: // /ASSEMBLYMODULE:filename
       
  1293         AddModuleNamesToAssembly += option+15;
       
  1294         break;
       
  1295     case 0x062d065: // /ASSEMBLYRESOURCE:filename
       
  1296         LinkToManagedResourceFile = option+18;
       
  1297         break;
       
  1298     case 0x0336675: // /BASE:{address | @filename,key}
       
  1299         // Do we need to do a manual lookup when '@filename,key'?
       
  1300         // Seems BaseAddress only can contain the location...
       
  1301         // We don't use it in Qt, so keep it simple for now
       
  1302         BaseAddress = option+6;
       
  1303         break;
       
  1304     case 0x3389797: // /DEBUG
       
  1305         GenerateDebugInformation = _True;
       
  1306         break;
       
  1307     case 0x0033896: // /DEF:filename
       
  1308         ModuleDefinitionFile = option+5;
       
  1309         break;
       
  1310     case 0x338a069: // /DELAY:{UNLOAD | NOBIND}
       
  1311         // MS documentation does not specify what to do with
       
  1312         // this option, so we'll put it in AdditionalOptions
       
  1313         AdditionalOptions += option;
       
  1314         break;
       
  1315     case 0x06f4bf4: // /DELAYLOAD:dllname
       
  1316         DelayLoadDLLs += option+11;
       
  1317         break;
       
  1318     case 0x003390c: // /DLL
       
  1319         // This option is not used for vcproj files
       
  1320         break;
       
  1321     case 0x33a3979: // /ENTRY:function
       
  1322         EntryPointSymbol = option+7;
       
  1323         break;
       
  1324     case 0x033c960: // /HEAP:reserve[,commit]
       
  1325         {
       
  1326             QStringList both = QString(option+6).split(",");
       
  1327             HeapReserveSize = both[0].toLongLong();
       
  1328             if(both.count() == 2)
       
  1329                 HeapCommitSize = both[1].toLongLong();
       
  1330         }
       
  1331         break;
       
  1332     case 0x3d91494: // /IDLOUT:[path\]filename
       
  1333         MergedIDLBaseFileName = option+8;
       
  1334         break;
       
  1335     case 0x345a04c: // /IGNOREIDL
       
  1336         IgnoreEmbeddedIDL = _True;
       
  1337         break;
       
  1338     case 0x3e250e2: // /IMPLIB:filename
       
  1339         ImportLibrary = option+8;
       
  1340         break;
       
  1341     case 0xe281ab5: // /INCLUDE:symbol
       
  1342         ForceSymbolReferences += option+9;
       
  1343         break;
       
  1344     case 0xb28103c: // /INCREMENTAL[:no]
       
  1345         if(*(option+12) == ':' &&
       
  1346              (*(option+13) == 'n' || *(option+13) == 'N'))
       
  1347             LinkIncremental = linkIncrementalNo;
       
  1348         else
       
  1349             LinkIncremental = linkIncrementalYes;
       
  1350         break;
       
  1351     case 0x26e4675: // /LARGEADDRESSAWARE[:no]
       
  1352         if(*(option+18) == ':' &&
       
  1353              *(option+19) == 'n')
       
  1354             LargeAddressAware = addrAwareNoLarge;
       
  1355         else
       
  1356             LargeAddressAware = addrAwareLarge;
       
  1357         break;
       
  1358     case 0x2f96bc8: // /libpath:dir
       
  1359     case 0x0d745c8: // /LIBPATH:dir
       
  1360         AdditionalLibraryDirectories += option+9;
       
  1361         break;
       
  1362     case 0x0341877: // /LTCG[:NOSTATUS|:STATUS]
       
  1363         config->WholeProgramOptimization = _True;
       
  1364         if (config->CompilerVersion >= NET2005) {
       
  1365             LinkTimeCodeGeneration = optLTCGEnabled;
       
  1366             if(*(option+5) == ':') {
       
  1367                 const char* str = option+6;
       
  1368                 if (*str == 'S')
       
  1369                     ShowProgress = linkProgressAll;
       
  1370 #ifndef Q_OS_WIN
       
  1371                 else if (strncasecmp(str, "pginstrument", 12))
       
  1372                     LinkTimeCodeGeneration = optLTCGInstrument;
       
  1373                 else if (strncasecmp(str, "pgoptimize", 10))
       
  1374                     LinkTimeCodeGeneration = optLTCGOptimize;
       
  1375                 else if (strncasecmp(str, "pgupdate", 8 ))
       
  1376                     LinkTimeCodeGeneration = optLTCGUpdate;
       
  1377 #else
       
  1378                 else if (_stricmp(str, "pginstrument"))
       
  1379                     LinkTimeCodeGeneration = optLTCGInstrument;
       
  1380                 else if (_stricmp(str, "pgoptimize"))
       
  1381                     LinkTimeCodeGeneration = optLTCGOptimize;
       
  1382                 else if (_stricmp(str, "pgupdate"))
       
  1383                     LinkTimeCodeGeneration = optLTCGUpdate;
       
  1384 #endif
       
  1385             }
       
  1386         } else {
       
  1387             AdditionalOptions.append(option);
       
  1388         }
       
  1389         break;
       
  1390 	case 0x379ED25:
       
  1391     case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE}
       
  1392         switch (elfHash(option+9)) {
       
  1393         // Very limited documentation on all options but X86,
       
  1394         case 0x0005bb6: // X86
       
  1395             TargetMachine = machineX86;
       
  1396             break;
       
  1397         // so we put the others in AdditionalOptions...
       
  1398         case 0x0005b94: // X64
       
  1399         case 0x0046063: // AM33
       
  1400         case 0x000466d: // ARM
       
  1401         case 0x0004795: // CEE
       
  1402         case 0x0004963: // EBC
       
  1403         case 0x004d494: // IA64
       
  1404         case 0x0050672: // M32R
       
  1405         case 0x0051e53: // MIPS
       
  1406         case 0x51e5646: // MIPS16
       
  1407         case 0x1e57b05: // MIPSFPU
       
  1408         case 0x57b09a6: // MIPSFPU16
       
  1409         case 0x5852738: // MIPSR41XX
       
  1410         case 0x0005543: // PPC
       
  1411         case 0x00057b3: // SH3
       
  1412         case 0x57b7980: // SH3DSP
       
  1413         case 0x00057b4: // SH4
       
  1414         case 0x00057b5: // SH5
       
  1415         case 0x058da12: // THUMB
       
  1416         case 0x96d8435: // TRICORE
       
  1417         default:
       
  1418             AdditionalOptions += option;
       
  1419             break;
       
  1420         }
       
  1421         break;
       
  1422     case 0x0034160: // /MAP[:filename]
       
  1423         GenerateMapFile = _True;
       
  1424         MapFileName = option+5;
       
  1425         break;
       
  1426     case 0x164e1ef: // /MAPINFO:{EXPORTS|LINES}
       
  1427         if(*(option+9) == 'E')
       
  1428             MapExports = _True;
       
  1429         else if(*(option+9) == 'L')
       
  1430             MapLines = _True;
       
  1431         break;
       
  1432     case 0x341a6b5: // /MERGE:from=to
       
  1433         MergeSections = option+7;
       
  1434         break;
       
  1435     case 0x0341d8c: // /MIDL:@file
       
  1436         MidlCommandFile = option+7;
       
  1437         break;
       
  1438     case 0x84e2679: // /NOASSEMBLY
       
  1439         TurnOffAssemblyGeneration = _True;
       
  1440         break;
       
  1441     case 0x2b21942: // /NODEFAULTLIB[:library]
       
  1442         if(*(option+13) == '\0')
       
  1443             IgnoreAllDefaultLibraries = _True;
       
  1444         else
       
  1445             IgnoreDefaultLibraryNames += option+14;
       
  1446         break;
       
  1447     case 0x33a3a39: // /NOENTRY
       
  1448         ResourceOnlyDLL = _True;
       
  1449         break;
       
  1450     case 0x434138f: // /NOLOGO
       
  1451         SuppressStartupBanner = _True;
       
  1452         break;
       
  1453     case 0x0034454: // /OPT:{REF | NOREF | ICF[=iterations] | NOICF | WIN98 | NOWIN98}
       
  1454         {
       
  1455             char third = *(option+7);
       
  1456             switch (third) {
       
  1457             case 'F': // REF
       
  1458                 if(*(option+5) == 'R') {
       
  1459                     OptimizeReferences = optReferences;
       
  1460                 } else { // ICF[=iterations]
       
  1461                     EnableCOMDATFolding = optFolding;
       
  1462                     // [=iterations] case is not documented
       
  1463                 }
       
  1464                 break;
       
  1465             case 'R': // NOREF
       
  1466                 OptimizeReferences = optNoReferences;
       
  1467                 break;
       
  1468             case 'I': // NOICF
       
  1469                 EnableCOMDATFolding = optNoFolding;
       
  1470                 break;
       
  1471             case 'N': // WIN98
       
  1472                 OptimizeForWindows98 = optWin98Yes;
       
  1473                 break;
       
  1474             case 'W': // NOWIN98
       
  1475                 OptimizeForWindows98 = optWin98No;
       
  1476                 break;
       
  1477             default:
       
  1478                 found = false;
       
  1479             }
       
  1480         }
       
  1481         break;
       
  1482     case 0x34468a2: // /ORDER:@filename
       
  1483         FunctionOrder = option+8;
       
  1484         break;
       
  1485     case 0x00344a4: // /OUT:filename
       
  1486         OutputFile = option+5;
       
  1487         break;
       
  1488     case 0x0034482: // /PDB:filename
       
  1489         ProgramDatabaseFile = option+5;
       
  1490         break;
       
  1491     case 0xa2ad314: // /PDBSTRIPPED:pdb_file_name
       
  1492         StripPrivateSymbols = option+13;
       
  1493         break;
       
  1494     case 0x6a09535: // /RELEASE
       
  1495         SetChecksum = _True;
       
  1496         break;
       
  1497     case 0x348857b: // /STACK:reserve[,commit]
       
  1498         {
       
  1499             QStringList both = QString(option+7).split(",");
       
  1500             StackReserveSize = both[0].toLongLong();
       
  1501             if(both.count() == 2)
       
  1502                 StackCommitSize = both[1].toLongLong();
       
  1503         }
       
  1504         break;
       
  1505     case 0x75AA4D8: // /SAFESH:{NO}
       
  1506         {
       
  1507             AdditionalOptions += option;
       
  1508             break;
       
  1509         }
       
  1510 	case 0x9B3C00D:
       
  1511     case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
       
  1512         {
       
  1513             // Split up in subsystem, and version number
       
  1514             QStringList both = QString(option+11).split(",");
       
  1515             switch (elfHash(both[0].toLatin1())) {
       
  1516             case 0x8438445: // CONSOLE
       
  1517                 SubSystem = subSystemConsole;
       
  1518                 break;
       
  1519             case 0xbe29493: // WINDOWS
       
  1520                 SubSystem = subSystemWindows;
       
  1521                 break;
       
  1522             // The following are undocumented, so add them to AdditionalOptions
       
  1523             case 0x240949e: // EFI_APPLICATION
       
  1524             case 0xe617652: // EFI_BOOT_SERVICE_DRIVER
       
  1525             case 0x9af477d: // EFI_ROM
       
  1526             case 0xd34df42: // EFI_RUNTIME_DRIVER
       
  1527             case 0x5268ea5: // NATIVE
       
  1528             case 0x05547e8: // POSIX
       
  1529             case 0x2949c95: // WINDOWSCE
       
  1530 			case 0x4B69795: // windowsce
       
  1531                 AdditionalOptions += option;
       
  1532                 break;
       
  1533             default:
       
  1534                 found = false;
       
  1535             }
       
  1536         }
       
  1537         break;
       
  1538     case 0x8b654de: // /SWAPRUN:{NET | CD}
       
  1539         if(*(option+9) == 'N')
       
  1540             SwapRunFromNet = _True;
       
  1541         else if(*(option+9) == 'C')
       
  1542             SwapRunFromCD = _True;
       
  1543         else
       
  1544             found = false;
       
  1545         break;
       
  1546     case 0x34906d4: // /TLBID:id
       
  1547         TypeLibraryResourceID = QString(option+7).toLongLong();
       
  1548         break;
       
  1549     case 0x4907494: // /TLBOUT:[path\]filename
       
  1550         TypeLibraryFile = option+8;
       
  1551         break;
       
  1552     case 0x976b525: // /TSAWARE[:NO]
       
  1553         if(*(option+8) == ':')
       
  1554             TerminalServerAware = termSvrAwareNo;
       
  1555         else
       
  1556             TerminalServerAware = termSvrAwareYes;
       
  1557         break;
       
  1558     case 0xaa67735: // /VERBOSE[:lib]
       
  1559         if(*(option+9) == ':') {
       
  1560             ShowProgress = linkProgressLibs;
       
  1561             AdditionalOptions += option;
       
  1562         } else {
       
  1563             ShowProgress = linkProgressAll;
       
  1564         }
       
  1565         break;
       
  1566     case 0xaa77f7e: // /VERSION:major[.minor]
       
  1567         Version = option+9;
       
  1568         break;
       
  1569     default:
       
  1570         AdditionalOptions += option;
       
  1571         break;
       
  1572     }
       
  1573     if(!found) {
       
  1574         warn_msg(WarnLogic, "Could not parse Linker options: %s, added as AdditionalOption", option);
       
  1575         AdditionalOptions += option;
       
  1576     }
       
  1577     return found;
       
  1578 }
       
  1579 
       
  1580 // VCMIDLTool -------------------------------------------------------
       
  1581 VCMIDLTool::VCMIDLTool()
       
  1582     :        DefaultCharType(midlCharUnsigned),
       
  1583         EnableErrorChecks(midlDisableAll),
       
  1584         ErrorCheckAllocations(unset),
       
  1585         ErrorCheckBounds(unset),
       
  1586         ErrorCheckEnumRange(unset),
       
  1587         ErrorCheckRefPointers(unset),
       
  1588         ErrorCheckStubData(unset),
       
  1589         GenerateStublessProxies(unset),
       
  1590         GenerateTypeLibrary(unset),
       
  1591         IgnoreStandardIncludePath(unset),
       
  1592         MkTypLibCompatible(unset),
       
  1593         StructMemberAlignment(midlAlignNotSet),
       
  1594         SuppressStartupBanner(unset),
       
  1595         TargetEnvironment(midlTargetNotSet),
       
  1596         ValidateParameters(unset),
       
  1597         WarnAsError(unset),
       
  1598         WarningLevel(midlWarningLevel_0)
       
  1599 {
       
  1600 }
       
  1601 
       
  1602 XmlOutput &operator<<(XmlOutput &xml, const VCMIDLTool &tool)
       
  1603 {
       
  1604     return xml
       
  1605         << tag(_Tool)
       
  1606             << attrS(_Name, _VCMIDLTool)
       
  1607             << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
       
  1608             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
  1609             << attrX(_CPreprocessOptions, tool.CPreprocessOptions)
       
  1610             << attrE(_DefaultCharType, tool.DefaultCharType)
       
  1611             << attrS(_DLLDataFileName, tool.DLLDataFileName)
       
  1612             << attrE(_EnableErrorChecks, tool.EnableErrorChecks)
       
  1613             << attrT(_ErrorCheckAllocations, tool.ErrorCheckAllocations)
       
  1614             << attrT(_ErrorCheckBounds, tool.ErrorCheckBounds)
       
  1615             << attrT(_ErrorCheckEnumRange, tool.ErrorCheckEnumRange)
       
  1616             << attrT(_ErrorCheckRefPointers, tool.ErrorCheckRefPointers)
       
  1617             << attrT(_ErrorCheckStubData, tool.ErrorCheckStubData)
       
  1618             << attrX(_FullIncludePath, tool.FullIncludePath)
       
  1619             << attrT(_GenerateStublessProxies, tool.GenerateStublessProxies)
       
  1620             << attrT(_GenerateTypeLibrary, tool.GenerateTypeLibrary)
       
  1621             << attrS(_HeaderFileName, tool.HeaderFileName)
       
  1622             << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
       
  1623             << attrS(_InterfaceIdentifierFileName, tool.InterfaceIdentifierFileName)
       
  1624             << attrT(_MkTypLibCompatible, tool.MkTypLibCompatible)
       
  1625             << attrS(_OutputDirectory, tool.OutputDirectory)
       
  1626             << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
       
  1627             << attrS(_ProxyFileName, tool.ProxyFileName)
       
  1628             << attrS(_RedirectOutputAndErrors, tool.RedirectOutputAndErrors)
       
  1629             << attrE(_StructMemberAlignment, tool.StructMemberAlignment, /*ifNot*/ midlAlignNotSet)
       
  1630             << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
       
  1631             << attrE(_TargetEnvironment, tool.TargetEnvironment, /*ifNot*/ midlTargetNotSet)
       
  1632             << attrS(_TypeLibraryName, tool.TypeLibraryName)
       
  1633             << attrX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions)
       
  1634             << attrT(_ValidateParameters, tool.ValidateParameters)
       
  1635             << attrT(_WarnAsError, tool.WarnAsError)
       
  1636             << attrE(_WarningLevel, tool.WarningLevel)
       
  1637         << closetag(_Tool);
       
  1638 }
       
  1639 
       
  1640 bool VCMIDLTool::parseOption(const char* option)
       
  1641 {
       
  1642 #ifdef USE_DISPLAY_HASH
       
  1643     displayHash("/D name[=def]"); displayHash("/I directory-list"); displayHash("/Oi");
       
  1644     displayHash("/Oic"); displayHash("/Oicf"); displayHash("/Oif"); displayHash("/Os");
       
  1645     displayHash("/U name"); displayHash("/WX"); displayHash("/W{0|1|2|3|4}");
       
  1646     displayHash("/Zp {N}"); displayHash("/Zs"); displayHash("/acf filename");
       
  1647     displayHash("/align {N}"); displayHash("/app_config"); displayHash("/c_ext");
       
  1648     displayHash("/char ascii7"); displayHash("/char signed"); displayHash("/char unsigned");
       
  1649     displayHash("/client none"); displayHash("/client stub"); displayHash("/confirm");
       
  1650     displayHash("/cpp_cmd cmd_line"); displayHash("/cpp_opt options");
       
  1651     displayHash("/cstub filename"); displayHash("/dlldata filename"); displayHash("/env win32");
       
  1652     displayHash("/env win64"); displayHash("/error all"); displayHash("/error allocation");
       
  1653     displayHash("/error bounds_check"); displayHash("/error enum"); displayHash("/error none");
       
  1654     displayHash("/error ref"); displayHash("/error stub_data"); displayHash("/h filename");
       
  1655     displayHash("/header filename"); displayHash("/iid filename"); displayHash("/lcid");
       
  1656     displayHash("/mktyplib203"); displayHash("/ms_ext"); displayHash("/ms_union");
       
  1657     displayHash("/msc_ver <nnnn>"); displayHash("/newtlb"); displayHash("/no_cpp");
       
  1658     displayHash("/no_def_idir"); displayHash("/no_default_epv"); displayHash("/no_format_opt");
       
  1659     displayHash("/no_warn"); displayHash("/nocpp"); displayHash("/nologo"); displayHash("/notlb");
       
  1660     displayHash("/o filename"); displayHash("/oldnames"); displayHash("/oldtlb");
       
  1661     displayHash("/osf"); displayHash("/out directory"); displayHash("/pack {N}");
       
  1662     displayHash("/prefix all"); displayHash("/prefix client"); displayHash("/prefix server");
       
  1663     displayHash("/prefix switch"); displayHash("/protocol all"); displayHash("/protocol dce");
       
  1664     displayHash("/protocol ndr64"); displayHash("/proxy filename"); displayHash("/robust");
       
  1665     displayHash("/rpcss"); displayHash("/savePP"); displayHash("/server none");
       
  1666     displayHash("/server stub"); displayHash("/sstub filename"); displayHash("/syntax_check");
       
  1667     displayHash("/target {system}"); displayHash("/tlb filename"); displayHash("/use_epv");
       
  1668     displayHash("/win32"); displayHash("/win64");
       
  1669 #endif
       
  1670     bool found = true;
       
  1671     int offset = 0;
       
  1672     switch(elfHash(option)) {
       
  1673     case 0x0000334: // /D name[=def]
       
  1674         PreprocessorDefinitions += option+3;
       
  1675         break;
       
  1676     case 0x0000339: // /I directory-list
       
  1677         AdditionalIncludeDirectories += option+3;
       
  1678         break;
       
  1679     case 0x0345f96: // /Oicf
       
  1680     case 0x00345f6: // /Oif
       
  1681         GenerateStublessProxies = _True;
       
  1682         break;
       
  1683     case 0x0000345: // /U name
       
  1684         UndefinePreprocessorDefinitions += option+3;
       
  1685         break;
       
  1686     case 0x00034c8: // /WX
       
  1687         WarnAsError = _True;
       
  1688         break;
       
  1689     case 0x3582fde: // /align {N}
       
  1690         offset = 3;  // Fallthrough
       
  1691     case 0x0003510: // /Zp {N}
       
  1692         switch (*(option+offset+4)) {
       
  1693         case '1':
       
  1694             StructMemberAlignment = (*(option+offset+5) == '\0') ? midlAlignSingleByte : midlAlignSixteenBytes;
       
  1695             break;
       
  1696         case '2':
       
  1697             StructMemberAlignment = midlAlignTwoBytes;
       
  1698             break;
       
  1699         case '4':
       
  1700             StructMemberAlignment = midlAlignFourBytes;
       
  1701             break;
       
  1702         case '8':
       
  1703             StructMemberAlignment = midlAlignEightBytes;
       
  1704             break;
       
  1705         default:
       
  1706             found = false;
       
  1707         }
       
  1708         break;
       
  1709     case 0x0359e82: // /char {ascii7|signed|unsigned}
       
  1710         switch(*(option+6)) {
       
  1711         case 'a':
       
  1712             DefaultCharType = midlCharAscii7;
       
  1713             break;
       
  1714         case 's':
       
  1715             DefaultCharType = midlCharSigned;
       
  1716             break;
       
  1717         case 'u':
       
  1718             DefaultCharType = midlCharUnsigned;
       
  1719             break;
       
  1720         default:
       
  1721             found = false;
       
  1722         }
       
  1723         break;
       
  1724     case 0xa766524: // /cpp_opt options
       
  1725         CPreprocessOptions += option+9;
       
  1726         break;
       
  1727     case 0xb32abf1: // /dlldata filename
       
  1728         DLLDataFileName = option + 9;
       
  1729         break;
       
  1730     case 0x0035c56: // /env {win32|win64}
       
  1731         TargetEnvironment = (*(option+8) == '6') ? midlTargetWin64 : midlTargetWin32;
       
  1732         break;
       
  1733     case 0x35c9962: // /error {all|allocation|bounds_check|enum|none|ref|stub_data}
       
  1734         EnableErrorChecks = midlEnableCustom;
       
  1735         switch (*(option+7)) {
       
  1736         case 'a':
       
  1737             if(*(option+10) == '\0')
       
  1738                 EnableErrorChecks = midlEnableAll;
       
  1739             else
       
  1740                 ErrorCheckAllocations = _True;
       
  1741             break;
       
  1742         case 'b':
       
  1743             ErrorCheckBounds = _True;
       
  1744             break;
       
  1745         case 'e':
       
  1746             ErrorCheckEnumRange = _True;
       
  1747             break;
       
  1748         case 'n':
       
  1749             EnableErrorChecks = midlDisableAll;
       
  1750             break;
       
  1751         case 'r':
       
  1752             ErrorCheckRefPointers = _True;
       
  1753             break;
       
  1754         case 's':
       
  1755             ErrorCheckStubData = _True;
       
  1756             break;
       
  1757         default:
       
  1758             found = false;
       
  1759         }
       
  1760         break;
       
  1761     case 0x5eb7af2: // /header filename
       
  1762         offset = 5;
       
  1763     case 0x0000358: // /h filename
       
  1764         HeaderFileName = option + offset + 3;
       
  1765         break;
       
  1766     case 0x0035ff4: // /iid filename
       
  1767         InterfaceIdentifierFileName = option+5;
       
  1768         break;
       
  1769     case 0x64b7933: // /mktyplib203
       
  1770         MkTypLibCompatible = _True;
       
  1771         break;
       
  1772     case 0x8e0b0a2: // /no_def_idir
       
  1773         IgnoreStandardIncludePath = _True;
       
  1774         break;
       
  1775     case 0x65635ef: // /nologo
       
  1776         SuppressStartupBanner = _True;
       
  1777         break;
       
  1778     case 0x3656b22: // /notlb
       
  1779         GenerateTypeLibrary = _True;
       
  1780         break;
       
  1781     case 0x000035f: // /o filename
       
  1782         RedirectOutputAndErrors = option+3;
       
  1783         break;
       
  1784     case 0x00366c4: // /out directory
       
  1785         OutputDirectory = option+5;
       
  1786         break;
       
  1787     case 0x36796f9: // /proxy filename
       
  1788         ProxyFileName = option+7;
       
  1789         break;
       
  1790     case 0x6959c94: // /robust
       
  1791         ValidateParameters = _True;
       
  1792         break;
       
  1793     case 0x6a88df4: // /target {system}
       
  1794         if(*(option+11) == '6')
       
  1795             TargetEnvironment = midlTargetWin64;
       
  1796         else
       
  1797             TargetEnvironment = midlTargetWin32;
       
  1798         break;
       
  1799     case 0x0036b22: // /tlb filename
       
  1800         TypeLibraryName = option+5;
       
  1801         break;
       
  1802     case 0x36e0162: // /win32
       
  1803         TargetEnvironment = midlTargetWin32;
       
  1804         break;
       
  1805     case 0x36e0194: // /win64
       
  1806         TargetEnvironment = midlTargetWin64;
       
  1807         break;
       
  1808     case 0x0003459: // /Oi
       
  1809     case 0x00345f3: // /Oic
       
  1810     case 0x0003463: // /Os
       
  1811     case 0x0003513: // /Zs
       
  1812     case 0x0035796: // /acf filename
       
  1813     case 0x5b1cb97: // /app_config
       
  1814     case 0x3595cf4: // /c_ext
       
  1815     case 0x5a2fc64: // /client {none|stub}
       
  1816     case 0xa64d3dd: // /confirm
       
  1817     case 0xa765b64: // /cpp_cmd cmd_line
       
  1818     case 0x35aabb2: // /cstub filename
       
  1819     case 0x03629f4: // /lcid
       
  1820     case 0x6495cc4: // /ms_ext
       
  1821     case 0x96c7a1e: // /ms_union
       
  1822     case 0x4996fa2: // /msc_ver <nnnn>
       
  1823     case 0x64ceb12: // /newtlb
       
  1824     case 0x6555a40: // /no_cpp
       
  1825     case 0xf64d6a6: // /no_default_epv
       
  1826     case 0x6dd9384: // /no_format_opt
       
  1827     case 0x556dbee: // /no_warn
       
  1828     case 0x3655a70: // /nocpp
       
  1829     case 0x2b455a3: // /oldnames
       
  1830     case 0x662bb12: // /oldtlb
       
  1831     case 0x0036696: // /osf
       
  1832     case 0x036679b: // /pack {N}
       
  1833     case 0x678bd38: // /prefix {all|client|server|switch}
       
  1834     case 0x96b702c: // /protocol {all|dce|ndr64}
       
  1835     case 0x3696aa3: // /rpcss
       
  1836     case 0x698ca60: // /savePP
       
  1837     case 0x69c9cf2: // /server {none|stub}
       
  1838     case 0x36aabb2: // /sstub filename
       
  1839     case 0xce9b12b: // /syntax_check
       
  1840     case 0xc9b5f16: // /use_epv
       
  1841         AdditionalOptions += option;
       
  1842         break;
       
  1843     default:
       
  1844         // /W{0|1|2|3|4} case
       
  1845         if(*(option+1) == 'W') {
       
  1846             switch (*(option+2)) {
       
  1847             case '0':
       
  1848                 WarningLevel = midlWarningLevel_0;
       
  1849                 break;
       
  1850             case '1':
       
  1851                 WarningLevel = midlWarningLevel_1;
       
  1852                 break;
       
  1853             case '2':
       
  1854                 WarningLevel = midlWarningLevel_2;
       
  1855                 break;
       
  1856             case '3':
       
  1857                 WarningLevel = midlWarningLevel_3;
       
  1858                 break;
       
  1859             case '4':
       
  1860                 WarningLevel = midlWarningLevel_4;
       
  1861                 break;
       
  1862             default:
       
  1863                 found = false;
       
  1864             }
       
  1865         }
       
  1866         break;
       
  1867     }
       
  1868     if(!found)
       
  1869         warn_msg(WarnLogic, "Could not parse MIDL option: %s", option);
       
  1870     return true;
       
  1871 }
       
  1872 
       
  1873 // VCLibrarianTool --------------------------------------------------
       
  1874 VCLibrarianTool::VCLibrarianTool()
       
  1875     :        IgnoreAllDefaultLibraries(unset),
       
  1876         SuppressStartupBanner(_True)
       
  1877 {
       
  1878 }
       
  1879 
       
  1880 XmlOutput &operator<<(XmlOutput &xml, const VCLibrarianTool &tool)
       
  1881 {
       
  1882     return xml
       
  1883         << tag(_Tool)
       
  1884             << attrS(_Name, _VCLibrarianTool)
       
  1885             << attrX(_AdditionalDependencies, tool.AdditionalDependencies)
       
  1886             << attrX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories)
       
  1887             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
  1888             << attrX(_ExportNamedFunctions, tool.ExportNamedFunctions)
       
  1889             << attrX(_ForceSymbolReferences, tool.ForceSymbolReferences)
       
  1890             << attrT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
       
  1891             << attrX(_IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames)
       
  1892             << attrS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
       
  1893             << attrS(_OutputFile, tool.OutputFile)
       
  1894             << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
       
  1895         << closetag(_Tool);
       
  1896 }
       
  1897 
       
  1898 // VCCustomBuildTool ------------------------------------------------
       
  1899 VCCustomBuildTool::VCCustomBuildTool()
       
  1900 {
       
  1901     ToolName = "VCCustomBuildTool";
       
  1902 }
       
  1903 
       
  1904 XmlOutput &operator<<(XmlOutput &xml, const VCCustomBuildTool &tool)
       
  1905 {
       
  1906     // The code below offers two ways to split custom build step commands.
       
  1907     // Normally the $$escape_expand(\n\t) is used in a project file, which is correctly translated
       
  1908     // in all generators. However, if you use $$escape_expand(\n\r) (or \n\h) instead, the VCPROJ
       
  1909     // generator will instead of binding the commands with " && " will insert a proper newline into
       
  1910     // the VCPROJ file. We sometimes use this method of splitting commands if the custom buildstep
       
  1911     // contains a command-line which is too big to run on certain OS.
       
  1912     QString cmds;
       
  1913     int end = tool.CommandLine.count();
       
  1914     for(int i = 0; i < end; ++i) {
       
  1915         QString cmdl = tool.CommandLine.at(i);
       
  1916         if (cmdl.contains("\r\t")) {
       
  1917             if (i == end - 1)
       
  1918                 cmdl = cmdl.trimmed();
       
  1919             cmdl.replace("\r\t", " && ");
       
  1920         } else if (cmdl.contains("\r\n")) {
       
  1921             ;
       
  1922         } else if (cmdl.contains("\r\\h")) {
       
  1923             // The above \r\n should work, but doesn't, so we have this hack
       
  1924             cmdl.replace("\r\\h", "\r\n");
       
  1925         } else {
       
  1926             if (i < end - 1)
       
  1927                 cmdl += " && ";
       
  1928         }
       
  1929         cmds += cmdl;
       
  1930     }
       
  1931     return xml
       
  1932         << tag(_Tool)
       
  1933             << attrS(_Name, tool.ToolName)
       
  1934             << attrX(_AdditionalDependencies, tool.AdditionalDependencies, ";")
       
  1935             << attrS(_CommandLine, cmds)
       
  1936             << attrS(_Description, tool.Description)
       
  1937             << attrX(_Outputs, tool.Outputs, ";")
       
  1938             << attrS(_Path, tool.ToolPath)
       
  1939         << closetag(_Tool);
       
  1940 }
       
  1941 
       
  1942 // VCResourceCompilerTool -------------------------------------------
       
  1943 VCResourceCompilerTool::VCResourceCompilerTool()
       
  1944     :   Culture(rcUseDefault),
       
  1945         IgnoreStandardIncludePath(unset),
       
  1946         ShowProgress(linkProgressNotSet)
       
  1947 {
       
  1948     PreprocessorDefinitions = QStringList("NDEBUG");
       
  1949 }
       
  1950 
       
  1951 XmlOutput &operator<<(XmlOutput &xml, const VCResourceCompilerTool &tool)
       
  1952 {
       
  1953     return xml
       
  1954         << tag(_Tool)
       
  1955             << attrS(_Name, _VCResourceCompilerTool)
       
  1956             << attrS(_Path, tool.ToolPath)
       
  1957             << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
       
  1958             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
  1959             << attrE(_Culture, tool.Culture, /*ifNot*/ rcUseDefault)
       
  1960             << attrX(_FullIncludePath, tool.FullIncludePath)
       
  1961             << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
       
  1962             << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
       
  1963             << attrS(_ResourceOutputFileName, tool.ResourceOutputFileName)
       
  1964             << attrE(_ShowProgress, tool.ShowProgress, /*ifNot*/ linkProgressNotSet)
       
  1965         << closetag(_Tool);
       
  1966 }
       
  1967 
       
  1968 // VCDeploymentTool --------------------------------------------
       
  1969 VCDeploymentTool::VCDeploymentTool()
       
  1970     :   RegisterOutput(registerNo)
       
  1971 {
       
  1972     DeploymentTag = "DeploymentTool";
       
  1973     RemoteDirectory = "";
       
  1974 }
       
  1975 
       
  1976 XmlOutput &operator<<(XmlOutput &xml, const VCDeploymentTool &tool)
       
  1977 {
       
  1978     if (tool.AdditionalFiles.isEmpty())
       
  1979         return xml;
       
  1980     return xml
       
  1981         << tag(tool.DeploymentTag)
       
  1982         << attrS(_RemoteDirectory, tool.RemoteDirectory)
       
  1983         << attrE(_RegisterOutput, tool.RegisterOutput)
       
  1984         << attrS(_AdditionalFiles, tool.AdditionalFiles)
       
  1985         << closetag(tool.DeploymentTag);
       
  1986 }
       
  1987 
       
  1988 // VCEventTool -------------------------------------------------
       
  1989 XmlOutput &operator<<(XmlOutput &xml, const VCEventTool &tool)
       
  1990 {
       
  1991     return xml
       
  1992         << tag(_Tool)
       
  1993             << attrS(_Name, tool.ToolName)
       
  1994             << attrS(_Path, tool.ToolPath)
       
  1995             << attrS(_CommandLine, tool.CommandLine)
       
  1996             << attrS(_Description, tool.Description)
       
  1997             << attrT(_ExcludedFromBuild, tool.ExcludedFromBuild)
       
  1998         << closetag(_Tool);
       
  1999 }
       
  2000 
       
  2001 // VCPostBuildEventTool ---------------------------------------------
       
  2002 VCPostBuildEventTool::VCPostBuildEventTool()
       
  2003 {
       
  2004     ToolName = "VCPostBuildEventTool";
       
  2005 }
       
  2006 
       
  2007 // VCPreBuildEventTool ----------------------------------------------
       
  2008 VCPreBuildEventTool::VCPreBuildEventTool()
       
  2009 {
       
  2010     ToolName = "VCPreBuildEventTool";
       
  2011 }
       
  2012 
       
  2013 // VCPreLinkEventTool -----------------------------------------------
       
  2014 VCPreLinkEventTool::VCPreLinkEventTool()
       
  2015 {
       
  2016     ToolName = "VCPreLinkEventTool";
       
  2017 }
       
  2018 
       
  2019 // VCConfiguration --------------------------------------------------
       
  2020 
       
  2021 VCConfiguration::VCConfiguration()
       
  2022     :        ATLMinimizesCRunTimeLibraryUsage(unset),
       
  2023         BuildBrowserInformation(unset),
       
  2024         CharacterSet(charSetNotSet),
       
  2025         ConfigurationType(typeApplication),
       
  2026         RegisterOutput(unset),
       
  2027         UseOfATL(useATLNotSet),
       
  2028         UseOfMfc(useMfcStdWin),
       
  2029         WholeProgramOptimization(unset)
       
  2030 {
       
  2031     compiler.config = this;
       
  2032     linker.config = this;
       
  2033     idl.config = this;
       
  2034 }
       
  2035 
       
  2036 XmlOutput &operator<<(XmlOutput &xml, const VCConfiguration &tool)
       
  2037 {
       
  2038     xml << tag(_Configuration)
       
  2039             << attrS(_Name, tool.Name)
       
  2040             << attrS(_OutputDirectory, tool.OutputDirectory)
       
  2041             << attrT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage)
       
  2042             << attrT(_BuildBrowserInformation, tool.BuildBrowserInformation)
       
  2043             << attrE(_CharacterSet, tool.CharacterSet, /*ifNot*/ charSetNotSet)
       
  2044             << attrE(_ConfigurationType, tool.ConfigurationType)
       
  2045             << attrS(_DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean)
       
  2046             << attrS(_ImportLibrary, tool.ImportLibrary)
       
  2047             << attrS(_IntermediateDirectory, tool.IntermediateDirectory)
       
  2048             << attrS(_PrimaryOutput, tool.PrimaryOutput)
       
  2049             << attrS(_ProgramDatabase, tool.ProgramDatabase)
       
  2050             << attrT(_RegisterOutput, tool.RegisterOutput)
       
  2051             << attrE(_UseOfATL, tool.UseOfATL, /*ifNot*/ useATLNotSet)
       
  2052             << attrE(_UseOfMfc, tool.UseOfMfc)
       
  2053             << attrT(_WholeProgramOptimization, tool.WholeProgramOptimization)
       
  2054             << tool.compiler
       
  2055             << tool.custom;
       
  2056     if (tool.ConfigurationType == typeStaticLibrary)
       
  2057         xml << tool.librarian;
       
  2058     else
       
  2059         xml << tool.linker;
       
  2060     xml     << tool.idl
       
  2061             << tool.postBuild
       
  2062             << tool.preBuild
       
  2063             << tool.preLink
       
  2064             << tool.resource
       
  2065             << tool.deployment
       
  2066         << closetag(_Configuration);
       
  2067     return xml;
       
  2068 }
       
  2069 // VCFilter ---------------------------------------------------------
       
  2070 VCFilter::VCFilter()
       
  2071     :   ParseFiles(unset),
       
  2072         Config(0)
       
  2073 {
       
  2074     useCustomBuildTool = false;
       
  2075     useCompilerTool = false;
       
  2076 }
       
  2077 
       
  2078 void VCFilter::addFile(const QString& filename)
       
  2079 {
       
  2080     Files += VCFilterFile(filename);
       
  2081 }
       
  2082 
       
  2083 void VCFilter::addFile(const VCFilterFile& fileInfo)
       
  2084 {
       
  2085     Files += VCFilterFile(fileInfo);
       
  2086 }
       
  2087 
       
  2088 void VCFilter::addFiles(const QStringList& fileList)
       
  2089 {
       
  2090     for (int i = 0; i < fileList.count(); ++i)
       
  2091         addFile(fileList.at(i));
       
  2092 }
       
  2093 
       
  2094 void VCFilter::modifyPCHstage(QString str)
       
  2095 {
       
  2096     bool autogenSourceFile = Project->autogenPrecompCPP;
       
  2097     bool pchThroughSourceFile = !Project->precompCPP.isEmpty();
       
  2098     bool isCFile = false;
       
  2099     for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) {
       
  2100         if (str.endsWith(*it)) {
       
  2101             isCFile = true;
       
  2102             break;
       
  2103         }
       
  2104     }
       
  2105     bool isHFile = str.endsWith(".h") && (str == Project->precompH);
       
  2106     bool isCPPFile = pchThroughSourceFile && (str == Project->precompCPP);
       
  2107 
       
  2108     if(!isCFile && !isHFile && !isCPPFile)
       
  2109         return;
       
  2110 
       
  2111     if(isHFile && pchThroughSourceFile) {
       
  2112         if (autogenSourceFile) {
       
  2113             useCustomBuildTool = true;
       
  2114             QString toFile(Project->precompCPP);
       
  2115             CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ...";
       
  2116             CustomBuildTool.Outputs += toFile;
       
  2117 
       
  2118             QStringList lines;
       
  2119             CustomBuildTool.CommandLine +=
       
  2120                 "echo /*-------------------------------------------------------------------- >" + toFile;
       
  2121             lines << "* Precompiled header source file used by Visual Studio.NET to generate";
       
  2122             lines << "* the .pch file.";
       
  2123             lines << "*";
       
  2124             lines << "* Due to issues with the dependencies checker within the IDE, it";
       
  2125             lines << "* sometimes fails to recompile the PCH file, if we force the IDE to";
       
  2126             lines << "* create the PCH file directly from the header file.";
       
  2127             lines << "*";
       
  2128             lines << "* This file is auto-generated by qmake since no PRECOMPILED_SOURCE was";
       
  2129             lines << "* specified, and is used as the common stdafx.cpp. The file is only";
       
  2130             lines << "* generated when creating .vcproj project files, and is not used for";
       
  2131             lines << "* command line compilations by nmake.";
       
  2132             lines << "*";
       
  2133             lines << "* WARNING: All changes made in this file will be lost.";
       
  2134             lines << "--------------------------------------------------------------------*/";
       
  2135             lines << "#include \"" + Project->precompHFilename + "\"";
       
  2136             foreach(QString line, lines)
       
  2137                 CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile;
       
  2138         }
       
  2139         return;
       
  2140     }
       
  2141 
       
  2142     useCompilerTool = true;
       
  2143     // Setup PCH options
       
  2144     CompilerTool.UsePrecompiledHeader     = (isCFile ? pchNone : pchCreateUsingSpecific);
       
  2145     CompilerTool.PrecompiledHeaderThrough = (isCPPFile ? QString("$(INHERIT)") : QString("$(NOINHERIT)"));
       
  2146     CompilerTool.ForcedIncludeFiles       = QStringList("$(NOINHERIT)");
       
  2147 }
       
  2148 
       
  2149 bool VCFilter::addExtraCompiler(const VCFilterFile &info)
       
  2150 {
       
  2151     const QStringList &extraCompilers = Project->extraCompilerSources.value(info.file);
       
  2152     if (extraCompilers.isEmpty())
       
  2153         return false;
       
  2154 
       
  2155     QString inFile = info.file;
       
  2156 
       
  2157     // is the extracompiler rule on a file with a built in compiler?
       
  2158     const QStringList &objectMappedFile = Project->extraCompilerOutputs[inFile];
       
  2159     bool hasBuiltIn = false;
       
  2160     if (!objectMappedFile.isEmpty()) {
       
  2161         hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile.at(0));
       
  2162 //        qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(" ")));
       
  2163     }
       
  2164 
       
  2165     CustomBuildTool.AdditionalDependencies.clear();
       
  2166     CustomBuildTool.CommandLine.clear();
       
  2167     CustomBuildTool.Description.clear();
       
  2168     CustomBuildTool.Outputs.clear();
       
  2169     CustomBuildTool.ToolPath.clear();
       
  2170 	CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
       
  2171 
       
  2172     for (int x = 0; x < extraCompilers.count(); ++x) {
       
  2173         const QString &extraCompilerName = extraCompilers.at(x);
       
  2174 
       
  2175         if (!Project->verifyExtraCompiler(extraCompilerName, inFile) && !hasBuiltIn)
       
  2176             continue;
       
  2177 
       
  2178         // All information about the extra compiler
       
  2179         QString tmp_out = Project->project->first(extraCompilerName + ".output");
       
  2180         QString tmp_cmd = Project->project->variables()[extraCompilerName + ".commands"].join(" ");
       
  2181         QString tmp_cmd_name = Project->project->variables()[extraCompilerName + ".name"].join(" ");
       
  2182         QStringList tmp_dep = Project->project->variables()[extraCompilerName + ".depends"];
       
  2183         QString tmp_dep_cmd = Project->project->variables()[extraCompilerName + ".depend_command"].join(" ");
       
  2184         QStringList vars = Project->project->variables()[extraCompilerName + ".variables"];
       
  2185         QStringList configs = Project->project->variables()[extraCompilerName + ".CONFIG"];
       
  2186         bool combined = configs.indexOf("combine") != -1;
       
  2187 
       
  2188         QString cmd, cmd_name, out;
       
  2189         QStringList deps, inputs;
       
  2190         // Variabel replacement of output name
       
  2191         out = Option::fixPathToTargetOS(
       
  2192                     Project->replaceExtraCompilerVariables(tmp_out, inFile, QString()),
       
  2193                     false);
       
  2194 
       
  2195         // If file has built-in compiler, we've swapped the input and output of
       
  2196         // the command, as we in Visual Studio cannot have a Custom Buildstep on
       
  2197         // a file which uses a built-in compiler. We would in this case only get
       
  2198         // the result from the extra compiler. If 'hasBuiltIn' is true, we know
       
  2199         // that we're actually on the _output_file_ of the result, and we
       
  2200         // therefore swap inFile and out below, since the extra-compiler still
       
  2201         // must see it as the original way. If the result also has a built-in
       
  2202         // compiler, too bad..
       
  2203         if (hasBuiltIn) {
       
  2204             out = inFile;
       
  2205             inFile = objectMappedFile.at(0);
       
  2206         }
       
  2207 
       
  2208         // Dependency for the output
       
  2209         if(!tmp_dep.isEmpty())
       
  2210 	    deps = tmp_dep;
       
  2211 	if(!tmp_dep_cmd.isEmpty()) {
       
  2212             // Execute dependency command, and add every line as a dep
       
  2213 	    char buff[256];
       
  2214 	    QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd,
       
  2215 							             Option::fixPathToLocalOS(inFile, true, false),
       
  2216                                                                      out);
       
  2217             if(Project->canExecute(dep_cmd)) {
       
  2218                 if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) {
       
  2219                     QString indeps;
       
  2220                     while(!feof(proc)) {
       
  2221                         int read_in = (int)fread(buff, 1, 255, proc);
       
  2222                         if(!read_in)
       
  2223                             break;
       
  2224                         indeps += QByteArray(buff, read_in);
       
  2225                     }
       
  2226                     QT_PCLOSE(proc);
       
  2227                     if(!indeps.isEmpty()) {
       
  2228                         QStringList extradeps = indeps.split(QLatin1Char('\n'));
       
  2229                         for (int i = 0; i < extradeps.count(); ++i) {
       
  2230                             QString dd = extradeps.at(i).simplified();
       
  2231                             if (!dd.isEmpty())
       
  2232                                 deps += Project->fileFixify(dd);
       
  2233                         }
       
  2234                     }
       
  2235                 }
       
  2236             }
       
  2237         }
       
  2238         for (int i = 0; i < deps.count(); ++i)
       
  2239 	    deps[i] = Option::fixPathToTargetOS(
       
  2240                         Project->replaceExtraCompilerVariables(deps.at(i), inFile, out),
       
  2241                         false).trimmed();
       
  2242         // Command for file
       
  2243         if (combined) {
       
  2244             // Add dependencies for each file
       
  2245             QStringList tmp_in = Project->project->variables()[extraCompilerName + ".input"];
       
  2246             for (int a = 0; a < tmp_in.count(); ++a) {
       
  2247                 const QStringList &files = Project->project->variables()[tmp_in.at(a)];
       
  2248                 for (int b = 0; b < files.count(); ++b) {
       
  2249                     deps += Project->findDependencies(files.at(b));
       
  2250                     inputs += Option::fixPathToTargetOS(files.at(b), false);
       
  2251                 }
       
  2252             }
       
  2253             deps += inputs; // input files themselves too..
       
  2254 
       
  2255             // Replace variables for command w/all input files
       
  2256             // ### join gives path issues with directories containing spaces!
       
  2257             cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
       
  2258                                                          inputs.join(" "),
       
  2259                                                          out);
       
  2260         } else {
       
  2261             deps += inFile; // input file itself too..
       
  2262             cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
       
  2263                                                          inFile,
       
  2264                                                          out);
       
  2265         }
       
  2266         // Name for command
       
  2267 	if(!tmp_cmd_name.isEmpty()) {
       
  2268 	    cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out);
       
  2269 	} else {
       
  2270 	    int space = cmd.indexOf(' ');
       
  2271 	    if(space != -1)
       
  2272 		cmd_name = cmd.left(space);
       
  2273 	    else
       
  2274 		cmd_name = cmd;
       
  2275 	    if((cmd_name[0] == '\'' || cmd_name[0] == '"') &&
       
  2276 		cmd_name[0] == cmd_name[cmd_name.length()-1])
       
  2277 		cmd_name = cmd_name.mid(1,cmd_name.length()-2);
       
  2278 	}
       
  2279 
       
  2280         // Fixify paths
       
  2281         for (int i = 0; i < deps.count(); ++i)
       
  2282             deps[i] = Option::fixPathToTargetOS(deps[i], false);
       
  2283 
       
  2284 
       
  2285         // Output in info.additionalFile -----------
       
  2286         if (!CustomBuildTool.Description.isEmpty())
       
  2287             CustomBuildTool.Description += " & ";
       
  2288         CustomBuildTool.Description += cmd_name;
       
  2289         CustomBuildTool.CommandLine += cmd.trimmed().split("\n", QString::SkipEmptyParts);
       
  2290         int space = cmd.indexOf(' ');
       
  2291         QFileInfo finf(cmd.left(space));
       
  2292         if (CustomBuildTool.ToolPath.isEmpty())
       
  2293             CustomBuildTool.ToolPath += Option::fixPathToTargetOS(finf.path());
       
  2294         CustomBuildTool.Outputs += out;
       
  2295 
       
  2296         deps += CustomBuildTool.AdditionalDependencies;
       
  2297         deps += cmd.left(cmd.indexOf(' '));
       
  2298         // Make sure that all deps are only once
       
  2299         QMap<QString, bool> uniqDeps;
       
  2300         for (int c = 0; c < deps.count(); ++c) {
       
  2301             QString aDep = deps.at(c).trimmed();
       
  2302             if (!aDep.isEmpty())
       
  2303                 uniqDeps[aDep] = false;
       
  2304         }
       
  2305         CustomBuildTool.AdditionalDependencies = uniqDeps.keys();
       
  2306     }
       
  2307 
       
  2308     // Ensure that none of the output files are also dependencies. Or else, the custom buildstep
       
  2309     // will be rebuild every time, even if nothing has changed.
       
  2310     foreach(QString output, CustomBuildTool.Outputs) {
       
  2311         CustomBuildTool.AdditionalDependencies.removeAll(output);
       
  2312     }
       
  2313 
       
  2314     useCustomBuildTool = !CustomBuildTool.CommandLine.isEmpty();
       
  2315     return useCustomBuildTool;
       
  2316 }
       
  2317 
       
  2318 void VCFilter::outputFileConfig(XmlOutput &xml, const QString &filename)
       
  2319 {
       
  2320     // Clearing each filter tool
       
  2321     useCustomBuildTool = false;
       
  2322     useCompilerTool = false;
       
  2323     CustomBuildTool = VCCustomBuildTool();
       
  2324     CompilerTool = VCCLCompilerTool();
       
  2325 
       
  2326     // Unset some default options
       
  2327     CompilerTool.BufferSecurityCheck = unset;
       
  2328     CompilerTool.DebugInformationFormat = debugUnknown;
       
  2329     CompilerTool.ExceptionHandling = ehDefault;
       
  2330     CompilerTool.GeneratePreprocessedFile = preprocessUnknown;
       
  2331     CompilerTool.Optimization = optimizeDefault;
       
  2332     CompilerTool.ProgramDataBaseFileName.clear();
       
  2333     CompilerTool.RuntimeLibrary = rtUnknown;
       
  2334     CompilerTool.WarningLevel = warningLevelUnknown;
       
  2335     CompilerTool.config = Config;
       
  2336 
       
  2337     bool inBuild = false;
       
  2338     VCFilterFile info;
       
  2339     for (int i = 0; i < Files.count(); ++i) {
       
  2340         if (Files.at(i).file == filename) {
       
  2341             info = Files.at(i);
       
  2342             inBuild = true;
       
  2343         }
       
  2344     }
       
  2345     inBuild &= !info.excludeFromBuild;
       
  2346 
       
  2347     if (inBuild) {
       
  2348         addExtraCompiler(info);
       
  2349         if(Project->usePCH)
       
  2350             modifyPCHstage(info.file);
       
  2351     } else {
       
  2352         // Excluded files uses an empty compiler stage
       
  2353         if(info.excludeFromBuild)
       
  2354             useCompilerTool = true;
       
  2355     }
       
  2356 
       
  2357     // Actual XML output ----------------------------------
       
  2358     if(useCustomBuildTool || useCompilerTool || !inBuild) {
       
  2359         xml << tag(_FileConfiguration)
       
  2360                 << attr(_Name, (*Config).Name)
       
  2361                 << (!inBuild ? attrS(_ExcludedFromBuild, "true") : noxml());
       
  2362         if (useCustomBuildTool)
       
  2363             xml << CustomBuildTool;
       
  2364         if (useCompilerTool)
       
  2365             xml << CompilerTool;
       
  2366         xml << closetag(_FileConfiguration);
       
  2367     }
       
  2368 }
       
  2369 
       
  2370 XmlOutput &operator<<(XmlOutput &xml, VCFilter &tool)
       
  2371 {
       
  2372     if(!tool.Files.count())
       
  2373         return xml;
       
  2374 
       
  2375     if (!tool.Name.isEmpty()) {
       
  2376         xml << tag(_Filter)
       
  2377                 << attrS(_Name, tool.Name)
       
  2378                 << attrS(_Filter, tool.Filter)
       
  2379                 << attrS(_UniqueIdentifier, tool.Guid)
       
  2380                 << attrT(_ParseFiles, tool.ParseFiles);
       
  2381     }
       
  2382     for (int i = 0; i < tool.Files.count(); ++i) {
       
  2383         const VCFilterFile &info = tool.Files.at(i);
       
  2384         xml << tag(q_File)
       
  2385                 << attrS(_RelativePath, Option::fixPathToLocalOS(info.file))
       
  2386             << data(); // In case no custom builds, to avoid "/>" endings
       
  2387         tool.outputFileConfig(xml, tool.Files.at(i).file);
       
  2388         xml << closetag(q_File);
       
  2389     }
       
  2390     if (!tool.Name.isEmpty())
       
  2391         xml << closetag(_Filter);
       
  2392     return xml;
       
  2393 }
       
  2394 
       
  2395 // VCProjectSingleConfig --------------------------------------------
       
  2396 VCFilter nullFilter;
       
  2397 VCFilter& VCProjectSingleConfig::filterForExtraCompiler(const QString &compilerName)
       
  2398 {
       
  2399     for (int i = 0; i < ExtraCompilersFiles.count(); ++i)
       
  2400         if (ExtraCompilersFiles.at(i).Name == compilerName)
       
  2401             return ExtraCompilersFiles[i];
       
  2402     return nullFilter;
       
  2403 }
       
  2404 
       
  2405 
       
  2406 XmlOutput &operator<<(XmlOutput &xml, const VCProjectSingleConfig &tool)
       
  2407 {
       
  2408     xml << decl("1.0", "Windows-1252")
       
  2409         << tag(_VisualStudioProject)
       
  2410             << attrS(_ProjectType, "Visual C++")
       
  2411             << attrS(_Version, tool.Version)
       
  2412             << attrS(_Name, tool.Name)
       
  2413             << attrS(_ProjectGUID, tool.ProjectGUID)
       
  2414             << attrS(_Keyword, tool.Keyword)
       
  2415             << attrS(_SccProjectName, tool.SccProjectName)
       
  2416             << attrS(_SccLocalPath, tool.SccLocalPath)
       
  2417             << tag(_Platforms)
       
  2418                 << tag(_Platform)
       
  2419                     << attrS(_Name, tool.PlatformName)
       
  2420             << closetag(_Platforms)
       
  2421             << tag(_Configurations)
       
  2422             << tool.Configuration;
       
  2423     xml     << closetag(_Configurations)
       
  2424             << tag(q_Files);
       
  2425     // Add this configuration into a multi-config project, since that's where we have the flat/tree
       
  2426     // XML output functionality
       
  2427     VCProject tempProj;
       
  2428     tempProj.SingleProjects += tool;
       
  2429     tempProj.outputFilter(xml, "Sources");
       
  2430     tempProj.outputFilter(xml, "Headers");
       
  2431     tempProj.outputFilter(xml, "GeneratedFiles");
       
  2432     tempProj.outputFilter(xml, "LexYaccFiles");
       
  2433     tempProj.outputFilter(xml, "TranslationFiles");
       
  2434     tempProj.outputFilter(xml, "FormFiles");
       
  2435     tempProj.outputFilter(xml, "ResourceFiles");
       
  2436     for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) {
       
  2437         tempProj.outputFilter(xml, tempProj.ExtraCompilers.at(x));
       
  2438     }
       
  2439     tempProj.outputFilter(xml, "RootFiles");
       
  2440     xml     << closetag(q_Files)
       
  2441             << tag(_Globals)
       
  2442                 << data(); // No "/>" end tag
       
  2443     return xml;
       
  2444 }
       
  2445 
       
  2446 
       
  2447 // Tree file generation ---------------------------------------------
       
  2448 void TreeNode::generateXML(XmlOutput &xml, const QString &tagName, VCProject &tool, const QString &filter) {
       
  2449     if (children.size()) {
       
  2450         // Filter
       
  2451         ChildrenMap::ConstIterator it, end = children.constEnd();
       
  2452         if (!tagName.isEmpty()) {
       
  2453             xml << tag("Filter")
       
  2454                 << attr("Name", tagName)
       
  2455                 << attr("Filter", "");
       
  2456         }
       
  2457         // First round, do nested filters
       
  2458         for (it = children.constBegin(); it != end; ++it)
       
  2459             if ((*it)->children.size())
       
  2460                 (*it)->generateXML(xml, it.key(), tool, filter);
       
  2461         // Second round, do leafs
       
  2462         for (it = children.constBegin(); it != end; ++it)
       
  2463             if (!(*it)->children.size())
       
  2464                 (*it)->generateXML(xml, it.key(), tool, filter);
       
  2465 
       
  2466         if (!tagName.isEmpty())
       
  2467             xml << closetag("Filter");
       
  2468     } else {
       
  2469         // Leaf
       
  2470         tool.outputFileConfigs(xml, info, filter);
       
  2471     }
       
  2472 }
       
  2473 
       
  2474 
       
  2475 // Flat file generation ---------------------------------------------
       
  2476 void FlatNode::generateXML(XmlOutput &xml, const QString &/*tagName*/, VCProject &tool, const QString &filter) {
       
  2477     if (children.size()) {
       
  2478         ChildrenMapFlat::ConstIterator it = children.constBegin();
       
  2479         ChildrenMapFlat::ConstIterator end = children.constEnd();
       
  2480         for (; it != end; ++it) {
       
  2481             tool.outputFileConfigs(xml, (*it), filter);
       
  2482         }
       
  2483     }
       
  2484 }
       
  2485 
       
  2486 
       
  2487 // VCProject --------------------------------------------------------
       
  2488 // Output all configurations (by filtername) for a file (by info)
       
  2489 // A filters config output is in VCFilter.outputFileConfig()
       
  2490 void VCProject::outputFileConfigs(XmlOutput &xml,
       
  2491 //                                  VCProjectSingleConfig::FilterTypes type
       
  2492                                   const VCFilterFile &info,
       
  2493                                   const QString &filtername)
       
  2494 {
       
  2495     xml << tag(q_File)
       
  2496             << attrS(_RelativePath, Option::fixPathToLocalOS(info.file));
       
  2497     for (int i = 0; i < SingleProjects.count(); ++i) {
       
  2498         VCFilter filter;
       
  2499         if (filtername == "RootFiles") {
       
  2500             filter = SingleProjects.at(i).RootFiles;
       
  2501         } else if (filtername == "Sources") {
       
  2502             filter = SingleProjects.at(i).SourceFiles;
       
  2503         } else if (filtername == "Headers") {
       
  2504             filter = SingleProjects.at(i).HeaderFiles;
       
  2505         } else if (filtername == "GeneratedFiles") {
       
  2506             filter = SingleProjects.at(i).GeneratedFiles;
       
  2507         } else if (filtername == "LexYaccFiles") {
       
  2508             filter = SingleProjects.at(i).LexYaccFiles;
       
  2509         } else if (filtername == "TranslationFiles") {
       
  2510             filter = SingleProjects.at(i).TranslationFiles;
       
  2511         } else if (filtername == "FormFiles") {
       
  2512             filter = SingleProjects.at(i).FormFiles;
       
  2513         } else if (filtername == "ResourceFiles") {
       
  2514             filter = SingleProjects.at(i).ResourceFiles;
       
  2515         } else {
       
  2516             // ExtraCompilers
       
  2517             filter = SingleProjects[i].filterForExtraCompiler(filtername);
       
  2518         }
       
  2519 
       
  2520         if (filter.Config) // only if the filter is not empty
       
  2521             filter.outputFileConfig(xml, info.file);
       
  2522     }
       
  2523     xml << closetag(q_File);
       
  2524 }
       
  2525 
       
  2526 // outputs a given filter for all existing configurations of a project
       
  2527 void VCProject::outputFilter(XmlOutput &xml,
       
  2528 //                             VCProjectSingleConfig::FilterTypes type
       
  2529                              const QString &filtername)
       
  2530 {
       
  2531     Node *root;
       
  2532     if (SingleProjects.at(0).flat_files)
       
  2533         root = new FlatNode;
       
  2534     else
       
  2535         root = new TreeNode;
       
  2536 
       
  2537     QString name, extfilter, guid;
       
  2538     triState parse;
       
  2539 
       
  2540     for (int i = 0; i < SingleProjects.count(); ++i) {
       
  2541         VCFilter filter;
       
  2542         if (filtername == "RootFiles") {
       
  2543             filter = SingleProjects.at(i).RootFiles;
       
  2544         } else if (filtername == "Sources") {
       
  2545             filter = SingleProjects.at(i).SourceFiles;
       
  2546         } else if (filtername == "Headers") {
       
  2547             filter = SingleProjects.at(i).HeaderFiles;
       
  2548         } else if (filtername == "GeneratedFiles") {
       
  2549             filter = SingleProjects.at(i).GeneratedFiles;
       
  2550         } else if (filtername == "LexYaccFiles") {
       
  2551             filter = SingleProjects.at(i).LexYaccFiles;
       
  2552         } else if (filtername == "TranslationFiles") {
       
  2553             filter = SingleProjects.at(i).TranslationFiles;
       
  2554         } else if (filtername == "FormFiles") {
       
  2555             filter = SingleProjects.at(i).FormFiles;
       
  2556         } else if (filtername == "ResourceFiles") {
       
  2557             filter = SingleProjects.at(i).ResourceFiles;
       
  2558         } else {
       
  2559             // ExtraCompilers
       
  2560             filter = SingleProjects[i].filterForExtraCompiler(filtername);
       
  2561         }
       
  2562 
       
  2563         // Merge all files in this filter to root tree
       
  2564         for (int x = 0; x < filter.Files.count(); ++x)
       
  2565             root->addElement(filter.Files.at(x));
       
  2566 
       
  2567         // Save filter setting from first filter. Next filters
       
  2568         // may differ but we cannot handle that. (ex. extfilter)
       
  2569         if (name.isEmpty()) {
       
  2570             name = filter.Name;
       
  2571             extfilter = filter.Filter;
       
  2572             parse = filter.ParseFiles;
       
  2573             guid = filter.Guid;
       
  2574         }
       
  2575     }
       
  2576 
       
  2577     if (!root->hasElements())
       
  2578         return;
       
  2579 
       
  2580     // Actual XML output ----------------------------------
       
  2581     if (!name.isEmpty()) {
       
  2582         xml << tag(_Filter)
       
  2583                 << attrS(_Name, name)
       
  2584                 << attrS(_Filter, extfilter)
       
  2585                 << attrS(_UniqueIdentifier, guid)
       
  2586                 << attrT(_ParseFiles, parse);
       
  2587     }
       
  2588     root->generateXML(xml, "", *this, filtername); // output root tree
       
  2589     if (!name.isEmpty())
       
  2590         xml << closetag(_Filter);
       
  2591 }
       
  2592 
       
  2593 XmlOutput &operator<<(XmlOutput &xml, VCProject &tool)
       
  2594 {
       
  2595     if (tool.SingleProjects.count() == 0) {
       
  2596         warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output");
       
  2597         return xml;
       
  2598     }
       
  2599 
       
  2600     xml << decl("1.0", "Windows-1252")
       
  2601         << tag(_VisualStudioProject)
       
  2602             << attrS(_ProjectType, "Visual C++")
       
  2603             << attrS(_Version, tool.Version)
       
  2604             << attrS(_Name, tool.Name)
       
  2605             << attrS(_ProjectGUID, tool.ProjectGUID)
       
  2606             << attrS(_Keyword, tool.Keyword)
       
  2607             << attrS(_SccProjectName, tool.SccProjectName)
       
  2608             << attrS(_SccLocalPath, tool.SccLocalPath)
       
  2609             << tag(_Platforms)
       
  2610                 << tag(_Platform)
       
  2611                     << attrS(_Name, tool.PlatformName)
       
  2612             << closetag(_Platforms)
       
  2613             << tag(_Configurations);
       
  2614     // Output each configuration
       
  2615     for (int i = 0; i < tool.SingleProjects.count(); ++i)
       
  2616         xml     << tool.SingleProjects.at(i).Configuration;
       
  2617     xml     << closetag(_Configurations)
       
  2618             << tag(q_Files);
       
  2619     tool.outputFilter(xml, "Sources");
       
  2620     tool.outputFilter(xml, "Headers");
       
  2621     tool.outputFilter(xml, "GeneratedFiles");
       
  2622     tool.outputFilter(xml, "LexYaccFiles");
       
  2623     tool.outputFilter(xml, "TranslationFiles");
       
  2624     tool.outputFilter(xml, "FormFiles");
       
  2625     tool.outputFilter(xml, "ResourceFiles");
       
  2626     for (int x = 0; x < tool.ExtraCompilers.count(); ++x) {
       
  2627         tool.outputFilter(xml, tool.ExtraCompilers.at(x));
       
  2628     }
       
  2629     tool.outputFilter(xml, "RootFiles");
       
  2630     xml     << closetag(q_Files)
       
  2631             << tag(_Globals)
       
  2632             << data(); // No "/>" end tag
       
  2633     return xml;
       
  2634 }
       
  2635 
       
  2636 QT_END_NAMESPACE