use strict; no strict 'refs'; ###################################################### # Data Section ###################################################### my(@lines) = (); # holds the input file my(@tabs) = (); # for indentation my(@lineToPrint) = (); # current formatted output line #my(@configOutput) = (); # output from configuration parsing my(%configOutput) = (); # hash of configuration-specific config options my($currentConfig) = ""; # configuration currently being parsed my($nameFound) = 0; # flag set when project name has been parsed my($lineCt) = 0; # current line number in the source file my($exclusionsFound) = 0; # an file has been 'excluded from build' for some configuration my($projectName) = ""; # base name of the project my($parsingFiles) = 0; # a cheap state variable my($splitConfigs) = 0; # debug variable set from the commmand line my($outputPath) = undef;# optional path for the vpc destination my($spaceBeforeFolder) = 0; # tracks when to add a line before folder blocks my($spaceBeforeFile) = 0; # tracks when to add a line before file blocks my($tabstop) = 4; # size of tabs - 4 for visual studio my($srcdirBackslash) = undef;# holds the value of the macro SRCDIR, with \ separators my($srcdirForwardslash) = undef;# holds the value of the macro SRCDIR, with / separators my($usestring) = 1; # use string values for compiler options my($stripEmptyOptions) = 1; # remove compiler options that have empty values (strings) if ( $ARGV[1] =~ /useindex/ ) { $usestring = 0; } elsif ( $ARGV[1] =~ /allownullstrings/ ) { $stripEmptyOptions = 0; } elsif ( $ARGV[1] =~ /-o/ ) { $outputPath = $ARGV[2]; } ############################################################################## # Match vcproj option keywords with vpc keywords - only string value options # String on the left matches the option name in the VCProj. # String on the right matches the option name in vpc my(%configOptionsSingleValue) = ( # Configuration "General" => { # General "OutputDirectory" => "OutputDirectory", "IntermediateDirectory" => "IntermediateDirectory", "DeleteExtensionsOnClean" => "ExtensionsToDeleteOnClean", "BuildLogFile" => "BuildLogFile", "ATLMinimizesCRunTimeLibraryUsage" => "MinimizeCRTUseInATL", "ManagedExtensions" => "UseManagedExtensions", "WholeProgramOptimization" => "WholeProgramOptimization", "ReferencesPath" => "ReferencesPath", "ExcludedFromBuild" => "ExcludedFromBuild", # Debugging }, # C/C++ "VCCLCompilerTool" => { # General "AdditionalIncludeDirectories" => "AdditionalIncludeDirectories", "AdditionalUsingDirectories" => "ResolveUsingReferences", # Optimization # Preprocessor "PreprocessorDefinitions" => "PreprocessorDefinitions", # Code Generation # Language # Precompiled Headers "PrecompiledHeaderThrough" => "Create/UsePCHThroughFile", "PrecompiledHeaderFile" => "PrecompiledHeaderFile", # Output Files "AssemblerListingLocation" => "ASMListLocation", "ObjectFile" => "ObjectFileName", "ProgramDataBaseFileName" => "ProgramDatabaseFileName", "XMLDocumentationFileName" => "XMLDocumentationFileName", # Browse Information "BrowseInformationFile" => "BrowseFile", # Advanced "DisableSpecificWarnings" => "DisableSpecificWarnings", "ForcedIncludeFiles" => "ForceIncludes", "ForcedUsingFiles" => "ForceUsing", "UndefinePreprocessorDefinitions" => "UndefinePreprocessorDefinitions", # Command Line "AdditionalOptions" => "AdditionalOptions", }, # Librarian "VCLibrarianTool" => { # General "OutputFile" => "OutputFileexplo", "AdditionalDependencies" => "AdditionalDependencies", "AdditionalLibraryDirectories" => "AdditionalLibraryDirectories", "ModuleDefinitionFile" => "ModuleDefinitionFileName", "IgnoreDefaultLibraryNames" => "IgnoreSpecificLibrary", "ExportNamedFunctions" => "ExportNamedFunctions", "ForceSymbolReferences" => "ForceSymbolReferences", # Command LIne "AdditionalOptions" => "AdditionalOptions", }, # Linker "VCLinkerTool" => { # General "OutputFile" => "OutputFile", "Version" => "Version", "AdditionalLibraryDirectories" => "AdditionalLibraryDirectories", # Input "AdditionalDependencies" => "AdditionalDependencies", "IgnoreDefaultLibraryNames" => "IgnoreSpecificLibrary", "ModuleDefinitionFile" => "ModuleDefinitionFile", "AddModuleNamesToAssembly" => "AddModuleToAssembly", "EmbedManagedResourceFile" => "EmbedManagedResourceFile", "ForceSymbolReferences" => "ForceSymbolReferences", "DelayLoadDLLs" => "DelayLoadedDLLs", "AssemblyLinkResource" => "AssemblyLinkResource", # Manifest File "ManifestFile" => "ManifestFile", "AdditionalManifestDependencies" => "AdditionalManifestDependencies", # Debugging "ProgramDatabaseFile" => "GenerateProgramDatabaseFile", "StripPrivateSymbols" => "StripPrivateSymbols", "MapFileName" => "MapFileName", # System "HeapReserveSize" => "HeapReserverSize", "HeapCommitSize" => "HeapCommitSize", "StackReserveSize" => "StackReserveSize", "StackCommitSize" => "StackCommitSize", # Optimization "FunctionOrder" => "FunctionOrder", "ProfileGuidedDatabase" => "ProfileGuidedDatabase", # Embedded IDL "MidlCommandFile" => "MIDLCommands", "MergedIDLBaseFileName" => "MergedIDLBaseFileName", "TypeLibraryFile" => "TypeLibrary", "TypeLibraryResourceID" => "TypeLibResourceID", # Advanced "EntryPointSymbol" => "EntryPoint", "BaseAddress" => "BaseAddress", "ImportLibrary" => "ImportLibrary", "MergeSections" => "MergeSections", "KeyFile" => "KeyFile", "KeyContainer" => "KeyContainer", # Command LIne "AdditionalOptions" => "AdditionalOptions", }, # Resources "VCResourceCompilerTool" => { # General "PreprocessorDefinitions" => "PreprocessorDefinitions", "AdditionalIncludeDirectories" => "AdditionalIncludeDirectories", "ResourceOutputFileName" => "ResourceFileName", # Command LIne "AdditionalOptions" => "AdditionalOptions", }, # Build Events "VCPreBuildEventTool" => { # Pre-Build Event "CommandLine" => "CommandLine", "Description" => "Description", "ExcludedFromBuild" => "ExcludedFromBuild", }, "VCPreLinkEventTool" => { # Pre-Link Event "CommandLine" => "CommandLine", "Description" => "Description", "ExcludedFromBuild" => "ExcludedFromBuild", }, "VCPostBuildEventTool" => { # Post-Build Event "CommandLine" => "CommandLine", "Description" => "Description", "ExcludedFromBuild" => "ExcludedFromBuild", }, # Custom Build Step "VCCustomBuildTool" => { # Pre-Build Event "CommandLine" => "CommandLine", "Description" => "Description", "Outputs" => "Outputs", "AdditionalDependencies" => "AdditionalDependencies", }, ); ############################################################################## # Match vcproj option keywords with vpc keywords - only multi-value options # String on the left matches the option name in the VCProj. # String on the right matches the option name in vpc my(%configOptionsMultiValue) = ( # General "ConfigurationType" => "ConfigurationType", "UseOfMFC" => "UseOfMFC", "UseOfAtl" => "UseOfATL", "CharacterSet" => "CharacterSet", # Debugging # C/C++ # General "DebugInformationFormat" => "DebugInformationFormat", "SuppressStartupBanner" => "SuppressStartupBanner", "WarningLevel" => "WarningLevel", "Detect64BitPortabilityProblems" => "Detect64BitPortabilityIssues", "WarnAsError" => "TreatWarningsAsErrors", "UseUnicodeResponseFiles" => "UseUNICODEResponseFiles", # Optimization "Optimization" => "Optimization", "InlineFunctionExpansion" => "InlineFunctionExpansion", "EnableIntrinsicFunctions" => "EnableIntrinsicFunctions", "FavorSizeOrSpeed" => "FavorSizeOrSpeed", "OmitFramePointers" => "OmitFramePointers", "EnableFiberSafeOptimizations" => "EnableFiberSafeOptimizations", "WholeProgramOptimization" => "WholeProgramOptimization", # Preprocessor "IgnoreStandardIncludePath" => "IgnoreStandardIncludePath", "GeneratePreprocessedFile" => "GeneratePreprocessedFile", "KeepComments" => "KeepComments", # Code Generation "StringPooling" => "EnableStringPooling", "MinimalRebuild" => "EnableMinimalRebuild", "ExceptionHandling" => "EnableC++Exceptions", "SmallerTypeCheck" => "SmallerTypeCheck", "BasicRuntimeChecks" => "BasicRuntimeChecks", "RuntimeLibrary" => "RuntimeLibrary", "StructMemberAlignment" => "StructMemberAlignement", "BufferSecurityCheck" => "BufferSecurityCheck", "EnableFunctionLevelLinking" => "EnableFunctionLevelLinking", "EnableEnhancedInstructionSet" => "EnableEnhancedInstructionSet", "FloatingPointModel" => "FloatingPointModel", "FloatingPointExceptions" => "EnableFloatingPointExceptions", # Language "DisableLanguageExtensions" => "DisableLanguageExtensions", "DefaultCharIsUnsigned" => "DefaultCharUnsigned", "TreatWChar_tAsBuiltInType" => "TreatWchar_tAsBuiltinType", "ForceConformanceInForLoopScope" => "ForceConformanceInForLoopScope", "RuntimeTypeInfo" => "EnableRunTimeTypeInfo", "OpenMP" => "OpenMPSupport", # Precompiled Headers "UsePrecompiledHeader" => "Create/UsePrecompiledHeader", # Output Files "ExpandAttributedSource" => "ExpandAttributedSource", "AssemblerOutput" => "AssemblerOutput", "GenerateXMLDocumentationFiles" => "GenerateXMLDocumentationFiles", # Browse Information "BrowseInformation" => "EnableBrowseInformation", # Advanced "CallingConvention" => "CallingConvention", "CompileAs" => "CompileAs", "UndefineAllPreprocessorDefinitions" => "UndefineAllPreprocessorDefinitions", "UseFullPaths" => "UseFullPaths", "OmitDefaultLibName" => "OmitDefaultLibraryNames", "ErrorReporting" => "ErrorReporting", # Librarian # General "SuppressStartupBanner" => "SuppressStartupBanner", "IgnoreAllDefaultLibraries" => "IgnoreAllDefaultLibraries", "UseUnicodeResponseFiles" => "UseUNICODEResponseFiles", "LinkLibraryDependencies" => "LinkLibraryDependencies", # Linker # General "ShowProgress" => "ShowProgress", "LinkIncremental" => "EnableIncrementalLinking", "SuppressStartupBanner" => "SuppressStartupBanner", "IgnoreImportLibrary" => "IgnoreImportLibrary", "RegisterOutput" => "RegisterOutput", "LinkLibraryDependencies" => "LinkLibraryDependencies", "UseLibraryDependencyInputs" => "UseLibraryDependencyInputs", "UseUnicodeResponseFiles" => "UseUNICODEResponseFiles", # Input "IgnoreAllDefaultLibraries" => "IgnoreAllDefaultLibraries", # Manifest File "GenerateManifest" => "GenerateManifest", "AllowIsolation" => "AllowIsolation", # Debugging "GenerateDebugInformation" => "GenerateDebugInfo", "GenerateMapFile" => "GenerateMapFile", "MapExports" => "MapExports", "AssemblyDebug" => "DebuggableAssembly", # System "SubSystem" => "SubSystem", "LargeAddressAware" => "EnableLargeAddresses", "TerminalServerAware" => "TerminalServer", "SwapRunFromCD" => "SwapRunFromCD", "SwapRunFromNet" => "SwapRunFromNetwork", "Driver" => "Driver", # Optimization "OptimizeReferences" => "References", "EnableCOMDATFolding" => "EnableCOMDATFolding", "OptimizeForWindows98" => "OptimizeForWindows98", "LinkTimeCodeGeneration" => "LinkTimeCodeGeneration", # Embedded IDL "IgnoreEmbeddedIDL" => "IgnoreEmbeddedIDL", # Advanced "ResourceOnlyDLL" => "NoEntryPoint", "SetChecksum" => "SetChecksum", "FixedBaseAddress" => "FixedBaseAddress", "TurnOffAssemblyGeneration" => "TurnOffAssemblyGeneration", "SupportUnloadOfDelayLoadedDLL" => "DelayLoadedDLL", "TargetMachine" => "TargetMachine", "Profile" => "Profile", "CLRThreadAttribute" => "CLRThreadAttribute", "CLRImageType" => "CLRImageType", "DelaySign" => "DelaySign", "ErrorReporting" => "ErrorReporting", "CLRUnmanagedCodeCheck" => "CLRUnmanagedCodeCheck", # Resources # General "Culture" => "Culture", "IgnoreStandardIncludePath" => "IgnoreStandardIncludePath", "ShowProgress" => "ShowProgress", ); ############################################################################## # Match user option names to their lists of possible values my(%configOptionValues) = ( # General "ConfigurationType" => { "0" => "Makefile", "1" => "Application \(\.exe\)", "2" => "Dynamic Library \(\.dll\)", "3" => "Static Library \(\.lib\)", "4" => "Utility", }, "UseOfMFC" => { "0" => "Use Standard Windows Libraries", "1" => "Use MFC In A Static Library", "2" => "Use MFC In A Shared DLL", }, "UseOfATL" => { "0" => "Not Using ATL", "1" => "Static Link To ATL", "2" => "Dynamic Link To ATL", }, "CharacterSet" => { "0" => "Not Set", "1" => "Use Unicode Character Set", "2" => "Use Multi-Byte Character Set", }, # Debugging # C/C++ # General "DebugInformationFormat" => { # These skip a number on purpose (per VS2005) "0" => "Disabled", "1" => "C7 Compatible \(\/Z7\)", "3" => "Program Database \(\/Zi\)", "4" => "Program Database for Edit & Continue \(\/ZI\)", }, "SuppressStartupBanner" => { "false" => "No", "true" => "Yes \(\/nologo\)", }, "WarningLevel" => { "0" => "Off: Turn Off All Warnings \(\/W0\)", "1" => "Level 1 \(\/W1\)", "2" => "Level 2 \(\/W2\)", "3" => "Level 3 \(\/W3\)", "4" => "Level 4 \(\/W4\)", }, "Detect64BitPortabilityProblems" => { "false" => "No", "true" => "Yes \(\/Wp64\)", }, "WarnAsError" => { "false" => "No", "true" => "Yes \(\/WX\)", }, "UseUnicodeResponseFiles" => { "false" => "No", "true" => "Yes", }, # Optimization "Optimization" => { "0" => "Disabled \(\/Od\)", "1" => "Minimize Size \(\/O1\)", "2" => "Maximize Speed \(\/O2\)", "3" => "Full Optimization \(\/Ox\)", "4" => "Custom", }, "InlineFunctionExpansion" => { "0" => "Default", "1" => "Only __inline \(\/Ob1\)", "2" => "Any Suitable \(\/Ob2\)", }, "EnableIntrinsicFunctions" => { "false" => "No", "true" => "Yes \(\/Oi\)", }, "FavorSizeOrSpeed" => { "0" => "Neither", "1" => "Favor Fast Code \(\/Ot\)", "2" => "Favor Small Code \(\/Os\)", }, "OmitFramePointers" => { "false" => "No", "true" => "Yes \(\/Oy\)", }, "EnableFiberSafeOptimizations" => { "false" => "No", "true" => "Yes \(\/GT\)", }, "WholeProgramOptimization" => { "false" => "No", "true" => "Enable link-time code generation \(\/GL\)", }, # Preprocessor "IgnoreStandardIncludePath" => { "false" => "No", "true" => "Yes \(\/X\)", }, "GeneratePreprocessedFile" => { "0" => "No", "1" => "With Line Numbers \(\/P\)", "2" => "Without Line Numbers \(\/EP \/P\)", }, "KeepComments" => { "false" => "No", "true" => "Yes \(\/C\)", }, # Code Generation "StringPooling" => { "false" => "No", "true" => "Yes \(\/GF\)", }, "MinimalRebuild" => { "false" => "No", "true" => "Yes \(\/Gm\)", }, "ExceptionHandling" => { "0" => "No", "1" => "Yes \(\/EHsc\)", "2" => "Yes With SEH Exceptions \(\/EHa\)", }, "SmallerTypeCheck" => { "false" => "No", "true" => "Yes \(\/RTCc\)", }, "BasicRuntimeChecks" => { "0" => "Default", "1" => "Stack Frames \(\/RTCs\)", "2" => "Uninitialized Variables \(\/RTCu\)", "3" => "Both \(\/RTC1, equiv\. to \/RTCsu\)", }, "RuntimeLibrary" => { "0" => "Multi-threaded \(\/MT\)", "1" => "Multi-threaded Debug \(\/MTd\)", "2" => "Multi-threaded DLL \(\/MD\)", "3" => "Multi-threaded Debug DLL \(\/MDd\)", }, "StructMemberAlignment" => { "0" => "Default", "1" => "1 Byte \(\/Zp1\)", "2" => "2 Bytes \(\/Zp2\)", "3" => "4 Bytes \(\/Zp4\)", "4" => "8 Bytes \(\/Zp8\)", "5" => "16 Bytes \(\/Zp16\)", }, "BufferSecurityCheck" => { "false" => "No (/GS-)", "true" => "Yes", }, "EnableFunctionLevelLinking" => { "false" => "No", "true" => "Yes \(/Gy\)", }, "EnableEnhancedInstructionSet" => { "0" => "Not Set", "1" => "Streaming SIMD Extensions \(\/arch:SSE\)", "2" => "Streaming SIMD Extensions 2 \(\/arch:SSE2\)", }, "FloatingPointModel" => { "0" => "Precise \(\/fp:precise\)", "1" => "Strict \(\/fp:strict\)", "2" => "Fast \(\/fp:fast\)", }, "FloatingPointExceptions" => { "false" => "No", "true" => "Yes \(\/fp:except\)", }, # Language "DisableLanguageExtensions" => { "false" => "No", "true" => "Yes \(/Za\)", }, "DefaultCharIsUnsigned" => { "false" => "No", "true" => "Yes \(\/J\)", }, "TreatWChar_tAsBuiltInType" => { "false" => "No \(\/Zc:wchar_t-\)", "true" => "Yes", }, "ForceConformanceInForLoopScope" => { "false" => "No \(\/Zc:forScope-\)", "true" => "Yes", }, "RuntimeTypeInfo" => { "false" => "No \(\/GR-\)", "true" => "Yes", }, "OpenMP" => { "false" => "No", "true" => "Yes \(\/openmp\)", }, # Precompiled Headers "UsePrecompiledHeader" => { "0" => "Not Using Precompiled Headers", "1" => "Create Precompiled Header \(\/Yc\)", "2" => "Use Precompiled Header \(\/Yu\)", }, # Output Files "ExpandAttributedSource" => { "false" => "No", "true" => "Yes \(\/Fx\)", }, "AssemblerOutput" => { "0" => "No Listing", "1" => "Assembly-Only Listing \(\/FA\)", "2" => "Assembly, Machine Code and Source \(\/FAcs\)", "3" => "Assembly With Machine Code \(\/FAc\)", "4" => "Assembly With Source Code \(\/FAs\)", }, "GenerateXMLDocumentationFiles" => { "false" => "No", "true" => "Yes (/doc)", }, # Browse Information "BrowseInformation" => { "0" => "None", "1" => "Include All Browse Information \(\/FR\)", "2" => "No Local Symbols \(\/Fr\)", }, # Advanced "CallingConvention" => { "0" => "__cdecl \(\/Gd\)", "1" => "__fastcall \(\/Gr\)", "2" => "__stdcall \(\/Gz\)", }, "CompileAs" => { "0" => "Default", "1" => "Compile as C Code \(\/TC\)", "2" => "Compile as C\+\+ Code \(\/TP\)", }, "ShowIncludes" => { "false" => "No", "true" => "Yes \(\/showIncludes\)", }, "UndefineAllPreprocessorDefinitions" => { "false" => "No", "true" => "Yes \(\/u\)", }, "UseFullPaths" => { "false" => "No", "true" => "Yes \(\/FC\)", }, "OmitDefaultLibName" => { "false" => "No", "true" => "Yes \(\/Zl\)", }, "ErrorReporting" => { "0" => "Default", "1" => "Prompt Immediately \(\/errorReport:prompt\)", "2" => "Queue For Next Login \(\/errorReport:queue\)", }, # Librarian # General "SuppressStartupBanner" => { "false" => "No", "true" => "Yes \(\/NOLOGO\)", }, "IgnoreAllDefaultLibraries" => { "false" => "No", "true" => "Yes \(\/NODEFAULTLIB\)", }, "UseUnicodeResponseFiles" => { "false" => "No", "true" => "Yes", }, "LinkLibraryDependencies" => { "false" => "No", "true" => "Yes", }, # Linker #General "ShowProgress" => { "0" => "Not Set", "1" => "Display All Progress Messages \(\/VERBOSE\)", "2" => "Displays Some Progress Messages \(\/VERBOSE:LIB\)", }, "LinkIncremental" => { "0" => "Default", "1" => "No \(\/INCREMENTAL:NO\)", "2" => "Yes \(\/INCREMENTAL\)", }, "SuppressStartupBanner" => { "false" => "No", "true" => "Yes \(\/NOLOGO\)", }, "IgnoreImportLibrary" => { "false" => "No", "true" => "Yes", }, "RegisterOutput" => { "false" => "No", "true" => "Yes", }, "LinkLibraryDependencies" => { "false" => "No", "true" => "Yes", }, "UseLibraryDependencyInputs" => { "false" => "No", "true" => "Yes", }, "UseUnicodeResponseFiles" => { "false" => "No", "true" => "Yes", }, # Input "IgnoreAllDefaultLibraries" => { "false" => "No", "true" => "Yes \(\/NODEFAULTLIB\)", }, # Manifest File "GenerateManifest" => { "false" => "No", "true" => "Yes", }, "AllowIsolation" => { "false" => "Don't allow side-by-side isolation \(\/ALLOWISOLATION:NO\)", "true" => "Yes", }, # Debugging "GenerateDebugInformation" => { "false" => "No", "true" => "Yes \(\/DEBUG\)", }, "GenerateMapFile" => { "false" => "No", "true" => "Yes \(\/MAP\)", }, "MapExports" => { "false" => "No", "true" => "Yes \(\/MAPINFO:EXPORTS\)", }, "AssemblyDebug" => { "0" => "No Debuggable attribute emitted", "1" => "Runtime tracking and disable optimizations \(\/ASSEMBLYDEBUG\)", "2" => "No runtime tracking and enable optimizations \(\/ASSEMBLYDEBUG:DISABLE\)", }, # System "SubSystem" => { "0" => "Not Set", "1" => "Console \(\/SUBSYSTEM:CONSOLE\)", "2" => "Windows \(\/SUBSYSTEM:WINDOWS\)", "3" => "Native \(\/SUBSYSTEM:NATIVE\)", "4" => "EFI Application \(\/SUBSYSTEM:EFI_APPLICATION\)", "5" => "EFI Boot Service Driver \(\/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER\)", "6" => "EFI ROM \(\/SUBSYSTEM:EFI_ROM\)", "7" => "EFI Runtime \(\/SUBSYSTEM:EFI_RUNTIME_DRIVER\)", "8" => "Posix \(\/SUBSYSTEM:POSIX\)", "9" => "WindowsCE \(\/SUBSYSTEM:WINDOWSCE\)", }, "LargeAddressesAware" => { "0" => "Default", "1" => "Do Not Support Addresses Larger Than 2 Gigabytes \(\/LARGEADDRESSAWARE:NO\)", "2" => "Support Addresses Larger Than 2 Gigabytes \(\/LARGEADDRESSAWARE\)", }, "TerminalServerAware" => { "0" => "Default", "1" => "Not Terminal Server Aware \(\/TSAWARE:NO\)", "2" => "Application is Terminal Server Aware \(\/TSAWARE\)", }, "SwapRunFromCD" => { "false" => "No", "true" => "Yes \(\/SWAPRUN:CD\)", }, "SwapRunFromNet" => { "false" => "No", "true" => "Yes \(\/SWAPRUN:NET\)", }, "Driver" => { "0" => "Not Set", "1" => "Driver \(\/DRIVER\)", "2" => "Up Only \(\/DRIVER:UPONLY\)", "3" => "WDM \(\/DRIVER:WDM\)", }, #Optimization "OptimizeReferences" => { "0" => "Default", "1" => "Keep Unreferenced Data \(\/OPT:NOREF\)", "2" => "Eliminate Unreferenced Data \(\/OPT:REF\)", }, "EnableCOMDATFolding" => { "0" => "Default", "1" => "Do Not Remove Redundant COMDATs \(\/OPT:NOICF\)", "2" => "Remove Redundant COMDATs \(\/OPT:ICF\)", }, "OptimizeForWindows98" => { "0" => "Default", "1" => "No \(\/OPT:NOWIN98\)", "2" => "Yes \(\/OPT:WIN98\)", }, "LinkTimeCodeGeneration" => { "0" => "Default", "1" => "Use Link Time Code Generation \(\/ltcg\)", "2" => "Profile Guided Optimization - Instrument \(\/ltcg:pginstrument\)", "3" => "Profile Guided Optimization - Optimize \(\/ltcg:pgoptimize\)", "4" => "Profile Guided Optimization - Update \(\/ltcg:pgupdate\)", }, # Embedded IDL "IgnoreEmbeddedIDL" => { "false" => "No", "true" => "Yes \(\/IGNOREIDL\)", }, #Advanced "ResourceOnlyDLL" => { "false" => "No", "true" => "Yes \(\/NOENTRY\)", }, "SetChecksum" => { "false" => "No", "true" => "Yes \(\/RELEASE\)", }, "FixedBaseAddress" => { "0" => "Default", "1" => "Generate a relocation section \(\/FIXED:NO\)", "2" => "Image must be loaded at a fixed address \(\/FIXED\)", }, "TurnOffAssemblyGeneration" => { "false" => "No", "true" => "Yes \(\/NOASSEMBLY\)", }, "SupportUnloadOfDelayLoadedDLL" => { "0" => "Don't Support Unload", "1" => "Support Unload \(\/DELAY:UNLOAD\)", }, "TargetMachine" => { "0" => "Not Set", "1" => "MachineX86 \(\/MACHINE:X86\)", "2" => "MachineAM33 \(\/MACHINE:AM33\)", "3" => "MachineARM \(\/MACHINE:ARM\)", "4" => "MachineEBC \(\/MACHINE:EBC\)", "5" => "MachineIA64 \(\/MACHINE:IA64\)", "6" => "MachineM32R \(\/MACHINE:M32R\)", "7" => "MachineMIPS \(\/MACHINE:MIPS\)", "8" => "MachineMIPS16 \(\/MACHINE:MIPS16\)", "9" => "MachineMIPSFPU \(\/MACHINE:MIPSFPU\)", "10" => "MachineMIPSFPU16 \(\/MACHINE:MIPSFPU16\)", "11" => "MachineMIPSR41XX \(\/MACHINE:MIPSR41XX\)", "12" => "MachineSH3 \(\/MACHINE:SH3\)", "13" => "MachineSH4 \(\/MACHINE:SH4\)", "14" => "MachineSH5 \(\/MACHINE:SH5\)", "15" => "MachineTHUMB \(\/MACHINE:THUMB\)", "16" => "MachineX64 \(\/MACHINE:X64\)", }, "Profile" => { "false" => "No", "true" => "Enable Profiling information \(\/PROFILE\)", }, "CLRThreadAttribute" => { "0" => "No threading attribute set", "1" => "MTA threading attribute \(\/CLRTHREADATTRIBUTE:MTA\)", "2" => "STA threading attribute \(\/CLRTHREADATTRIBUTE:STA\)", }, "CLRImageType" => { "0" => "Default image type", "1" => "Force IJW image \(\/CLRIMAGETYPE:IJW\)", "2" => "Force pure IL image \(\/CLRIMAGETYPE:PURE\)", "3" => "Force safe IL image \(\/CLRIMAGETYPE:SAFE\)", }, "DelaySign" => { "false" => "No", "true" => "Yes \(\/DELAYSIGN\)", }, "ErrorReporting" => { "0" => "Default", "1" => "Prompt Immediately \(\/ERRORREPORT:PROMPT\)", "2" => "Queue For Next Login \(\/ERRORREPORT:QUEUE\)", }, "CLRUnmanagedCodeCheck" => { "false" => "No", "true" => "Apply Unmanaged Code Check \(\/CLRUNMANAGEDCODECHECK\)", }, # Resources # General "Culture" => { "1000" => "Default", "1001" => "Afrikaans \(0x436\)", "1002" => "Albanian \(0x41c\)", "1003" => "Arabic (Saudi Arabia) \(0x401\)", "1004" => "Arabic (Iraq) \(0x801\)", "1005" => "Arabic (Egypt) \(0xc01\)", "1006" => "Arabic (Libya) \(0x1001\)", "1007" => "Arabic (Algeria) \(0x1401\)", "1008" => "Arabic (Morocco) \(0x1801\)", "1009" => "Arabic (Tunisia) \(0x1c01\)", "1010" => "Arabic (Oman) \(0x2001\)", "1011" => "Arabic (Yemen) \(0x2401\)", "1012" => "Arabic (Syria) \(0x2801\)", "1013" => "Arabic (Jordan) \(0x2c01\)", "1014" => "Arabic (Lebanon) \(0x3001\)", "1015" => "Arabic (Kuwait) \(0x3401\)", "1016" => "Arabic (U.A.E.) \(0x3801\)", "1017" => "Arabic (Bahrain) \(0x3c01\)", "1018" => "Arabic (Qatar) \(0x4001\)", "1019" => "Basque \(0x42d\)", "1020" => "Bulgarian \(0x402\)", "1021" => "Belarusian \(0x423\)", "1022" => "Catalan \(0x403\)", "1023" => "Chinese (Taiwan) \(0x404\)", "1024" => "Chinese (PRC) \(0x804\)", "1025" => "Chinese (Hong Kong S.A.R.) \(0xc04\)", "1026" => "Chinese (Singapore) \(0x1004\)", "1027" => "Croatian \(0x41a\)", "1028" => "Czech \(0x405\)", "1029" => "Danish \(0x406\)", "1030" => "Dutch (Netherlands) \(0x413\)", "1031" => "Dutch (Belgium) \(0x813\)", "1032" => "English (United States) \(0x409\)", "1033" => "English (United Kingdom) \(0x809\)", "1034" => "English (Australia) \(0xc09\)", "1035" => "English (Canada) \(0x1009\)", "1036" => "English (New Zealand) \(0x1409\)", "1037" => "English (Ireland) \(0x1809\)", "1038" => "English (South Africa) \(0x1c09\)", "1039" => "English (Jamaica) \(0x2009\)", "1040" => "English (Caribbean) \(0x2409\)", "1041" => "Estonian \(0x425\)", "1042" => "Farsi \(0x429\)", "1043" => "Finnish \(0x40b)", "1044" => "French (France) \(0x40c\)", "1045" => "French (Belgium) \(0x80c\)", "1046" => "French (Canada) \(0xc0c\)", "1047" => "French (Switzerland) \(0x100c\)", "1048" => "French (Luxembourg) \(0x140c\)", "1049" => "German (Germany) \(0x407\)", "1050" => "German (Switzerland) \(0x807\)", "1051" => "German (Austria) \(0xc07\)", "1052" => "German (Luxembourg) \(0x1007\)", "1053" => "German (Liechtenstein) \(0x1407\)", "1054" => "Greek \(0x408\)", "1055" => "Hebrew \(0x40d\)", "1056" => "Hungarian \(0x40e\)", "1057" => "Icelandic \(0x40f\)", "1058" => "Indonesian \(0x421\)", "1059" => "Italian (Italy) \(0x410\)", "1060" => "Italian (Switzerland) \(0x810\)", "1061" => "Japanese \(0x411\)", "1062" => "Korean \(0x412\)", "1063" => "0x812", "1064" => "Latvian \(0x426\)", "1065" => "Lithuanian \(0x427\)", "1066" => "Norwegian (Bokmal) \(0x414\)", "1067" => "Norwegian (Nynorsk) \(0x814\)", "1068" => "Polish \(0x415\)", "1069" => "Portuguese (Brazil) \(0x416\)", "1070" => "Portuguese (Portugal) \(0x816\)", "1071" => "Romanian \(0x418\)", "1072" => "Russian \(0x419\)", "1073" => "Slovak \(0x41b\)", "1074" => "Spanish (Traditional Sort) \(0x40a\)", "1075" => "Spanish (Mexico) \(0x80a\)", "1076" => "Spanish (International Sort) \(0xc0a\)", "1077" => "Spanish (Guatemala) \(0x100a\)", "1078" => "Spanish (Costa Rica) \(0x140a\)", "1079" => "Spanish (Panama) \(0x180a\)", "1080" => "Spanish (Dominican Republic) \(0x1c0a\)", "1081" => "Spanish (Venezuela) \(0x200a\)", "1082" => "Spanish (Colombia) \(0x240a\)", "1083" => "Spanish (Peru) \(0x280a\)", "1084" => "Spanish (Argentina) \(0x2c0a\)", "1085" => "Spanish (Ecuador) \(0x300a\)", "1086" => "Spanish (Chile) \(0x340a\)", "1087" => "Spanish (Uruguay) \(0x380a\)", "1088" => "Spanish (Paraguay) \(0x3c0a\)", "1089" => "Spanish (Bolivia) \(0x400a\)", "1090" => "Swedish \(0x41d\)", "1091" => "Thai \(0x41e\)", "1092" => "Turkish \(0x41f\)", "1093" => "Ukrainian \(0x422\)", "1094" => "Serbian (Latin) \(0x81a\)", "1095" => "Urdu \(0x420\)", }, "IgnoreStandardIncludePath" => "IgnoreStandardIncludePath", { "1" => "No", "2" => "Yes \(\/X\)", }, "ShowProgress" => "ShowProgress", { "1" => "No", "2" => "Yes \(\/v\)", }, ); # Hash matches vcproj configuration names with their output versions my(%configurationNames) = ( "Base" => "base", "DoD" => "dod", "CounterStrike" => "cstrike", "HL1" => "hl1", "HL2" => "hl2", "Episodic HL2" => "episodic", "TF" => "tf", "SDK" => "sdk", "HL2MP" => "hl2mp", "LostCoast" => "lostcoast", "Portal" => "portal", "Dedicated" => "dedicated", ); my(@configurations) = keys %configurationNames; my(%toolNames) = ( "VCCLCompilerTool" => "Compiler", "VCCustomBuildTool" => "CustomBuildStep", "VCLinkerTool" => "Linker", "VCPostBuildEventTool" => "PostBuildEvent", "VCPreBuildEventTool" => "PreBuildEvent", "VCPreLinkEventTool" => "PreLinkEvent", "VCResourceCompilerTool" => "Resources", "VCLibrarianTool" => "Librarian", ); my(@tools) = values %toolNames; my($baseConfiguration) = "Application (.exe)"; my(%baseConfigurationTypes) = ( "Dynamic Library (.dll)" => "dll", "Application (.exe)" => "exe", "Static Library (.lib)" => "lib", "Utility" => "lib", ); my($configurationSubsystem) = "con"; my(%outputs); my(%excludes); my(%filesAdded); for ( @configurations ) { $outputs{$_} = (); $excludes{$_} = 0; $filesAdded{$_} = 0; } my(%keytabs) = ( 0 => "\t\t\t\t\t\t\t\t\t\t", 4 => "\t\t\t\t\t\t\t\t\t", 8 => "\t\t\t\t\t\t\t\t", 12 => "\t\t\t\t\t\t\t", 16 => "\t\t\t\t\t\t", 20 => "\t\t\t\t\t", 24 => "\t\t\t\t", 28 => "\t\t\t", 32 => "\t\t", 36 => "\t", ); ###################################################### # Subroutines ###################################################### sub break { return; } sub outputToAllConfigurations { for ( @configurations ) { push( @{ $outputs{$_} }, @lineToPrint ); } } sub compare_arrays { my ($first, $second) = @_; return 0 unless @$first == @$second; for (my $i = 0; $i < @$first; $i++) { if ( $first->[$i] =~ /^(Debug|Release)$/ ) { next; } return 0 if $first->[$i] ne $second->[$i]; } return 1; } sub set_current_configuration { my($line) = shift; $line =~ ( /Name="(\w+) ([\w\s]*)\|/ ); my($name1) = $1; my($name2) = $2; if ( $name2 =~ /Release|Debug/ ) { $currentConfig = $name1; } else { $currentConfig = $name2; } if ( $line =~ ( /Name="(Release|Debug)\|/ ) ) { # default configurations $currentConfig = "Base"; } } #################################################### sub processFileConfig { $spaceBeforeFile = 1; my($splitFiles) = 0; my($line) = $_[++$lineCt]; # Set the current configuration set_current_configuration( $line ); push( @tabs, "\t" ); $line =~ ( /Name="([\w\s]*)\|/ ); my($configName) = ( $1 =~ /(Debug|Release)/ ); push( @{ $configOutput{$currentConfig} }, @tabs, "\$Configuration\t\"", $configName, "\"\n" ); push( @{ $configOutput{$currentConfig} }, @tabs, "\{\n" ); # Process the configuration my($configResult) = processConfiguration( @_ ); # end if this configuration push( @{ $configOutput{$currentConfig} }, @tabs, "\}\n" ); if ( $configResult == 1 ) { # Mark this file as excluded for the current configuration $excludes{$currentConfig} = 1; $splitFiles = 1; } elsif ( $configResult == -1 ) { # Configuration is empty, so clear it @{ $configOutput{$currentConfig} } = (); } pop( @tabs ); return $splitFiles; } #################################################### sub processFile { # get the file name and path @lineToPrint = (); if ( $spaceBeforeFile == 1 ) { $spaceBeforeFile = 0; # push( @lineToPrint, "\n" ); } $_[++$lineCt] =~ ( /RelativePath="([^"]+)"/ ); my $line = $1; # replace ..\ and .\ in filenames $line =~ s/^\Q$srcdirBackslash\E\\/\$SRCDIR\\/; $line =~ s/^\Q$srcdirForwardslash\E\//\$SRCDIR\\/; $line =~ s/^\.\\//; push( @lineToPrint, @tabs, "\t\$File\t\"", $line, "\"\n" ); push( @tabs, "\t" ); my($splitFiles) = 0; my($configFound) = 0; # loop until the tag %configOutput = (); while ( $_[++$lineCt] !~ /^\s*\<\/File\>$/ ) { # Check for file specific configurations if ( $_[$lineCt] =~ /^\s*\ 0 ) { push( @{ $outputs{"Base"} }, @lineToPrint, @tabs, "\{\n" ); push( @{ $outputs{"Base"} }, @{ $configOutput{"Base"} } ); push( @{ $outputs{"Base"} }, @tabs, "\}\n\n" ); } else { push( @{ $outputs{"Base"} }, @lineToPrint ); } $filesAdded{"Base"} = 1; } else { $excludes{"Base"} = 1; $exclusionsFound = 1; for ( @configurations ) { if ( !$excludes{$_} ) { if ( @{ $configOutput{$_} } > 0 ) { push( @{ $outputs{$_} }, @lineToPrint, @tabs, "\{\n" ); push( @{ $outputs{$_} }, @{ $configOutput{$_} } ); push( @{ $outputs{$_} }, @tabs, "\}\n\n" ); } else { push( @{ $outputs{$_} }, @lineToPrint ); } $filesAdded{$_} = 1; } else { # reset the exclude flag $excludes{$_} = 0; } } } pop( @tabs ); } #################################################### sub processFolder { push( @tabs, "\t" ); # Grab the folder name and add it to all configuration's outputs $_[++$lineCt] =~ ( /Name="([^"]+)"/ ); @lineToPrint = ( @tabs, "\$Folder\t\"", $1, "\"\n", @tabs, "\{\n" ); outputToAllConfigurations(); # Loop until the tag while ( $_[++$lineCt] !~ /^\s*\<\/Filter\>$/ ) { if ( $_[$lineCt] =~ /^\s*\$/ ) { ++$lineCt; } return; } my( @tempOutput ); if ( !$parsingFiles ) { push( @tempOutput, "\n" ); } push( @tempOutput, @tabs, "\$", $toolNames{$toolName}, "\n" ); push( @tempOutput, @tabs, "\{\n" ); # Loop until the /> tag my($keyname); my($keyvalue); my($optionsFound) = 0; while ( $_[$lineCt] !~ /\/\>$/ ) { ($keyname, $keyvalue) = processConfigOption( $_[++$lineCt], $toolName ); if ( $keyname ) { if ( $keyvalue || !$stripEmptyOptions ) { $optionsFound = 1; } my($len) = $tabstop * int( (length( $keyname ) + $tabstop + 1) / $tabstop ); push( @tempOutput, @tabs, "\t\$", $keyname, $keytabs{$len}, "\"", $keyvalue, "\"\n" ); } } pop( @tabs ); # End of the tool if ( $optionsFound ) { push( @{ $configOutput{$currentConfig} }, @tempOutput, @tabs, "\t}\n" ); return 1; } return 0; } #################################################### sub processConfiguration { my( $configOptionsFound ) = 0; my( $startedGeneral ) = 0; # Loop until the tag while ( $_[++$lineCt] !~ /^\s*\<\/(File)*Configuration\>$/ ) { if ( $_[$lineCt] =~ /^\s*\; close( INFILE ); my(@pathArray) = split(/\\/, $infile ); my($vcprojname) = $pathArray[$#pathArray]; unless ( $outputPath ) { $outputPath = $infile; $outputPath =~ s/$vcprojname//; } # build the fileheader my(@fileheader); push( @fileheader, "\/\/-----------------------------------------------------------------------------\n" ); push( @fileheader, "\/\/\t",uc($vcprojname),".VPC\n" ); push( @fileheader, "\/\/\n" ); push( @fileheader, "\/\/\tProject Script\n" ); push( @fileheader, "\/\/-----------------------------------------------------------------------------\n" ); push( @fileheader, "\/\/ ***** AUTO-GENERATED: PLEASE FIXUP MANUALLY BEFORE USING THIS SCRIPT! *****\n" ); push( @fileheader, "\n" ); push( @fileheader, "\$Macro SRCDIR\t\t\".." ); $srcdirBackslash = ".."; my($dirct) = $#pathArray - 2; for ( my($i) = 0; $i < $dirct; ++$i ) { push( @fileheader, "\\.." ); $srcdirBackslash = join( "\\", $srcdirBackslash, ".." ); } $srcdirForwardslash = $srcdirBackslash; $srcdirForwardslash =~ s/\\/\//g; push( @fileheader, "\"\n" ); # Process the file one line at a time my $folderOpenBrace = 0; for( $lineCt = 0; $lineCt < @lines; ++$lineCt ) { my($line) = @lines[$lineCt]; if ( !$nameFound && $line =~ ( /Name="([^"]+)"/ ) ) { $projectName = $1; # Print the project name my $capName = $projectName; $capName =~ s/\b(\w)/\U$1/g; @lineToPrint = ( "\$Project \"", $capName, "\"\n\{\n" ); for ( @configurations ) { push( @{ $outputs{$_} }, @lineToPrint ); } $nameFound = 1; $folderOpenBrace = 1; # Clean up the directory # for ( @configurations ) # { # # delete the existing files # my($filename) = join('_', $vcprojname, $configurationNames{$_} ); # if( $outputPath ) # { # $filename = join('/', $outputPath, $filename ); # $filename =~ s/\//\\/g; # } # system( "del /Q $filename.vpc" ); # } } if ( $line =~ /^\s*\$/ ) { # end of configurations section - write out the files # first, finish filling in the header info my($configtype) = $baseConfigurationTypes{$baseConfiguration}; if ( $configtype =~ /lib/ ) { push( @fileheader, "\$Macro OUTLIBDIR\t\"\$SRCDIR\\lib\\XXXX\"\n" ); } else { push( @fileheader, "\$Macro OUTBINDIR\t\"\$SRCDIR\\..\\game\\bin\"\n" ); } push( @fileheader, "\n" ); push( @fileheader, "\$Include \"\$SRCDIR\\vpc_scripts\\source_" ); push( @fileheader, $configtype ); if ( $configtype =~ /exe/ ) { push( @fileheader, "_", $configurationSubsystem ); } push( @fileheader, "_win32_base.vpc\"\n" ); # push( @fileheader, "_win32_base.vpc\"\t\[\$WIN32\|\|\$LINUX\]\n" ); # push( @fileheader, "\$Include \"\$SRCDIR\\vpc_scripts\\source_" ); # push( @fileheader, $configtype ); # push( @fileheader, "_x360_base.vpc\"\t\t\[\$X360\]\n" ); push( @fileheader, "\n" ); for ( @configurations ) { my $joinedname = join( '_', $_, "Debug" ); # print the configs if ( @{ $configOutput{$joinedname} } > 0 ) { my($filename) = join('_', $vcprojname, $configurationNames{$_} ); if( $outputPath ) { $filename = join('/', $outputPath, $filename ); } open ( OUTFILE, ">$filename.vpc" ); print OUTFILE @fileheader; print OUTFILE @{ $configOutput{$joinedname} }; $joinedname = join( '_', $_, "Release" ); print OUTFILE @{ $configOutput{$joinedname} }; close ( OUTFILE ); } } $parsingFiles = 1; } elsif ( $line =~ /^\s*\>$filename.vpc" ); print OUTFILE @{ $outputs{$_} }; close ( OUTFILE ); } } if ( $projectCt == 1 ) { my $oldname = join('_', $vcprojname, "base.vpc" ); my $newname = join('', $vcprojname, ".vpc" ); if( $outputPath ) { $oldname = join('/', $outputPath, $oldname ); $newname = join('/', $outputPath, $newname ); } rename $oldname, $newname; }