You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1668 lines
40 KiB
1668 lines
40 KiB
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, "\/\/" ); |
|
} |
|
|
|
# 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; |
|
} |
|
|
|
|
|
|