mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 06:06:50 +00:00
1670 lines
40 KiB
Perl
1670 lines
40 KiB
Perl
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 or yes/no 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",
|
|
"BrowseInformation" => "BuildBrowserInformation",
|
|
# "ATLMinimizesCRunTimeLibraryUsage" => "MinimizeCRTUseInATL",
|
|
"ManagedExtensions" => "UseManagedExtensions",
|
|
# "WholeProgramOptimization" => "WholeProgramOptimization",
|
|
"ReferencesPath" => "ReferencesPath",
|
|
"ExcludedFromBuild" => "ExcludedFromBuild",
|
|
|
|
# Debugging
|
|
},
|
|
|
|
# C/C++
|
|
"VCCLCompilerTool" =>
|
|
{
|
|
# General
|
|
"AdditionalIncludeDirectories" => "AdditionalIncludeDirectories",
|
|
"AdditionalUsingDirectories" => "ResolveUsingReferences",
|
|
# "WarningLevel" => "WarningLevel",
|
|
|
|
# Optimization
|
|
|
|
# Preprocessor
|
|
"PreprocessorDefinitions" => "PreprocessorDefinitions",
|
|
|
|
# Code Generation
|
|
|
|
# Language
|
|
|
|
# Precompiled Headers
|
|
"PrecompiledHeaderThrough" => "Create/UsePCHThroughFile",
|
|
"PrecompiledHeaderFile" => "PrecompiledHeaderFile",
|
|
|
|
# Output Files
|
|
# "AssemblerListingLocation" => "ASMListLocation",
|
|
# "ObjectFile" => "ObjectFileName",
|
|
# "ProgramDataBaseFileName" => "ProgramDatabaseFileName",
|
|
|
|
# Browse Information
|
|
"BrowseInformationFile" => "BrowseFile",
|
|
|
|
# Advanced
|
|
"DisableSpecificWarnings" => "DisableSpecificWarnings",
|
|
"ForcedIncludeFiles" => "ForceIncludes",
|
|
"ForcedUsingFiles" => "ForceUsing",
|
|
"UndefinePreprocessorDefinitions" => "UndefinePreprocessorDefinitions",
|
|
|
|
# Command Line
|
|
"AdditionalOptions" => "AdditionalOptions",
|
|
},
|
|
|
|
# Librarian
|
|
"VCLibrarianTool" =>
|
|
{
|
|
# General
|
|
"OutputFile" => "ResourceOutputFileName",
|
|
"AdditionalDependencies" => "AdditionalDependencies",
|
|
"AdditionalLibraryDirectories" => "AdditionalLibraryDirectories",
|
|
"ModuleDefinitionFile" => "ModuleDefinitionFileName",
|
|
"IgnoreDefaultLibraryNames" => "IgnoreSpecificLibrary",
|
|
"ExportNamedFunctions" => "ExportNamedFunctions",
|
|
"ForceSymbolReferences" => "ForceSymbolReferences",
|
|
|
|
# Command LIne
|
|
"AdditionalOptions" => "AdditionalOptions",
|
|
},
|
|
|
|
# Linker
|
|
"VCLinkerTool" =>
|
|
{
|
|
# General
|
|
# "OutputFile" => "OutputFile",
|
|
"Version" => "Version",
|
|
"IgnoreImportLibrary" => "IgnoreImportLibrary",
|
|
"RegisterOutput" => "RegisterOutput",
|
|
"AdditionalLibraryDirectories" => "AdditionalLibraryDirectories",
|
|
|
|
# Input
|
|
"AdditionalDependencies" => "AdditionalDependencies",
|
|
"IgnoreDefaultLibraryNames" => "IgnoreSpecificLibrary",
|
|
"ModuleDefinitionFile" => "ModuleDefinitionFile",
|
|
"AddModuleNamesToAssembly" => "AddModuleToAssembly",
|
|
"EmbedManagedResourceFile" => "EmbedManagedResourceFile",
|
|
"ForceSymbolReferences" => "ForceSymbolReferences",
|
|
"DelayLoadDLLs" => "DelayLoadedDLLs",
|
|
|
|
# Debugging
|
|
# "ProgramDatabaseFile" => "GenerateProgramDatabaseFile",
|
|
"StripPrivateSymbols" => "StripPrivateSymbols",
|
|
# "MapFileName" => "MapFileName",
|
|
|
|
# System
|
|
"HeapReserveSize" => "HeapReserverSize",
|
|
"HeapCommitSize" => "HeapCommitSize",
|
|
"StackReserveSize" => "StackReserveSize",
|
|
"StackCommitSize" => "StackCommitSize",
|
|
|
|
# Optimization
|
|
"FunctionOrder" => "FunctionOrder",
|
|
|
|
# Embedded IDL
|
|
"MidlCommandFile" => "MIDLCommands",
|
|
"MergedIDLBaseFileName" => "MergedIDLBaseFileName",
|
|
"TypeLibraryFile" => "TypeLibrary",
|
|
"TypeLibraryResourceID" => "TypeLibResourceID",
|
|
|
|
# Advanced
|
|
"EntryPointSymbol" => "EntryPoint",
|
|
# "BaseAddress" => "BaseAddress",
|
|
# "ImportLibrary" => "ImportLibrary",
|
|
"MergeSections" => "MergeSections",
|
|
|
|
# Command LIne
|
|
"AdditionalOptions" => "AdditionalOptions",
|
|
},
|
|
|
|
# Resources
|
|
"VCResourceCompilerTool" =>
|
|
{
|
|
# General
|
|
# "PreprocessorDefinitions" => "PreprocessorDefinitions",
|
|
"AdditionalIncludeDirectories" => "AdditionalIncludeDirectories",
|
|
"ResourceOutputFileName" => "ResourceOutputFileName",
|
|
|
|
# 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",
|
|
# "Detect64BitPortabilityProblems" => "Detect64BitPortabilityIssues",
|
|
"WarnAsError" => "TreatWarningsAsErrors",
|
|
|
|
# Optimization
|
|
# "Optimization" => "Optimization",
|
|
# "GlobalOptimizations" => "GlobalOptimizations",
|
|
# "InlineFunctionExpansion" => "InlineFunctionExpansion",
|
|
# "EnableIntrinsicFunctions" => "EnableIntrinsicFunctions",
|
|
# "ImproveFloatingPointConsistency" => "FloatingPointConsistency",
|
|
# "FavorSizeOrSpeed" => "FavorSizeOrSpeed",
|
|
# "OmitFramePointers" => "OmitFramePointers",
|
|
"EnableFiberSafeOptimizations" => "EnableFiberSafeOptimizations",
|
|
# "OptimizeForProcessor" => "OptimizeForProcessor",
|
|
"OptimizeForWindowsApplication" => "OptimizeForWindowsApplication",
|
|
# "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",
|
|
|
|
# Language
|
|
"DisableLanguageExtensions" => "DisableLanguageExtensions",
|
|
"DefaultCharIsUnsigned" => "DefaultCharUnsigned",
|
|
"TreatWChar_tAsBuiltInType" => "TreatWchar_tAsBuiltinType",
|
|
# "ForceConformanceInForLoopScope" => "ForceConformanceInForLoopScope",
|
|
"RuntimeTypeInfo" => "EnableRunTimeTypeInfo",
|
|
|
|
# Precompiled Headers
|
|
"UsePrecompiledHeader" => "Create/UsePrecompiledHeader",
|
|
|
|
# Output Files
|
|
"ExpandAttributedSource" => "ExpandAttributedSource",
|
|
"AssemblerOutput" => "AssemblerOutput",
|
|
|
|
# Browse Information
|
|
# "BrowseInformation" => "EnableBrowseInformation",
|
|
|
|
# Advanced
|
|
"CallingConvention" => "CallingConvention",
|
|
# "CompileAs" => "CompileAs",
|
|
"UndefineAllPreprocessorDefinitions" => "UndefineAllPreprocessorDefinitions",
|
|
|
|
# Librarian
|
|
# General
|
|
# "SuppressStartupBanner" => "SuppressStartupBanner",
|
|
"IgnoreAllDefaultLibraries" => "IgnoreAllDefaultLibraries",
|
|
|
|
# Linker
|
|
# General
|
|
"ShowProgress" => "ShowProgress",
|
|
# "LinkIncremental" => "EnableIncrementalLinking",
|
|
# "SuppressStartupBanner" => "SuppressStartupBanner",
|
|
|
|
# Linker
|
|
"IgnoreAllDefaultLibraries" => "IgnoreAllDefaultLibraries",
|
|
|
|
# Debugging
|
|
# "GenerateDebugInformation" => "GenerateDebugInfo",
|
|
"AssemblyDebug" => "DebuggableAssembly",
|
|
# "GenerateMapFile" => "GenerateMapFile",
|
|
"MapExports" => "MapExports",
|
|
"MapLines" => "MapLines",
|
|
|
|
# System
|
|
"SubSystem" => "SubSystem",
|
|
"LargeAddressAware" => "EnableLargeAddresses",
|
|
"TerminalServerAware" => "TerminalServer",
|
|
"SwapRunFromCD" => "SwapRunFromCD",
|
|
"SwapRunFromNet" => "SwapRunFromNetwork",
|
|
|
|
# Optimization
|
|
# "OptimizeReferences" => "References",
|
|
# "EnableCOMDATFolding" => "EnableCOMDATFolding",
|
|
"OptimizeForWindows98" => "OptimizeForWindows98",
|
|
|
|
# Embedded IDL
|
|
"IgnoreEmbeddedIDL" => "IgnoreEmbeddedIDL",
|
|
|
|
# Advanced
|
|
"ResourceOnlyDLL" => "ResourceOnlyDLL",
|
|
"SetChecksum" => "SetChecksum",
|
|
"FixedBaseAddress" => "FixedBaseAddress",
|
|
"TurnOffAssemblyGeneration" => "TurnOffAssemblyGeneration",
|
|
"SupportUnloadOfDelayLoadedDLL" => "DelayLoadedDLL",
|
|
# "TargetMachine" => "TargetMachine",
|
|
|
|
# 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" =>
|
|
{
|
|
"0" => "Disabled",
|
|
"1" => "C7 Compatible \(\/Z7\)",
|
|
"2" => "Line Numbers Only \(\/Zd\)",
|
|
"3" => "Program Database \(\/Zi\)",
|
|
"4" => "Program Database for Edit & Continue \(\/ZI\)",
|
|
},
|
|
"SuppressStartupBanner" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/nologo)",
|
|
},
|
|
"Detect64BitPortabilityProblems" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/Wp64)",
|
|
},
|
|
"WarnAsError" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/WX)",
|
|
},
|
|
|
|
# Optimization
|
|
"Optimization" =>
|
|
{
|
|
"0" => "Disabled \(\/Od\)",
|
|
"1" => "Minimize Size \(\/O1\)",
|
|
"2" => "Maximize Speed \(\/O2\)",
|
|
"3" => "Full Optimization \(\/Ox\)",
|
|
"4" => "Custom",
|
|
},
|
|
"GlobalOptimizations" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/Og)",
|
|
},
|
|
"InlineFunctionExpansion" =>
|
|
{
|
|
"0" => "Default",
|
|
"1" => "Only __inline \(\/Ob1\)",
|
|
"2" => "Any Suitable \(\/Ob2\)",
|
|
},
|
|
"EnableIntrinsicFunctions" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/Oi)",
|
|
},
|
|
"ImproveFloatingPointConsistency" =>
|
|
{
|
|
"FALSE" => "Default Consistency",
|
|
"TRUE" => "Improve Consistency \(\/Op\)",
|
|
},
|
|
"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)",
|
|
},
|
|
"OptimizeForProcessor" =>
|
|
{
|
|
"0" => "Blended",
|
|
"1" => "Pentium \(\/G5\)",
|
|
"2" => "Pentium Pro, Pentium II, Pentium III \(\/G6\)",
|
|
"3" => "Pentium 4 and Above \(\/G7\)",
|
|
},
|
|
"OptimizeForWindowsApplication" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/GA)",
|
|
},
|
|
"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" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/EHsc)",
|
|
},
|
|
"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\)",
|
|
"4" => "Single-threaded \(\/ML\)",
|
|
"5" => "Single-threaded Debug \(\/MLd\)",
|
|
},
|
|
"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",
|
|
"TRUE" => "Yes (/Gs)",
|
|
},
|
|
"EnableFunctionLevelLinking" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/Gy)",
|
|
},
|
|
"EnableEnhancedInstructionSet" =>
|
|
{
|
|
"0" => "Not Set",
|
|
"1" => "Streaming SIMD Extensions \(\/arch:SSE\)",
|
|
"2" => "Streaming SIMD Extensions 2 \(\/arch:SSE2\)",
|
|
},
|
|
|
|
# Language
|
|
"DisableLanguageExtensions" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/Za)",
|
|
},
|
|
"DefaultCharIsUnsigned" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/J)",
|
|
},
|
|
"TreatWChar_tAsBuiltInType" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/Zc:wchar_t)",
|
|
},
|
|
"ForceConformanceInForLoopScope" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/Zc:forScope)",
|
|
},
|
|
"RuntimeTypeInfo" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/GR)",
|
|
},
|
|
|
|
# Precompiled Headers
|
|
"UsePrecompiledHeader" =>
|
|
{
|
|
"0" => "Not Using Precompiled Headers",
|
|
"1" => "Create Precompiled Header \(\/Yc\)",
|
|
"2" => "Automatically Generate \(\/YX\)",
|
|
"3" => "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\)",
|
|
},
|
|
|
|
# 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\)",
|
|
},
|
|
"UndefineAllPreprocessorDefinitions" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/u)",
|
|
},
|
|
|
|
# Librarian
|
|
# General
|
|
"SuppressStartupBanner" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/NOLOGO)",
|
|
},
|
|
"IgnoreAllDefaultLibraries" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/NODEFAULTLIB)",
|
|
},
|
|
|
|
# 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)",
|
|
},
|
|
|
|
# Linker
|
|
"IgnoreAllDefaultLibraries" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/NODEFAULTLIB)",
|
|
},
|
|
|
|
# Debugging
|
|
"GenerateDebugInformation" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/DEBUG)",
|
|
},
|
|
"AssemblyDebug" =>
|
|
{
|
|
"0" => "No Debuggable attribute emitted",
|
|
"1" => "Runtime tracking and disable optimizations \(\/ASSEMBLYDEBUG\)",
|
|
"2" => "No runtime tracking and enable optimizations \(\/ASSEMBLYDEBUG:DISABLE\)",
|
|
},
|
|
"GenerateMapFile" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/MAP)",
|
|
},
|
|
"MapExports" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/MAPINFO:EXPORTS)",
|
|
},
|
|
"MapLines" =>
|
|
{
|
|
"FALSE" => "No",
|
|
"TRUE" => "Yes (/MAPINFO:LINES)",
|
|
},
|
|
|
|
# System
|
|
"SubSystem" =>
|
|
{
|
|
"0" => "Not Set",
|
|
"1" => "Console \(\/SUBSYSTEM:CONSOLE\)",
|
|
"2" => "Windows \(\/SUBSYSTEM:WINDOWS\)",
|
|
},
|
|
"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)",
|
|
},
|
|
|
|
#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\)",
|
|
},
|
|
|
|
# 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\)",
|
|
},
|
|
|
|
# Resources
|
|
# General
|
|
"Culture" => "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 </File> tag
|
|
|
|
%configOutput = ();
|
|
while ( $_[++$lineCt] !~ /^\s*\<\/File\>$/ )
|
|
{
|
|
# Check for file specific configurations
|
|
if ( $_[$lineCt] =~ /^\s*\<FileConfiguration/ )
|
|
{
|
|
$configFound = 1;
|
|
$splitFiles += processFileConfig( @_ );
|
|
}
|
|
}
|
|
|
|
# Compare the configurations to see if the files should be split
|
|
if ( $configFound && !$splitFiles )
|
|
{
|
|
for ( @configurations )
|
|
{
|
|
if ( $_ eq "Base" || $_ eq "Dedicated" )
|
|
{
|
|
next;
|
|
}
|
|
if ( !compare_arrays( \@{ $configOutput{"HL2"} }, \@{ $configOutput{$_} } ) )
|
|
{
|
|
$splitFiles = 1;
|
|
last;
|
|
}
|
|
}
|
|
if ( !$splitFiles )
|
|
{
|
|
push( @{ $configOutput{"Base"} }, @{ $configOutput{"HL2"} } );
|
|
}
|
|
}
|
|
|
|
# Add the file and configuration to the appropriate projects
|
|
|
|
if ( !$splitFiles )
|
|
{
|
|
if ( @{ $configOutput{"Base"} } > 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 </Filter> tag
|
|
|
|
while ( $_[++$lineCt] !~ /^\s*\<\/Filter\>$/ )
|
|
{
|
|
if ( $_[$lineCt] =~ /^\s*\<Filter$/ )
|
|
{
|
|
# Start of a new folder
|
|
|
|
if ( $spaceBeforeFolder == 1 )
|
|
{
|
|
$spaceBeforeFolder = 0;
|
|
@lineToPrint = "\n";
|
|
outputToAllConfigurations();
|
|
}
|
|
processFolder( @_ );
|
|
}
|
|
elsif ( $_[$lineCt] =~ /^\s*\<File$/ )
|
|
{
|
|
# Start of a new file
|
|
|
|
processFile( @_ );
|
|
$spaceBeforeFolder = 1;
|
|
}
|
|
}
|
|
|
|
# End of the folder
|
|
|
|
@lineToPrint = ( @tabs, "\}\n" );
|
|
for ( @configurations )
|
|
{
|
|
push( @{ $outputs{$_} }, @lineToPrint );
|
|
}
|
|
pop( @tabs );
|
|
}
|
|
|
|
|
|
####################################################
|
|
sub processConfigOption
|
|
{
|
|
my($line) = shift;
|
|
my($tool) = shift;
|
|
|
|
# Get the keyname and value
|
|
if ( $line !~ /(\w+)="([^"\n]*)(.*)/ )
|
|
{
|
|
return;
|
|
}
|
|
|
|
my($keyname) = $1;
|
|
my($keyvalue) = $2;
|
|
my($lastChar) = $3;
|
|
my($outputvalue);
|
|
|
|
# Lookup the keyname
|
|
if ( $outputvalue = $configOptionsSingleValue{$tool}{$keyname} )
|
|
{
|
|
# A single value option - outputvalue is the VPC defined keyname
|
|
|
|
# Translate TRUE/FALSE to Yes/No
|
|
$keyvalue =~ s/TRUE/Yes/;
|
|
$keyvalue =~ s/FALSE/No/;
|
|
|
|
$keyname = $outputvalue;
|
|
}
|
|
elsif ( $outputvalue = $configOptionValues{$keyname}{$keyvalue} )
|
|
{
|
|
# A multi-value option - outputvalue is the desired option setting in string form
|
|
|
|
my($translatedName) = $configOptionsMultiValue{$keyname};
|
|
|
|
# Do some bookkeeping for later
|
|
if ( $translatedName =~ /^SubSystem$/ && $outputvalue =~ /Windows/ )
|
|
{
|
|
$configurationSubsystem = "win";
|
|
}
|
|
elsif ( $translatedName =~ /^ConfigurationType$/ )
|
|
{
|
|
$baseConfiguration = $outputvalue;
|
|
}
|
|
|
|
if ( $usestring )
|
|
{
|
|
return $translatedName, $outputvalue;
|
|
}
|
|
else
|
|
{
|
|
return $translatedName, $keyvalue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# For debugging
|
|
# print( "Line ", $lineCt, ": Error, no config found for Tool: ", $tool, ", ", $keyname, "=", $keyvalue, "\n" );
|
|
# push( @tempOutput, "\/\/" );
|
|
return;
|
|
}
|
|
|
|
# special handling for multi-line options
|
|
if ( !$lastChar )
|
|
{
|
|
my($nextline) = ( @lines[++$lineCt] =~ /([^\n]*)/ );
|
|
while( $nextline !~ /\"/ )
|
|
{
|
|
$keyvalue = join( '', $keyvalue, "\" \\ \"\\n\"\n", @tabs, $keytabs{0}, "\"", $nextline );
|
|
($nextline) = ( @lines[++$lineCt] =~ /([^\n]*)/ );
|
|
}
|
|
}
|
|
|
|
# replace " and ..\ and .\ in option values
|
|
$keyvalue =~ s/(?<=[^\\])\Q$srcdirBackslash\E\\/\$SRCDIR\\/g;
|
|
$keyvalue =~ s/(?<=[^\/])\Q$srcdirForwardslash\E\//\$SRCDIR\\/g;
|
|
$keyvalue =~ s/^\Q$srcdirBackslash\E\\/\$SRCDIR\\/g;
|
|
$keyvalue =~ s/^\Q$srcdirForwardslash\E\//\$SRCDIR\\/g;
|
|
$keyvalue =~ s/^\.\\//g;
|
|
$keyvalue =~ s/\"\;/\$QUOTE/g;
|
|
|
|
return $keyname, $keyvalue;
|
|
|
|
}
|
|
|
|
|
|
####################################################
|
|
sub processBuildTool
|
|
{
|
|
push( @tabs, "\t" );
|
|
# Grab the tool name
|
|
|
|
$_[++$lineCt] =~ ( /Name="([^"]+)"/ );
|
|
my($toolName) = $1;
|
|
|
|
if ( !$toolNames{$toolName} )
|
|
{
|
|
pop( @tabs );
|
|
while ( $_[$lineCt] !~ /\/\>$/ )
|
|
{
|
|
++$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 </Configuration> tag
|
|
|
|
while ( $_[++$lineCt] !~ /^\s*\<\/(File)*Configuration\>$/ )
|
|
{
|
|
if ( $_[$lineCt] =~ /^\s*\<Tool$/ )
|
|
{
|
|
if ( $startedGeneral )
|
|
{
|
|
# close out the faked "General" category
|
|
$startedGeneral = 0;
|
|
push( @{ $configOutput{$currentConfig} }, @tabs, "\}\n" );
|
|
pop( @tabs );
|
|
}
|
|
|
|
# Start of a new build tool
|
|
|
|
$configOptionsFound += processBuildTool( @_ );
|
|
}
|
|
elsif ( $_[$lineCt] =~ /=/ )
|
|
{
|
|
# Process the main configuration properties
|
|
|
|
if ( !$startedGeneral && !$parsingFiles )
|
|
{
|
|
# start the fake "General" category
|
|
$startedGeneral = 1;
|
|
|
|
push( @tabs, "\t" );
|
|
push( @{ $configOutput{$currentConfig} }, @tabs, "\$General\n" );
|
|
push( @{ $configOutput{$currentConfig} }, @tabs, "\{\n" );
|
|
}
|
|
|
|
my($keyname);
|
|
my($keyvalue);
|
|
($keyname, $keyvalue) = processConfigOption( $_[$lineCt], "General" );
|
|
|
|
if ( $keyname )
|
|
{
|
|
# Handle some special cases
|
|
if ( $keyname =~ /^ExcludedFromBuild$/ && $keyvalue =~ /^Yes$/ )
|
|
{
|
|
@{ $configOutput{$currentConfig} } = ();
|
|
return 1;
|
|
}
|
|
|
|
++$configOptionsFound;
|
|
my($len) = $tabstop * int( (length( $keyname ) + $tabstop + 1) / $tabstop );
|
|
push( @{ $configOutput{$currentConfig} }, @tabs, "\t\$", $keyname, $keytabs{$len}, "\"", $keyvalue, "\"\n" );
|
|
}
|
|
}
|
|
}
|
|
|
|
# See if any config options were recorded
|
|
if ( !$configOptionsFound )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
######################################################
|
|
# Code section
|
|
######################################################
|
|
|
|
if ( !$ARGV[0] )
|
|
{
|
|
print( "Error: no project name specified\n" );
|
|
exit;
|
|
}
|
|
|
|
# Read in the source file
|
|
|
|
my $infile = $ARGV[0];
|
|
$infile =~ s/.vcproj//;
|
|
open(INFILE, "$infile.vcproj" );
|
|
|
|
@lines = <INFILE>;
|
|
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*\<Configuration$/ )
|
|
{
|
|
# Start of a new configuration
|
|
|
|
# Get the configuration name and then process the configuration
|
|
|
|
my($configLine) = @lines[++$lineCt];
|
|
set_current_configuration( $configLine );
|
|
|
|
$configLine =~ ( /Name="([\w\s]*)\|/ );
|
|
my($configName) = ( $1 =~ /(Debug|Release)/ );
|
|
$currentConfig = join( '_', $currentConfig, $configName );
|
|
|
|
push( @{ $configOutput{$currentConfig} }, "\$Configuration\t\"", $configName, "\"\n" );
|
|
push( @{ $configOutput{$currentConfig} }, "\{\n" );
|
|
|
|
processConfiguration( @lines );
|
|
|
|
|
|
# end if this configuration
|
|
push( @{ $configOutput{$currentConfig} }, "\}\n\n" );
|
|
}
|
|
elsif ( $line =~ /^\s*\<Files\>$/ )
|
|
{
|
|
# 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*\<Filter$/ )
|
|
{
|
|
# Start of a new folder
|
|
|
|
if ( $spaceBeforeFolder == 1 )
|
|
{
|
|
$spaceBeforeFolder = 0;
|
|
for ( @configurations )
|
|
{
|
|
push( @{ $outputs{$_} }, "\n" );
|
|
}
|
|
}
|
|
|
|
processFolder( @lines );
|
|
}
|
|
elsif ( $line =~ /^\s*\<File$/ )
|
|
{
|
|
# Start of a new file
|
|
|
|
if ( $spaceBeforeFolder == 1 )
|
|
{
|
|
$spaceBeforeFolder = 0;
|
|
for ( @configurations )
|
|
{
|
|
push( @{ $outputs{$_} }, "\n" );
|
|
}
|
|
}
|
|
|
|
processFile( @lines );
|
|
}
|
|
}
|
|
|
|
|
|
my $projectCt = 0;
|
|
|
|
for ( @configurations )
|
|
{
|
|
push( @{ $outputs{$_} }, "\}\n" );
|
|
|
|
if ( $filesAdded{$_} )
|
|
{
|
|
++$projectCt;
|
|
|
|
# print the files
|
|
my($filename) = join('_', $vcprojname, $configurationNames{$_} );
|
|
if( $outputPath )
|
|
{
|
|
$filename = join('/', $outputPath, $filename );
|
|
}
|
|
open ( OUTFILE, ">>$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;
|
|
}
|
|
|
|
|