util/qmake/generators/win32/msvc_objectmodel.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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         case 0x0005b94: // X64
       
  1398             TargetMachine = machineX64;
       
  1399             break;
       
  1400         // so we put the others in AdditionalOptions...
       
  1401         case 0x0046063: // AM33
       
  1402         case 0x000466d: // ARM
       
  1403         case 0x0004795: // CEE
       
  1404         case 0x0004963: // EBC
       
  1405         case 0x004d494: // IA64
       
  1406         case 0x0050672: // M32R
       
  1407         case 0x0051e53: // MIPS
       
  1408         case 0x51e5646: // MIPS16
       
  1409         case 0x1e57b05: // MIPSFPU
       
  1410         case 0x57b09a6: // MIPSFPU16
       
  1411         case 0x5852738: // MIPSR41XX
       
  1412         case 0x0005543: // PPC
       
  1413         case 0x00057b3: // SH3
       
  1414         case 0x57b7980: // SH3DSP
       
  1415         case 0x00057b4: // SH4
       
  1416         case 0x00057b5: // SH5
       
  1417         case 0x058da12: // THUMB
       
  1418         case 0x96d8435: // TRICORE
       
  1419         default:
       
  1420             AdditionalOptions += option;
       
  1421             break;
       
  1422         }
       
  1423         break;
       
  1424     case 0x0034160: // /MAP[:filename]
       
  1425         GenerateMapFile = _True;
       
  1426         MapFileName = option+5;
       
  1427         break;
       
  1428     case 0x164e1ef: // /MAPINFO:{EXPORTS|LINES}
       
  1429         if(*(option+9) == 'E')
       
  1430             MapExports = _True;
       
  1431         else if(*(option+9) == 'L')
       
  1432             MapLines = _True;
       
  1433         break;
       
  1434     case 0x341a6b5: // /MERGE:from=to
       
  1435         MergeSections = option+7;
       
  1436         break;
       
  1437     case 0x0341d8c: // /MIDL:@file
       
  1438         MidlCommandFile = option+7;
       
  1439         break;
       
  1440     case 0x84e2679: // /NOASSEMBLY
       
  1441         TurnOffAssemblyGeneration = _True;
       
  1442         break;
       
  1443     case 0x2b21942: // /NODEFAULTLIB[:library]
       
  1444         if(*(option+13) == '\0')
       
  1445             IgnoreAllDefaultLibraries = _True;
       
  1446         else
       
  1447             IgnoreDefaultLibraryNames += option+14;
       
  1448         break;
       
  1449     case 0x33a3a39: // /NOENTRY
       
  1450         ResourceOnlyDLL = _True;
       
  1451         break;
       
  1452     case 0x434138f: // /NOLOGO
       
  1453         SuppressStartupBanner = _True;
       
  1454         break;
       
  1455     case 0x0034454: // /OPT:{REF | NOREF | ICF[=iterations] | NOICF | WIN98 | NOWIN98}
       
  1456         {
       
  1457             char third = *(option+7);
       
  1458             switch (third) {
       
  1459             case 'F': // REF
       
  1460                 if(*(option+5) == 'R') {
       
  1461                     OptimizeReferences = optReferences;
       
  1462                 } else { // ICF[=iterations]
       
  1463                     EnableCOMDATFolding = optFolding;
       
  1464                     // [=iterations] case is not documented
       
  1465                 }
       
  1466                 break;
       
  1467             case 'R': // NOREF
       
  1468                 OptimizeReferences = optNoReferences;
       
  1469                 break;
       
  1470             case 'I': // NOICF
       
  1471                 EnableCOMDATFolding = optNoFolding;
       
  1472                 break;
       
  1473             case 'N': // WIN98
       
  1474                 OptimizeForWindows98 = optWin98Yes;
       
  1475                 break;
       
  1476             case 'W': // NOWIN98
       
  1477                 OptimizeForWindows98 = optWin98No;
       
  1478                 break;
       
  1479             default:
       
  1480                 found = false;
       
  1481             }
       
  1482         }
       
  1483         break;
       
  1484     case 0x34468a2: // /ORDER:@filename
       
  1485         FunctionOrder = option+8;
       
  1486         break;
       
  1487     case 0x00344a4: // /OUT:filename
       
  1488         OutputFile = option+5;
       
  1489         break;
       
  1490     case 0x0034482: // /PDB:filename
       
  1491         ProgramDatabaseFile = option+5;
       
  1492         break;
       
  1493     case 0xa2ad314: // /PDBSTRIPPED:pdb_file_name
       
  1494         StripPrivateSymbols = option+13;
       
  1495         break;
       
  1496     case 0x6a09535: // /RELEASE
       
  1497         SetChecksum = _True;
       
  1498         break;
       
  1499     case 0x348857b: // /STACK:reserve[,commit]
       
  1500         {
       
  1501             QStringList both = QString(option+7).split(",");
       
  1502             StackReserveSize = both[0].toLongLong();
       
  1503             if(both.count() == 2)
       
  1504                 StackCommitSize = both[1].toLongLong();
       
  1505         }
       
  1506         break;
       
  1507     case 0x75AA4D8: // /SAFESH:{NO}
       
  1508         {
       
  1509             AdditionalOptions += option;
       
  1510             break;
       
  1511         }
       
  1512 	case 0x9B3C00D:
       
  1513     case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
       
  1514         {
       
  1515             // Split up in subsystem, and version number
       
  1516             QStringList both = QString(option+11).split(",");
       
  1517             switch (elfHash(both[0].toLatin1())) {
       
  1518             case 0x8438445: // CONSOLE
       
  1519                 SubSystem = subSystemConsole;
       
  1520                 break;
       
  1521             case 0xbe29493: // WINDOWS
       
  1522                 SubSystem = subSystemWindows;
       
  1523                 break;
       
  1524             // The following are undocumented, so add them to AdditionalOptions
       
  1525             case 0x240949e: // EFI_APPLICATION
       
  1526             case 0xe617652: // EFI_BOOT_SERVICE_DRIVER
       
  1527             case 0x9af477d: // EFI_ROM
       
  1528             case 0xd34df42: // EFI_RUNTIME_DRIVER
       
  1529             case 0x5268ea5: // NATIVE
       
  1530             case 0x05547e8: // POSIX
       
  1531             case 0x2949c95: // WINDOWSCE
       
  1532 			case 0x4B69795: // windowsce
       
  1533                 AdditionalOptions += option;
       
  1534                 break;
       
  1535             default:
       
  1536                 found = false;
       
  1537             }
       
  1538         }
       
  1539         break;
       
  1540     case 0x8b654de: // /SWAPRUN:{NET | CD}
       
  1541         if(*(option+9) == 'N')
       
  1542             SwapRunFromNet = _True;
       
  1543         else if(*(option+9) == 'C')
       
  1544             SwapRunFromCD = _True;
       
  1545         else
       
  1546             found = false;
       
  1547         break;
       
  1548     case 0x34906d4: // /TLBID:id
       
  1549         TypeLibraryResourceID = QString(option+7).toLongLong();
       
  1550         break;
       
  1551     case 0x4907494: // /TLBOUT:[path\]filename
       
  1552         TypeLibraryFile = option+8;
       
  1553         break;
       
  1554     case 0x976b525: // /TSAWARE[:NO]
       
  1555         if(*(option+8) == ':')
       
  1556             TerminalServerAware = termSvrAwareNo;
       
  1557         else
       
  1558             TerminalServerAware = termSvrAwareYes;
       
  1559         break;
       
  1560     case 0xaa67735: // /VERBOSE[:lib]
       
  1561         if(*(option+9) == ':') {
       
  1562             ShowProgress = linkProgressLibs;
       
  1563             AdditionalOptions += option;
       
  1564         } else {
       
  1565             ShowProgress = linkProgressAll;
       
  1566         }
       
  1567         break;
       
  1568     case 0xaa77f7e: // /VERSION:major[.minor]
       
  1569         Version = option+9;
       
  1570         break;
       
  1571     default:
       
  1572         AdditionalOptions += option;
       
  1573         break;
       
  1574     }
       
  1575     if(!found) {
       
  1576         warn_msg(WarnLogic, "Could not parse Linker options: %s, added as AdditionalOption", option);
       
  1577         AdditionalOptions += option;
       
  1578     }
       
  1579     return found;
       
  1580 }
       
  1581 
       
  1582 // VCMIDLTool -------------------------------------------------------
       
  1583 VCMIDLTool::VCMIDLTool()
       
  1584     :        DefaultCharType(midlCharUnsigned),
       
  1585         EnableErrorChecks(midlDisableAll),
       
  1586         ErrorCheckAllocations(unset),
       
  1587         ErrorCheckBounds(unset),
       
  1588         ErrorCheckEnumRange(unset),
       
  1589         ErrorCheckRefPointers(unset),
       
  1590         ErrorCheckStubData(unset),
       
  1591         GenerateStublessProxies(unset),
       
  1592         GenerateTypeLibrary(unset),
       
  1593         IgnoreStandardIncludePath(unset),
       
  1594         MkTypLibCompatible(unset),
       
  1595         StructMemberAlignment(midlAlignNotSet),
       
  1596         SuppressStartupBanner(unset),
       
  1597         TargetEnvironment(midlTargetNotSet),
       
  1598         ValidateParameters(unset),
       
  1599         WarnAsError(unset),
       
  1600         WarningLevel(midlWarningLevel_0)
       
  1601 {
       
  1602 }
       
  1603 
       
  1604 XmlOutput &operator<<(XmlOutput &xml, const VCMIDLTool &tool)
       
  1605 {
       
  1606     return xml
       
  1607         << tag(_Tool)
       
  1608             << attrS(_Name, _VCMIDLTool)
       
  1609             << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
       
  1610             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
  1611             << attrX(_CPreprocessOptions, tool.CPreprocessOptions)
       
  1612             << attrE(_DefaultCharType, tool.DefaultCharType)
       
  1613             << attrS(_DLLDataFileName, tool.DLLDataFileName)
       
  1614             << attrE(_EnableErrorChecks, tool.EnableErrorChecks)
       
  1615             << attrT(_ErrorCheckAllocations, tool.ErrorCheckAllocations)
       
  1616             << attrT(_ErrorCheckBounds, tool.ErrorCheckBounds)
       
  1617             << attrT(_ErrorCheckEnumRange, tool.ErrorCheckEnumRange)
       
  1618             << attrT(_ErrorCheckRefPointers, tool.ErrorCheckRefPointers)
       
  1619             << attrT(_ErrorCheckStubData, tool.ErrorCheckStubData)
       
  1620             << attrX(_FullIncludePath, tool.FullIncludePath)
       
  1621             << attrT(_GenerateStublessProxies, tool.GenerateStublessProxies)
       
  1622             << attrT(_GenerateTypeLibrary, tool.GenerateTypeLibrary)
       
  1623             << attrS(_HeaderFileName, tool.HeaderFileName)
       
  1624             << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
       
  1625             << attrS(_InterfaceIdentifierFileName, tool.InterfaceIdentifierFileName)
       
  1626             << attrT(_MkTypLibCompatible, tool.MkTypLibCompatible)
       
  1627             << attrS(_OutputDirectory, tool.OutputDirectory)
       
  1628             << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
       
  1629             << attrS(_ProxyFileName, tool.ProxyFileName)
       
  1630             << attrS(_RedirectOutputAndErrors, tool.RedirectOutputAndErrors)
       
  1631             << attrE(_StructMemberAlignment, tool.StructMemberAlignment, /*ifNot*/ midlAlignNotSet)
       
  1632             << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
       
  1633             << attrE(_TargetEnvironment, tool.TargetEnvironment, /*ifNot*/ midlTargetNotSet)
       
  1634             << attrS(_TypeLibraryName, tool.TypeLibraryName)
       
  1635             << attrX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions)
       
  1636             << attrT(_ValidateParameters, tool.ValidateParameters)
       
  1637             << attrT(_WarnAsError, tool.WarnAsError)
       
  1638             << attrE(_WarningLevel, tool.WarningLevel)
       
  1639         << closetag(_Tool);
       
  1640 }
       
  1641 
       
  1642 bool VCMIDLTool::parseOption(const char* option)
       
  1643 {
       
  1644 #ifdef USE_DISPLAY_HASH
       
  1645     displayHash("/D name[=def]"); displayHash("/I directory-list"); displayHash("/Oi");
       
  1646     displayHash("/Oic"); displayHash("/Oicf"); displayHash("/Oif"); displayHash("/Os");
       
  1647     displayHash("/U name"); displayHash("/WX"); displayHash("/W{0|1|2|3|4}");
       
  1648     displayHash("/Zp {N}"); displayHash("/Zs"); displayHash("/acf filename");
       
  1649     displayHash("/align {N}"); displayHash("/app_config"); displayHash("/c_ext");
       
  1650     displayHash("/char ascii7"); displayHash("/char signed"); displayHash("/char unsigned");
       
  1651     displayHash("/client none"); displayHash("/client stub"); displayHash("/confirm");
       
  1652     displayHash("/cpp_cmd cmd_line"); displayHash("/cpp_opt options");
       
  1653     displayHash("/cstub filename"); displayHash("/dlldata filename"); displayHash("/env win32");
       
  1654     displayHash("/env win64"); displayHash("/error all"); displayHash("/error allocation");
       
  1655     displayHash("/error bounds_check"); displayHash("/error enum"); displayHash("/error none");
       
  1656     displayHash("/error ref"); displayHash("/error stub_data"); displayHash("/h filename");
       
  1657     displayHash("/header filename"); displayHash("/iid filename"); displayHash("/lcid");
       
  1658     displayHash("/mktyplib203"); displayHash("/ms_ext"); displayHash("/ms_union");
       
  1659     displayHash("/msc_ver <nnnn>"); displayHash("/newtlb"); displayHash("/no_cpp");
       
  1660     displayHash("/no_def_idir"); displayHash("/no_default_epv"); displayHash("/no_format_opt");
       
  1661     displayHash("/no_warn"); displayHash("/nocpp"); displayHash("/nologo"); displayHash("/notlb");
       
  1662     displayHash("/o filename"); displayHash("/oldnames"); displayHash("/oldtlb");
       
  1663     displayHash("/osf"); displayHash("/out directory"); displayHash("/pack {N}");
       
  1664     displayHash("/prefix all"); displayHash("/prefix client"); displayHash("/prefix server");
       
  1665     displayHash("/prefix switch"); displayHash("/protocol all"); displayHash("/protocol dce");
       
  1666     displayHash("/protocol ndr64"); displayHash("/proxy filename"); displayHash("/robust");
       
  1667     displayHash("/rpcss"); displayHash("/savePP"); displayHash("/server none");
       
  1668     displayHash("/server stub"); displayHash("/sstub filename"); displayHash("/syntax_check");
       
  1669     displayHash("/target {system}"); displayHash("/tlb filename"); displayHash("/use_epv");
       
  1670     displayHash("/win32"); displayHash("/win64");
       
  1671 #endif
       
  1672     bool found = true;
       
  1673     int offset = 0;
       
  1674     switch(elfHash(option)) {
       
  1675     case 0x0000334: // /D name[=def]
       
  1676         PreprocessorDefinitions += option+3;
       
  1677         break;
       
  1678     case 0x0000339: // /I directory-list
       
  1679         AdditionalIncludeDirectories += option+3;
       
  1680         break;
       
  1681     case 0x0345f96: // /Oicf
       
  1682     case 0x00345f6: // /Oif
       
  1683         GenerateStublessProxies = _True;
       
  1684         break;
       
  1685     case 0x0000345: // /U name
       
  1686         UndefinePreprocessorDefinitions += option+3;
       
  1687         break;
       
  1688     case 0x00034c8: // /WX
       
  1689         WarnAsError = _True;
       
  1690         break;
       
  1691     case 0x3582fde: // /align {N}
       
  1692         offset = 3;  // Fallthrough
       
  1693     case 0x0003510: // /Zp {N}
       
  1694         switch (*(option+offset+4)) {
       
  1695         case '1':
       
  1696             StructMemberAlignment = (*(option+offset+5) == '\0') ? midlAlignSingleByte : midlAlignSixteenBytes;
       
  1697             break;
       
  1698         case '2':
       
  1699             StructMemberAlignment = midlAlignTwoBytes;
       
  1700             break;
       
  1701         case '4':
       
  1702             StructMemberAlignment = midlAlignFourBytes;
       
  1703             break;
       
  1704         case '8':
       
  1705             StructMemberAlignment = midlAlignEightBytes;
       
  1706             break;
       
  1707         default:
       
  1708             found = false;
       
  1709         }
       
  1710         break;
       
  1711     case 0x0359e82: // /char {ascii7|signed|unsigned}
       
  1712         switch(*(option+6)) {
       
  1713         case 'a':
       
  1714             DefaultCharType = midlCharAscii7;
       
  1715             break;
       
  1716         case 's':
       
  1717             DefaultCharType = midlCharSigned;
       
  1718             break;
       
  1719         case 'u':
       
  1720             DefaultCharType = midlCharUnsigned;
       
  1721             break;
       
  1722         default:
       
  1723             found = false;
       
  1724         }
       
  1725         break;
       
  1726     case 0xa766524: // /cpp_opt options
       
  1727         CPreprocessOptions += option+9;
       
  1728         break;
       
  1729     case 0xb32abf1: // /dlldata filename
       
  1730         DLLDataFileName = option + 9;
       
  1731         break;
       
  1732     case 0x0035c56: // /env {win32|win64}
       
  1733         TargetEnvironment = (*(option+8) == '6') ? midlTargetWin64 : midlTargetWin32;
       
  1734         break;
       
  1735     case 0x35c9962: // /error {all|allocation|bounds_check|enum|none|ref|stub_data}
       
  1736         EnableErrorChecks = midlEnableCustom;
       
  1737         switch (*(option+7)) {
       
  1738         case 'a':
       
  1739             if(*(option+10) == '\0')
       
  1740                 EnableErrorChecks = midlEnableAll;
       
  1741             else
       
  1742                 ErrorCheckAllocations = _True;
       
  1743             break;
       
  1744         case 'b':
       
  1745             ErrorCheckBounds = _True;
       
  1746             break;
       
  1747         case 'e':
       
  1748             ErrorCheckEnumRange = _True;
       
  1749             break;
       
  1750         case 'n':
       
  1751             EnableErrorChecks = midlDisableAll;
       
  1752             break;
       
  1753         case 'r':
       
  1754             ErrorCheckRefPointers = _True;
       
  1755             break;
       
  1756         case 's':
       
  1757             ErrorCheckStubData = _True;
       
  1758             break;
       
  1759         default:
       
  1760             found = false;
       
  1761         }
       
  1762         break;
       
  1763     case 0x5eb7af2: // /header filename
       
  1764         offset = 5;
       
  1765     case 0x0000358: // /h filename
       
  1766         HeaderFileName = option + offset + 3;
       
  1767         break;
       
  1768     case 0x0035ff4: // /iid filename
       
  1769         InterfaceIdentifierFileName = option+5;
       
  1770         break;
       
  1771     case 0x64b7933: // /mktyplib203
       
  1772         MkTypLibCompatible = _True;
       
  1773         break;
       
  1774     case 0x8e0b0a2: // /no_def_idir
       
  1775         IgnoreStandardIncludePath = _True;
       
  1776         break;
       
  1777     case 0x65635ef: // /nologo
       
  1778         SuppressStartupBanner = _True;
       
  1779         break;
       
  1780     case 0x3656b22: // /notlb
       
  1781         GenerateTypeLibrary = _True;
       
  1782         break;
       
  1783     case 0x000035f: // /o filename
       
  1784         RedirectOutputAndErrors = option+3;
       
  1785         break;
       
  1786     case 0x00366c4: // /out directory
       
  1787         OutputDirectory = option+5;
       
  1788         break;
       
  1789     case 0x36796f9: // /proxy filename
       
  1790         ProxyFileName = option+7;
       
  1791         break;
       
  1792     case 0x6959c94: // /robust
       
  1793         ValidateParameters = _True;
       
  1794         break;
       
  1795     case 0x6a88df4: // /target {system}
       
  1796         if(*(option+11) == '6')
       
  1797             TargetEnvironment = midlTargetWin64;
       
  1798         else
       
  1799             TargetEnvironment = midlTargetWin32;
       
  1800         break;
       
  1801     case 0x0036b22: // /tlb filename
       
  1802         TypeLibraryName = option+5;
       
  1803         break;
       
  1804     case 0x36e0162: // /win32
       
  1805         TargetEnvironment = midlTargetWin32;
       
  1806         break;
       
  1807     case 0x36e0194: // /win64
       
  1808         TargetEnvironment = midlTargetWin64;
       
  1809         break;
       
  1810     case 0x0003459: // /Oi
       
  1811     case 0x00345f3: // /Oic
       
  1812     case 0x0003463: // /Os
       
  1813     case 0x0003513: // /Zs
       
  1814     case 0x0035796: // /acf filename
       
  1815     case 0x5b1cb97: // /app_config
       
  1816     case 0x3595cf4: // /c_ext
       
  1817     case 0x5a2fc64: // /client {none|stub}
       
  1818     case 0xa64d3dd: // /confirm
       
  1819     case 0xa765b64: // /cpp_cmd cmd_line
       
  1820     case 0x35aabb2: // /cstub filename
       
  1821     case 0x03629f4: // /lcid
       
  1822     case 0x6495cc4: // /ms_ext
       
  1823     case 0x96c7a1e: // /ms_union
       
  1824     case 0x4996fa2: // /msc_ver <nnnn>
       
  1825     case 0x64ceb12: // /newtlb
       
  1826     case 0x6555a40: // /no_cpp
       
  1827     case 0xf64d6a6: // /no_default_epv
       
  1828     case 0x6dd9384: // /no_format_opt
       
  1829     case 0x556dbee: // /no_warn
       
  1830     case 0x3655a70: // /nocpp
       
  1831     case 0x2b455a3: // /oldnames
       
  1832     case 0x662bb12: // /oldtlb
       
  1833     case 0x0036696: // /osf
       
  1834     case 0x036679b: // /pack {N}
       
  1835     case 0x678bd38: // /prefix {all|client|server|switch}
       
  1836     case 0x96b702c: // /protocol {all|dce|ndr64}
       
  1837     case 0x3696aa3: // /rpcss
       
  1838     case 0x698ca60: // /savePP
       
  1839     case 0x69c9cf2: // /server {none|stub}
       
  1840     case 0x36aabb2: // /sstub filename
       
  1841     case 0xce9b12b: // /syntax_check
       
  1842     case 0xc9b5f16: // /use_epv
       
  1843         AdditionalOptions += option;
       
  1844         break;
       
  1845     default:
       
  1846         // /W{0|1|2|3|4} case
       
  1847         if(*(option+1) == 'W') {
       
  1848             switch (*(option+2)) {
       
  1849             case '0':
       
  1850                 WarningLevel = midlWarningLevel_0;
       
  1851                 break;
       
  1852             case '1':
       
  1853                 WarningLevel = midlWarningLevel_1;
       
  1854                 break;
       
  1855             case '2':
       
  1856                 WarningLevel = midlWarningLevel_2;
       
  1857                 break;
       
  1858             case '3':
       
  1859                 WarningLevel = midlWarningLevel_3;
       
  1860                 break;
       
  1861             case '4':
       
  1862                 WarningLevel = midlWarningLevel_4;
       
  1863                 break;
       
  1864             default:
       
  1865                 found = false;
       
  1866             }
       
  1867         }
       
  1868         break;
       
  1869     }
       
  1870     if(!found)
       
  1871         warn_msg(WarnLogic, "Could not parse MIDL option: %s", option);
       
  1872     return true;
       
  1873 }
       
  1874 
       
  1875 // VCLibrarianTool --------------------------------------------------
       
  1876 VCLibrarianTool::VCLibrarianTool()
       
  1877     :        IgnoreAllDefaultLibraries(unset),
       
  1878         SuppressStartupBanner(_True)
       
  1879 {
       
  1880 }
       
  1881 
       
  1882 XmlOutput &operator<<(XmlOutput &xml, const VCLibrarianTool &tool)
       
  1883 {
       
  1884     return xml
       
  1885         << tag(_Tool)
       
  1886             << attrS(_Name, _VCLibrarianTool)
       
  1887             << attrX(_AdditionalDependencies, tool.AdditionalDependencies)
       
  1888             << attrX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories)
       
  1889             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
  1890             << attrX(_ExportNamedFunctions, tool.ExportNamedFunctions)
       
  1891             << attrX(_ForceSymbolReferences, tool.ForceSymbolReferences)
       
  1892             << attrT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
       
  1893             << attrX(_IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames)
       
  1894             << attrS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
       
  1895             << attrS(_OutputFile, tool.OutputFile)
       
  1896             << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
       
  1897         << closetag(_Tool);
       
  1898 }
       
  1899 
       
  1900 // VCCustomBuildTool ------------------------------------------------
       
  1901 VCCustomBuildTool::VCCustomBuildTool()
       
  1902 {
       
  1903     ToolName = "VCCustomBuildTool";
       
  1904 }
       
  1905 
       
  1906 XmlOutput &operator<<(XmlOutput &xml, const VCCustomBuildTool &tool)
       
  1907 {
       
  1908     // The code below offers two ways to split custom build step commands.
       
  1909     // Normally the $$escape_expand(\n\t) is used in a project file, which is correctly translated
       
  1910     // in all generators. However, if you use $$escape_expand(\n\r) (or \n\h) instead, the VCPROJ
       
  1911     // generator will instead of binding the commands with " && " will insert a proper newline into
       
  1912     // the VCPROJ file. We sometimes use this method of splitting commands if the custom buildstep
       
  1913     // contains a command-line which is too big to run on certain OS.
       
  1914     QString cmds;
       
  1915     int end = tool.CommandLine.count();
       
  1916     for(int i = 0; i < end; ++i) {
       
  1917         QString cmdl = tool.CommandLine.at(i);
       
  1918         if (cmdl.contains("\r\t")) {
       
  1919             if (i == end - 1)
       
  1920                 cmdl = cmdl.trimmed();
       
  1921             cmdl.replace("\r\t", " && ");
       
  1922         } else if (cmdl.contains("\r\n")) {
       
  1923             ;
       
  1924         } else if (cmdl.contains("\r\\h")) {
       
  1925             // The above \r\n should work, but doesn't, so we have this hack
       
  1926             cmdl.replace("\r\\h", "\r\n");
       
  1927         } else {
       
  1928             if (i < end - 1)
       
  1929                 cmdl += " && ";
       
  1930         }
       
  1931         cmds += cmdl;
       
  1932     }
       
  1933     return xml
       
  1934         << tag(_Tool)
       
  1935             << attrS(_Name, tool.ToolName)
       
  1936             << attrX(_AdditionalDependencies, tool.AdditionalDependencies, ";")
       
  1937             << attrS(_CommandLine, cmds)
       
  1938             << attrS(_Description, tool.Description)
       
  1939             << attrX(_Outputs, tool.Outputs, ";")
       
  1940             << attrS(_Path, tool.ToolPath)
       
  1941         << closetag(_Tool);
       
  1942 }
       
  1943 
       
  1944 // VCResourceCompilerTool -------------------------------------------
       
  1945 VCResourceCompilerTool::VCResourceCompilerTool()
       
  1946     :   Culture(rcUseDefault),
       
  1947         IgnoreStandardIncludePath(unset),
       
  1948         ShowProgress(linkProgressNotSet)
       
  1949 {
       
  1950     PreprocessorDefinitions = QStringList("NDEBUG");
       
  1951 }
       
  1952 
       
  1953 XmlOutput &operator<<(XmlOutput &xml, const VCResourceCompilerTool &tool)
       
  1954 {
       
  1955     return xml
       
  1956         << tag(_Tool)
       
  1957             << attrS(_Name, _VCResourceCompilerTool)
       
  1958             << attrS(_Path, tool.ToolPath)
       
  1959             << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
       
  1960             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
       
  1961             << attrE(_Culture, tool.Culture, /*ifNot*/ rcUseDefault)
       
  1962             << attrX(_FullIncludePath, tool.FullIncludePath)
       
  1963             << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
       
  1964             << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
       
  1965             << attrS(_ResourceOutputFileName, tool.ResourceOutputFileName)
       
  1966             << attrE(_ShowProgress, tool.ShowProgress, /*ifNot*/ linkProgressNotSet)
       
  1967         << closetag(_Tool);
       
  1968 }
       
  1969 
       
  1970 // VCDeploymentTool --------------------------------------------
       
  1971 VCDeploymentTool::VCDeploymentTool()
       
  1972     :   RegisterOutput(registerNo)
       
  1973 {
       
  1974     DeploymentTag = "DeploymentTool";
       
  1975     RemoteDirectory = "";
       
  1976 }
       
  1977 
       
  1978 XmlOutput &operator<<(XmlOutput &xml, const VCDeploymentTool &tool)
       
  1979 {
       
  1980     if (tool.AdditionalFiles.isEmpty())
       
  1981         return xml;
       
  1982     return xml
       
  1983         << tag(tool.DeploymentTag)
       
  1984         << attrS(_RemoteDirectory, tool.RemoteDirectory)
       
  1985         << attrE(_RegisterOutput, tool.RegisterOutput)
       
  1986         << attrS(_AdditionalFiles, tool.AdditionalFiles)
       
  1987         << closetag(tool.DeploymentTag);
       
  1988 }
       
  1989 
       
  1990 // VCEventTool -------------------------------------------------
       
  1991 XmlOutput &operator<<(XmlOutput &xml, const VCEventTool &tool)
       
  1992 {
       
  1993     return xml
       
  1994         << tag(_Tool)
       
  1995             << attrS(_Name, tool.ToolName)
       
  1996             << attrS(_Path, tool.ToolPath)
       
  1997             << attrS(_CommandLine, tool.CommandLine)
       
  1998             << attrS(_Description, tool.Description)
       
  1999             << attrT(_ExcludedFromBuild, tool.ExcludedFromBuild)
       
  2000         << closetag(_Tool);
       
  2001 }
       
  2002 
       
  2003 // VCPostBuildEventTool ---------------------------------------------
       
  2004 VCPostBuildEventTool::VCPostBuildEventTool()
       
  2005 {
       
  2006     ToolName = "VCPostBuildEventTool";
       
  2007 }
       
  2008 
       
  2009 // VCPreBuildEventTool ----------------------------------------------
       
  2010 VCPreBuildEventTool::VCPreBuildEventTool()
       
  2011 {
       
  2012     ToolName = "VCPreBuildEventTool";
       
  2013 }
       
  2014 
       
  2015 // VCPreLinkEventTool -----------------------------------------------
       
  2016 VCPreLinkEventTool::VCPreLinkEventTool()
       
  2017 {
       
  2018     ToolName = "VCPreLinkEventTool";
       
  2019 }
       
  2020 
       
  2021 // VCConfiguration --------------------------------------------------
       
  2022 
       
  2023 VCConfiguration::VCConfiguration()
       
  2024     :        ATLMinimizesCRunTimeLibraryUsage(unset),
       
  2025         BuildBrowserInformation(unset),
       
  2026         CharacterSet(charSetNotSet),
       
  2027         ConfigurationType(typeApplication),
       
  2028         RegisterOutput(unset),
       
  2029         UseOfATL(useATLNotSet),
       
  2030         UseOfMfc(useMfcStdWin),
       
  2031         WholeProgramOptimization(unset)
       
  2032 {
       
  2033     compiler.config = this;
       
  2034     linker.config = this;
       
  2035     idl.config = this;
       
  2036 }
       
  2037 
       
  2038 XmlOutput &operator<<(XmlOutput &xml, const VCConfiguration &tool)
       
  2039 {
       
  2040     xml << tag(_Configuration)
       
  2041             << attrS(_Name, tool.Name)
       
  2042             << attrS(_OutputDirectory, tool.OutputDirectory)
       
  2043             << attrT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage)
       
  2044             << attrT(_BuildBrowserInformation, tool.BuildBrowserInformation)
       
  2045             << attrE(_CharacterSet, tool.CharacterSet, /*ifNot*/ charSetNotSet)
       
  2046             << attrE(_ConfigurationType, tool.ConfigurationType)
       
  2047             << attrS(_DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean)
       
  2048             << attrS(_ImportLibrary, tool.ImportLibrary)
       
  2049             << attrS(_IntermediateDirectory, tool.IntermediateDirectory)
       
  2050             << attrS(_PrimaryOutput, tool.PrimaryOutput)
       
  2051             << attrS(_ProgramDatabase, tool.ProgramDatabase)
       
  2052             << attrT(_RegisterOutput, tool.RegisterOutput)
       
  2053             << attrE(_UseOfATL, tool.UseOfATL, /*ifNot*/ useATLNotSet)
       
  2054             << attrE(_UseOfMfc, tool.UseOfMfc)
       
  2055             << attrT(_WholeProgramOptimization, tool.WholeProgramOptimization)
       
  2056             << tool.compiler
       
  2057             << tool.custom;
       
  2058     if (tool.ConfigurationType == typeStaticLibrary)
       
  2059         xml << tool.librarian;
       
  2060     else
       
  2061         xml << tool.linker;
       
  2062     xml     << tool.idl
       
  2063             << tool.postBuild
       
  2064             << tool.preBuild
       
  2065             << tool.preLink
       
  2066             << tool.resource
       
  2067             << tool.deployment
       
  2068         << closetag(_Configuration);
       
  2069     return xml;
       
  2070 }
       
  2071 // VCFilter ---------------------------------------------------------
       
  2072 VCFilter::VCFilter()
       
  2073     :   ParseFiles(unset),
       
  2074         Config(0)
       
  2075 {
       
  2076     useCustomBuildTool = false;
       
  2077     useCompilerTool = false;
       
  2078 }
       
  2079 
       
  2080 void VCFilter::addFile(const QString& filename)
       
  2081 {
       
  2082     Files += VCFilterFile(filename);
       
  2083 }
       
  2084 
       
  2085 void VCFilter::addFile(const VCFilterFile& fileInfo)
       
  2086 {
       
  2087     Files += VCFilterFile(fileInfo);
       
  2088 }
       
  2089 
       
  2090 void VCFilter::addFiles(const QStringList& fileList)
       
  2091 {
       
  2092     for (int i = 0; i < fileList.count(); ++i)
       
  2093         addFile(fileList.at(i));
       
  2094 }
       
  2095 
       
  2096 void VCFilter::modifyPCHstage(QString str)
       
  2097 {
       
  2098     bool autogenSourceFile = Project->autogenPrecompCPP;
       
  2099     bool pchThroughSourceFile = !Project->precompCPP.isEmpty();
       
  2100     bool isCFile = false;
       
  2101     for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) {
       
  2102         if (str.endsWith(*it)) {
       
  2103             isCFile = true;
       
  2104             break;
       
  2105         }
       
  2106     }
       
  2107     bool isHFile = str.endsWith(".h") && (str == Project->precompH);
       
  2108     bool isCPPFile = pchThroughSourceFile && (str == Project->precompCPP);
       
  2109 
       
  2110     if(!isCFile && !isHFile && !isCPPFile)
       
  2111         return;
       
  2112 
       
  2113     if(isHFile && pchThroughSourceFile) {
       
  2114         if (autogenSourceFile) {
       
  2115             useCustomBuildTool = true;
       
  2116             QString toFile(Project->precompCPP);
       
  2117             CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ...";
       
  2118             CustomBuildTool.Outputs += toFile;
       
  2119 
       
  2120             QStringList lines;
       
  2121             CustomBuildTool.CommandLine +=
       
  2122                 "echo /*-------------------------------------------------------------------- >" + toFile;
       
  2123             lines << "* Precompiled header source file used by Visual Studio.NET to generate";
       
  2124             lines << "* the .pch file.";
       
  2125             lines << "*";
       
  2126             lines << "* Due to issues with the dependencies checker within the IDE, it";
       
  2127             lines << "* sometimes fails to recompile the PCH file, if we force the IDE to";
       
  2128             lines << "* create the PCH file directly from the header file.";
       
  2129             lines << "*";
       
  2130             lines << "* This file is auto-generated by qmake since no PRECOMPILED_SOURCE was";
       
  2131             lines << "* specified, and is used as the common stdafx.cpp. The file is only";
       
  2132             lines << "* generated when creating .vcproj project files, and is not used for";
       
  2133             lines << "* command line compilations by nmake.";
       
  2134             lines << "*";
       
  2135             lines << "* WARNING: All changes made in this file will be lost.";
       
  2136             lines << "--------------------------------------------------------------------*/";
       
  2137             lines << "#include \"" + Project->precompHFilename + "\"";
       
  2138             foreach(QString line, lines)
       
  2139                 CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile;
       
  2140         }
       
  2141         return;
       
  2142     }
       
  2143 
       
  2144     useCompilerTool = true;
       
  2145     // Setup PCH options
       
  2146     CompilerTool.UsePrecompiledHeader     = (isCFile ? pchNone : pchCreateUsingSpecific);
       
  2147     CompilerTool.PrecompiledHeaderThrough = (isCPPFile ? QString("$(INHERIT)") : QString("$(NOINHERIT)"));
       
  2148     CompilerTool.ForcedIncludeFiles       = QStringList("$(NOINHERIT)");
       
  2149 }
       
  2150 
       
  2151 bool VCFilter::addExtraCompiler(const VCFilterFile &info)
       
  2152 {
       
  2153     const QStringList &extraCompilers = Project->extraCompilerSources.value(info.file);
       
  2154     if (extraCompilers.isEmpty())
       
  2155         return false;
       
  2156 
       
  2157     QString inFile = info.file;
       
  2158 
       
  2159     // is the extracompiler rule on a file with a built in compiler?
       
  2160     const QStringList &objectMappedFile = Project->extraCompilerOutputs[inFile];
       
  2161     bool hasBuiltIn = false;
       
  2162     if (!objectMappedFile.isEmpty()) {
       
  2163         hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile.at(0));
       
  2164 //        qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(" ")));
       
  2165     }
       
  2166 
       
  2167     CustomBuildTool.AdditionalDependencies.clear();
       
  2168     CustomBuildTool.CommandLine.clear();
       
  2169     CustomBuildTool.Description.clear();
       
  2170     CustomBuildTool.Outputs.clear();
       
  2171     CustomBuildTool.ToolPath.clear();
       
  2172 	CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
       
  2173 
       
  2174     for (int x = 0; x < extraCompilers.count(); ++x) {
       
  2175         const QString &extraCompilerName = extraCompilers.at(x);
       
  2176 
       
  2177         if (!Project->verifyExtraCompiler(extraCompilerName, inFile) && !hasBuiltIn)
       
  2178             continue;
       
  2179 
       
  2180         // All information about the extra compiler
       
  2181         QString tmp_out = Project->project->first(extraCompilerName + ".output");
       
  2182         QString tmp_cmd = Project->project->variables()[extraCompilerName + ".commands"].join(" ");
       
  2183         QString tmp_cmd_name = Project->project->variables()[extraCompilerName + ".name"].join(" ");
       
  2184         QStringList tmp_dep = Project->project->variables()[extraCompilerName + ".depends"];
       
  2185         QString tmp_dep_cmd = Project->project->variables()[extraCompilerName + ".depend_command"].join(" ");
       
  2186         QStringList vars = Project->project->variables()[extraCompilerName + ".variables"];
       
  2187         QStringList configs = Project->project->variables()[extraCompilerName + ".CONFIG"];
       
  2188         bool combined = configs.indexOf("combine") != -1;
       
  2189 
       
  2190         QString cmd, cmd_name, out;
       
  2191         QStringList deps, inputs;
       
  2192         // Variabel replacement of output name
       
  2193         out = Option::fixPathToTargetOS(
       
  2194                     Project->replaceExtraCompilerVariables(tmp_out, inFile, QString()),
       
  2195                     false);
       
  2196 
       
  2197         // If file has built-in compiler, we've swapped the input and output of
       
  2198         // the command, as we in Visual Studio cannot have a Custom Buildstep on
       
  2199         // a file which uses a built-in compiler. We would in this case only get
       
  2200         // the result from the extra compiler. If 'hasBuiltIn' is true, we know
       
  2201         // that we're actually on the _output_file_ of the result, and we
       
  2202         // therefore swap inFile and out below, since the extra-compiler still
       
  2203         // must see it as the original way. If the result also has a built-in
       
  2204         // compiler, too bad..
       
  2205         if (hasBuiltIn) {
       
  2206             out = inFile;
       
  2207             inFile = objectMappedFile.at(0);
       
  2208         }
       
  2209 
       
  2210         // Dependency for the output
       
  2211         if(!tmp_dep.isEmpty())
       
  2212 	    deps = tmp_dep;
       
  2213 	if(!tmp_dep_cmd.isEmpty()) {
       
  2214             // Execute dependency command, and add every line as a dep
       
  2215 	    char buff[256];
       
  2216 	    QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd,
       
  2217 							             Option::fixPathToLocalOS(inFile, true, false),
       
  2218                                                                      out);
       
  2219             if(Project->canExecute(dep_cmd)) {
       
  2220                 if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) {
       
  2221                     QString indeps;
       
  2222                     while(!feof(proc)) {
       
  2223                         int read_in = (int)fread(buff, 1, 255, proc);
       
  2224                         if(!read_in)
       
  2225                             break;
       
  2226                         indeps += QByteArray(buff, read_in);
       
  2227                     }
       
  2228                     QT_PCLOSE(proc);
       
  2229                     if(!indeps.isEmpty()) {
       
  2230                         QStringList extradeps = indeps.split(QLatin1Char('\n'));
       
  2231                         for (int i = 0; i < extradeps.count(); ++i) {
       
  2232                             QString dd = extradeps.at(i).simplified();
       
  2233                             if (!dd.isEmpty())
       
  2234                                 deps += Project->fileFixify(dd);
       
  2235                         }
       
  2236                     }
       
  2237                 }
       
  2238             }
       
  2239         }
       
  2240         for (int i = 0; i < deps.count(); ++i)
       
  2241 	    deps[i] = Option::fixPathToTargetOS(
       
  2242                         Project->replaceExtraCompilerVariables(deps.at(i), inFile, out),
       
  2243                         false).trimmed();
       
  2244         // Command for file
       
  2245         if (combined) {
       
  2246             // Add dependencies for each file
       
  2247             QStringList tmp_in = Project->project->variables()[extraCompilerName + ".input"];
       
  2248             for (int a = 0; a < tmp_in.count(); ++a) {
       
  2249                 const QStringList &files = Project->project->variables()[tmp_in.at(a)];
       
  2250                 for (int b = 0; b < files.count(); ++b) {
       
  2251                     deps += Project->findDependencies(files.at(b));
       
  2252                     inputs += Option::fixPathToTargetOS(files.at(b), false);
       
  2253                 }
       
  2254             }
       
  2255             deps += inputs; // input files themselves too..
       
  2256 
       
  2257             // Replace variables for command w/all input files
       
  2258             // ### join gives path issues with directories containing spaces!
       
  2259             cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
       
  2260                                                          inputs.join(" "),
       
  2261                                                          out);
       
  2262         } else {
       
  2263             deps += inFile; // input file itself too..
       
  2264             cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
       
  2265                                                          inFile,
       
  2266                                                          out);
       
  2267         }
       
  2268         // Name for command
       
  2269 	if(!tmp_cmd_name.isEmpty()) {
       
  2270 	    cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out);
       
  2271 	} else {
       
  2272 	    int space = cmd.indexOf(' ');
       
  2273 	    if(space != -1)
       
  2274 		cmd_name = cmd.left(space);
       
  2275 	    else
       
  2276 		cmd_name = cmd;
       
  2277 	    if((cmd_name[0] == '\'' || cmd_name[0] == '"') &&
       
  2278 		cmd_name[0] == cmd_name[cmd_name.length()-1])
       
  2279 		cmd_name = cmd_name.mid(1,cmd_name.length()-2);
       
  2280 	}
       
  2281 
       
  2282         // Fixify paths
       
  2283         for (int i = 0; i < deps.count(); ++i)
       
  2284             deps[i] = Option::fixPathToTargetOS(deps[i], false);
       
  2285 
       
  2286 
       
  2287         // Output in info.additionalFile -----------
       
  2288         if (!CustomBuildTool.Description.isEmpty())
       
  2289             CustomBuildTool.Description += " & ";
       
  2290         CustomBuildTool.Description += cmd_name;
       
  2291         CustomBuildTool.CommandLine += cmd.trimmed().split("\n", QString::SkipEmptyParts);
       
  2292         int space = cmd.indexOf(' ');
       
  2293         QFileInfo finf(cmd.left(space));
       
  2294         if (CustomBuildTool.ToolPath.isEmpty())
       
  2295             CustomBuildTool.ToolPath += Option::fixPathToTargetOS(finf.path());
       
  2296         CustomBuildTool.Outputs += out;
       
  2297 
       
  2298         deps += CustomBuildTool.AdditionalDependencies;
       
  2299         deps += cmd.left(cmd.indexOf(' '));
       
  2300         // Make sure that all deps are only once
       
  2301         QMap<QString, bool> uniqDeps;
       
  2302         for (int c = 0; c < deps.count(); ++c) {
       
  2303             QString aDep = deps.at(c).trimmed();
       
  2304             if (!aDep.isEmpty())
       
  2305                 uniqDeps[aDep] = false;
       
  2306         }
       
  2307         CustomBuildTool.AdditionalDependencies = uniqDeps.keys();
       
  2308     }
       
  2309 
       
  2310     // Ensure that none of the output files are also dependencies. Or else, the custom buildstep
       
  2311     // will be rebuild every time, even if nothing has changed.
       
  2312     foreach(QString output, CustomBuildTool.Outputs) {
       
  2313         CustomBuildTool.AdditionalDependencies.removeAll(output);
       
  2314     }
       
  2315 
       
  2316     useCustomBuildTool = !CustomBuildTool.CommandLine.isEmpty();
       
  2317     return useCustomBuildTool;
       
  2318 }
       
  2319 
       
  2320 void VCFilter::outputFileConfig(XmlOutput &xml, const QString &filename)
       
  2321 {
       
  2322     // Clearing each filter tool
       
  2323     useCustomBuildTool = false;
       
  2324     useCompilerTool = false;
       
  2325     CustomBuildTool = VCCustomBuildTool();
       
  2326     CompilerTool = VCCLCompilerTool();
       
  2327 
       
  2328     // Unset some default options
       
  2329     CompilerTool.BufferSecurityCheck = unset;
       
  2330     CompilerTool.DebugInformationFormat = debugUnknown;
       
  2331     CompilerTool.ExceptionHandling = ehDefault;
       
  2332     CompilerTool.GeneratePreprocessedFile = preprocessUnknown;
       
  2333     CompilerTool.Optimization = optimizeDefault;
       
  2334     CompilerTool.ProgramDataBaseFileName.clear();
       
  2335     CompilerTool.RuntimeLibrary = rtUnknown;
       
  2336     CompilerTool.WarningLevel = warningLevelUnknown;
       
  2337     CompilerTool.config = Config;
       
  2338 
       
  2339     bool inBuild = false;
       
  2340     VCFilterFile info;
       
  2341     for (int i = 0; i < Files.count(); ++i) {
       
  2342         if (Files.at(i).file == filename) {
       
  2343             info = Files.at(i);
       
  2344             inBuild = true;
       
  2345         }
       
  2346     }
       
  2347     inBuild &= !info.excludeFromBuild;
       
  2348 
       
  2349     if (inBuild) {
       
  2350         addExtraCompiler(info);
       
  2351         if(Project->usePCH)
       
  2352             modifyPCHstage(info.file);
       
  2353     } else {
       
  2354         // Excluded files uses an empty compiler stage
       
  2355         if(info.excludeFromBuild)
       
  2356             useCompilerTool = true;
       
  2357     }
       
  2358 
       
  2359     // Actual XML output ----------------------------------
       
  2360     if(useCustomBuildTool || useCompilerTool || !inBuild) {
       
  2361         xml << tag(_FileConfiguration)
       
  2362                 << attr(_Name, (*Config).Name)
       
  2363                 << (!inBuild ? attrS(_ExcludedFromBuild, "true") : noxml());
       
  2364         if (useCustomBuildTool)
       
  2365             xml << CustomBuildTool;
       
  2366         if (useCompilerTool)
       
  2367             xml << CompilerTool;
       
  2368         xml << closetag(_FileConfiguration);
       
  2369     }
       
  2370 }
       
  2371 
       
  2372 XmlOutput &operator<<(XmlOutput &xml, VCFilter &tool)
       
  2373 {
       
  2374     if(!tool.Files.count())
       
  2375         return xml;
       
  2376 
       
  2377     if (!tool.Name.isEmpty()) {
       
  2378         xml << tag(_Filter)
       
  2379                 << attrS(_Name, tool.Name)
       
  2380                 << attrS(_Filter, tool.Filter)
       
  2381                 << attrS(_UniqueIdentifier, tool.Guid)
       
  2382                 << attrT(_ParseFiles, tool.ParseFiles);
       
  2383     }
       
  2384     for (int i = 0; i < tool.Files.count(); ++i) {
       
  2385         const VCFilterFile &info = tool.Files.at(i);
       
  2386         xml << tag(q_File)
       
  2387                 << attrS(_RelativePath, Option::fixPathToLocalOS(info.file))
       
  2388             << data(); // In case no custom builds, to avoid "/>" endings
       
  2389         tool.outputFileConfig(xml, tool.Files.at(i).file);
       
  2390         xml << closetag(q_File);
       
  2391     }
       
  2392     if (!tool.Name.isEmpty())
       
  2393         xml << closetag(_Filter);
       
  2394     return xml;
       
  2395 }
       
  2396 
       
  2397 // VCProjectSingleConfig --------------------------------------------
       
  2398 VCFilter nullFilter;
       
  2399 VCFilter& VCProjectSingleConfig::filterForExtraCompiler(const QString &compilerName)
       
  2400 {
       
  2401     for (int i = 0; i < ExtraCompilersFiles.count(); ++i)
       
  2402         if (ExtraCompilersFiles.at(i).Name == compilerName)
       
  2403             return ExtraCompilersFiles[i];
       
  2404     return nullFilter;
       
  2405 }
       
  2406 
       
  2407 
       
  2408 XmlOutput &operator<<(XmlOutput &xml, const VCProjectSingleConfig &tool)
       
  2409 {
       
  2410     xml << decl("1.0", "Windows-1252")
       
  2411         << tag(_VisualStudioProject)
       
  2412             << attrS(_ProjectType, "Visual C++")
       
  2413             << attrS(_Version, tool.Version)
       
  2414             << attrS(_Name, tool.Name)
       
  2415             << attrS(_ProjectGUID, tool.ProjectGUID)
       
  2416             << attrS(_Keyword, tool.Keyword)
       
  2417             << attrS(_SccProjectName, tool.SccProjectName)
       
  2418             << attrS(_SccLocalPath, tool.SccLocalPath)
       
  2419             << tag(_Platforms)
       
  2420                 << tag(_Platform)
       
  2421                     << attrS(_Name, tool.PlatformName)
       
  2422             << closetag(_Platforms)
       
  2423             << tag(_Configurations)
       
  2424             << tool.Configuration;
       
  2425     xml     << closetag(_Configurations)
       
  2426             << tag(q_Files);
       
  2427     // Add this configuration into a multi-config project, since that's where we have the flat/tree
       
  2428     // XML output functionality
       
  2429     VCProject tempProj;
       
  2430     tempProj.SingleProjects += tool;
       
  2431     tempProj.outputFilter(xml, "Sources");
       
  2432     tempProj.outputFilter(xml, "Headers");
       
  2433     tempProj.outputFilter(xml, "GeneratedFiles");
       
  2434     tempProj.outputFilter(xml, "LexYaccFiles");
       
  2435     tempProj.outputFilter(xml, "TranslationFiles");
       
  2436     tempProj.outputFilter(xml, "FormFiles");
       
  2437     tempProj.outputFilter(xml, "ResourceFiles");
       
  2438     for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) {
       
  2439         tempProj.outputFilter(xml, tempProj.ExtraCompilers.at(x));
       
  2440     }
       
  2441     tempProj.outputFilter(xml, "RootFiles");
       
  2442     xml     << closetag(q_Files)
       
  2443             << tag(_Globals)
       
  2444                 << data(); // No "/>" end tag
       
  2445     return xml;
       
  2446 }
       
  2447 
       
  2448 
       
  2449 // Tree file generation ---------------------------------------------
       
  2450 void TreeNode::generateXML(XmlOutput &xml, const QString &tagName, VCProject &tool, const QString &filter) {
       
  2451     if (children.size()) {
       
  2452         // Filter
       
  2453         ChildrenMap::ConstIterator it, end = children.constEnd();
       
  2454         if (!tagName.isEmpty()) {
       
  2455             xml << tag("Filter")
       
  2456                 << attr("Name", tagName)
       
  2457                 << attr("Filter", "");
       
  2458         }
       
  2459         // First round, do nested filters
       
  2460         for (it = children.constBegin(); it != end; ++it)
       
  2461             if ((*it)->children.size())
       
  2462                 (*it)->generateXML(xml, it.key(), tool, filter);
       
  2463         // Second round, do leafs
       
  2464         for (it = children.constBegin(); it != end; ++it)
       
  2465             if (!(*it)->children.size())
       
  2466                 (*it)->generateXML(xml, it.key(), tool, filter);
       
  2467 
       
  2468         if (!tagName.isEmpty())
       
  2469             xml << closetag("Filter");
       
  2470     } else {
       
  2471         // Leaf
       
  2472         tool.outputFileConfigs(xml, info, filter);
       
  2473     }
       
  2474 }
       
  2475 
       
  2476 
       
  2477 // Flat file generation ---------------------------------------------
       
  2478 void FlatNode::generateXML(XmlOutput &xml, const QString &/*tagName*/, VCProject &tool, const QString &filter) {
       
  2479     if (children.size()) {
       
  2480         ChildrenMapFlat::ConstIterator it = children.constBegin();
       
  2481         ChildrenMapFlat::ConstIterator end = children.constEnd();
       
  2482         for (; it != end; ++it) {
       
  2483             tool.outputFileConfigs(xml, (*it), filter);
       
  2484         }
       
  2485     }
       
  2486 }
       
  2487 
       
  2488 
       
  2489 // VCProject --------------------------------------------------------
       
  2490 // Output all configurations (by filtername) for a file (by info)
       
  2491 // A filters config output is in VCFilter.outputFileConfig()
       
  2492 void VCProject::outputFileConfigs(XmlOutput &xml,
       
  2493 //                                  VCProjectSingleConfig::FilterTypes type
       
  2494                                   const VCFilterFile &info,
       
  2495                                   const QString &filtername)
       
  2496 {
       
  2497     xml << tag(q_File)
       
  2498             << attrS(_RelativePath, Option::fixPathToLocalOS(info.file));
       
  2499     for (int i = 0; i < SingleProjects.count(); ++i) {
       
  2500         VCFilter filter;
       
  2501         if (filtername == "RootFiles") {
       
  2502             filter = SingleProjects.at(i).RootFiles;
       
  2503         } else if (filtername == "Sources") {
       
  2504             filter = SingleProjects.at(i).SourceFiles;
       
  2505         } else if (filtername == "Headers") {
       
  2506             filter = SingleProjects.at(i).HeaderFiles;
       
  2507         } else if (filtername == "GeneratedFiles") {
       
  2508             filter = SingleProjects.at(i).GeneratedFiles;
       
  2509         } else if (filtername == "LexYaccFiles") {
       
  2510             filter = SingleProjects.at(i).LexYaccFiles;
       
  2511         } else if (filtername == "TranslationFiles") {
       
  2512             filter = SingleProjects.at(i).TranslationFiles;
       
  2513         } else if (filtername == "FormFiles") {
       
  2514             filter = SingleProjects.at(i).FormFiles;
       
  2515         } else if (filtername == "ResourceFiles") {
       
  2516             filter = SingleProjects.at(i).ResourceFiles;
       
  2517         } else {
       
  2518             // ExtraCompilers
       
  2519             filter = SingleProjects[i].filterForExtraCompiler(filtername);
       
  2520         }
       
  2521 
       
  2522         if (filter.Config) // only if the filter is not empty
       
  2523             filter.outputFileConfig(xml, info.file);
       
  2524     }
       
  2525     xml << closetag(q_File);
       
  2526 }
       
  2527 
       
  2528 // outputs a given filter for all existing configurations of a project
       
  2529 void VCProject::outputFilter(XmlOutput &xml,
       
  2530 //                             VCProjectSingleConfig::FilterTypes type
       
  2531                              const QString &filtername)
       
  2532 {
       
  2533     Node *root;
       
  2534     if (SingleProjects.at(0).flat_files)
       
  2535         root = new FlatNode;
       
  2536     else
       
  2537         root = new TreeNode;
       
  2538 
       
  2539     QString name, extfilter, guid;
       
  2540     triState parse;
       
  2541 
       
  2542     for (int i = 0; i < SingleProjects.count(); ++i) {
       
  2543         VCFilter filter;
       
  2544         if (filtername == "RootFiles") {
       
  2545             filter = SingleProjects.at(i).RootFiles;
       
  2546         } else if (filtername == "Sources") {
       
  2547             filter = SingleProjects.at(i).SourceFiles;
       
  2548         } else if (filtername == "Headers") {
       
  2549             filter = SingleProjects.at(i).HeaderFiles;
       
  2550         } else if (filtername == "GeneratedFiles") {
       
  2551             filter = SingleProjects.at(i).GeneratedFiles;
       
  2552         } else if (filtername == "LexYaccFiles") {
       
  2553             filter = SingleProjects.at(i).LexYaccFiles;
       
  2554         } else if (filtername == "TranslationFiles") {
       
  2555             filter = SingleProjects.at(i).TranslationFiles;
       
  2556         } else if (filtername == "FormFiles") {
       
  2557             filter = SingleProjects.at(i).FormFiles;
       
  2558         } else if (filtername == "ResourceFiles") {
       
  2559             filter = SingleProjects.at(i).ResourceFiles;
       
  2560         } else {
       
  2561             // ExtraCompilers
       
  2562             filter = SingleProjects[i].filterForExtraCompiler(filtername);
       
  2563         }
       
  2564 
       
  2565         // Merge all files in this filter to root tree
       
  2566         for (int x = 0; x < filter.Files.count(); ++x)
       
  2567             root->addElement(filter.Files.at(x));
       
  2568 
       
  2569         // Save filter setting from first filter. Next filters
       
  2570         // may differ but we cannot handle that. (ex. extfilter)
       
  2571         if (name.isEmpty()) {
       
  2572             name = filter.Name;
       
  2573             extfilter = filter.Filter;
       
  2574             parse = filter.ParseFiles;
       
  2575             guid = filter.Guid;
       
  2576         }
       
  2577     }
       
  2578 
       
  2579     if (!root->hasElements())
       
  2580         return;
       
  2581 
       
  2582     // Actual XML output ----------------------------------
       
  2583     if (!name.isEmpty()) {
       
  2584         xml << tag(_Filter)
       
  2585                 << attrS(_Name, name)
       
  2586                 << attrS(_Filter, extfilter)
       
  2587                 << attrS(_UniqueIdentifier, guid)
       
  2588                 << attrT(_ParseFiles, parse);
       
  2589     }
       
  2590     root->generateXML(xml, "", *this, filtername); // output root tree
       
  2591     if (!name.isEmpty())
       
  2592         xml << closetag(_Filter);
       
  2593 }
       
  2594 
       
  2595 XmlOutput &operator<<(XmlOutput &xml, VCProject &tool)
       
  2596 {
       
  2597     if (tool.SingleProjects.count() == 0) {
       
  2598         warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output");
       
  2599         return xml;
       
  2600     }
       
  2601 
       
  2602     xml << decl("1.0", "Windows-1252")
       
  2603         << tag(_VisualStudioProject)
       
  2604             << attrS(_ProjectType, "Visual C++")
       
  2605             << attrS(_Version, tool.Version)
       
  2606             << attrS(_Name, tool.Name)
       
  2607             << attrS(_ProjectGUID, tool.ProjectGUID)
       
  2608             << attrS(_Keyword, tool.Keyword)
       
  2609             << attrS(_SccProjectName, tool.SccProjectName)
       
  2610             << attrS(_SccLocalPath, tool.SccLocalPath)
       
  2611             << tag(_Platforms)
       
  2612                 << tag(_Platform)
       
  2613                     << attrS(_Name, tool.PlatformName)
       
  2614             << closetag(_Platforms)
       
  2615             << tag(_Configurations);
       
  2616     // Output each configuration
       
  2617     for (int i = 0; i < tool.SingleProjects.count(); ++i)
       
  2618         xml     << tool.SingleProjects.at(i).Configuration;
       
  2619     xml     << closetag(_Configurations)
       
  2620             << tag(q_Files);
       
  2621     tool.outputFilter(xml, "Sources");
       
  2622     tool.outputFilter(xml, "Headers");
       
  2623     tool.outputFilter(xml, "GeneratedFiles");
       
  2624     tool.outputFilter(xml, "LexYaccFiles");
       
  2625     tool.outputFilter(xml, "TranslationFiles");
       
  2626     tool.outputFilter(xml, "FormFiles");
       
  2627     tool.outputFilter(xml, "ResourceFiles");
       
  2628     for (int x = 0; x < tool.ExtraCompilers.count(); ++x) {
       
  2629         tool.outputFilter(xml, tool.ExtraCompilers.at(x));
       
  2630     }
       
  2631     tool.outputFilter(xml, "RootFiles");
       
  2632     xml     << closetag(q_Files)
       
  2633             << tag(_Globals)
       
  2634             << data(); // No "/>" end tag
       
  2635     return xml;
       
  2636 }
       
  2637 
       
  2638 QT_END_NAMESPACE