Counter Strike : Global Offensive Source Code
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.

1842 lines
45 KiB

  1. use strict;
  2. no strict 'refs';
  3. ######################################################
  4. # Data Section
  5. ######################################################
  6. my(@lines) = (); # holds the input file
  7. my(@tabs) = (); # for indentation
  8. my(@lineToPrint) = (); # current formatted output line
  9. #my(@configOutput) = (); # output from configuration parsing
  10. my(%configOutput) = (); # hash of configuration-specific config options
  11. my($currentConfig) = ""; # configuration currently being parsed
  12. my($nameFound) = 0; # flag set when project name has been parsed
  13. my($lineCt) = 0; # current line number in the source file
  14. my($exclusionsFound) = 0; # an file has been 'excluded from build' for some configuration
  15. my($projectName) = ""; # base name of the project
  16. my($parsingFiles) = 0; # a cheap state variable
  17. my($splitConfigs) = 0; # debug variable set from the commmand line
  18. my($outputPath) = undef;# optional path for the vpc destination
  19. my($spaceBeforeFolder) = 0; # tracks when to add a line before folder blocks
  20. my($spaceBeforeFile) = 0; # tracks when to add a line before file blocks
  21. my($tabstop) = 4; # size of tabs - 4 for visual studio
  22. my($srcdirBackslash) = undef;# holds the value of the macro SRCDIR, with \ separators
  23. my($srcdirForwardslash) = undef;# holds the value of the macro SRCDIR, with / separators
  24. my($usestring) = 1; # use string values for compiler options
  25. my($stripEmptyOptions) = 1; # remove compiler options that have empty values (strings)
  26. if ( $ARGV[1] =~ /useindex/ )
  27. {
  28. $usestring = 0;
  29. }
  30. elsif ( $ARGV[1] =~ /allownullstrings/ )
  31. {
  32. $stripEmptyOptions = 0;
  33. }
  34. elsif ( $ARGV[1] =~ /-o/ )
  35. {
  36. $outputPath = $ARGV[2];
  37. }
  38. ##############################################################################
  39. # Match vcproj option keywords with vpc keywords - only string value options
  40. # String on the left matches the option name in the VCProj.
  41. # String on the right matches the option name in vpc
  42. my(%configOptionsSingleValue) = (
  43. # Configuration
  44. "General" =>
  45. {
  46. # General
  47. "OutputDirectory" => "OutputDirectory",
  48. "IntermediateDirectory" => "IntermediateDirectory",
  49. "DeleteExtensionsOnClean" => "ExtensionsToDeleteOnClean",
  50. "BuildLogFile" => "BuildLogFile",
  51. "ATLMinimizesCRunTimeLibraryUsage" => "MinimizeCRTUseInATL",
  52. "ManagedExtensions" => "UseManagedExtensions",
  53. "WholeProgramOptimization" => "WholeProgramOptimization",
  54. "ReferencesPath" => "ReferencesPath",
  55. "ExcludedFromBuild" => "ExcludedFromBuild",
  56. # Debugging
  57. },
  58. # C/C++
  59. "VCCLCompilerTool" =>
  60. {
  61. # General
  62. "AdditionalIncludeDirectories" => "AdditionalIncludeDirectories",
  63. "AdditionalUsingDirectories" => "ResolveUsingReferences",
  64. # Optimization
  65. # Preprocessor
  66. "PreprocessorDefinitions" => "PreprocessorDefinitions",
  67. # Code Generation
  68. # Language
  69. # Precompiled Headers
  70. "PrecompiledHeaderThrough" => "Create/UsePCHThroughFile",
  71. "PrecompiledHeaderFile" => "PrecompiledHeaderFile",
  72. # Output Files
  73. "AssemblerListingLocation" => "ASMListLocation",
  74. "ObjectFile" => "ObjectFileName",
  75. "ProgramDataBaseFileName" => "ProgramDatabaseFileName",
  76. "XMLDocumentationFileName" => "XMLDocumentationFileName",
  77. # Browse Information
  78. "BrowseInformationFile" => "BrowseFile",
  79. # Advanced
  80. "DisableSpecificWarnings" => "DisableSpecificWarnings",
  81. "ForcedIncludeFiles" => "ForceIncludes",
  82. "ForcedUsingFiles" => "ForceUsing",
  83. "UndefinePreprocessorDefinitions" => "UndefinePreprocessorDefinitions",
  84. # Command Line
  85. "AdditionalOptions" => "AdditionalOptions",
  86. },
  87. # Librarian
  88. "VCLibrarianTool" =>
  89. {
  90. # General
  91. "OutputFile" => "OutputFileexplo",
  92. "AdditionalDependencies" => "AdditionalDependencies",
  93. "AdditionalLibraryDirectories" => "AdditionalLibraryDirectories",
  94. "ModuleDefinitionFile" => "ModuleDefinitionFileName",
  95. "IgnoreDefaultLibraryNames" => "IgnoreSpecificLibrary",
  96. "ExportNamedFunctions" => "ExportNamedFunctions",
  97. "ForceSymbolReferences" => "ForceSymbolReferences",
  98. # Command LIne
  99. "AdditionalOptions" => "AdditionalOptions",
  100. },
  101. # Linker
  102. "VCLinkerTool" =>
  103. {
  104. # General
  105. "OutputFile" => "OutputFile",
  106. "Version" => "Version",
  107. "AdditionalLibraryDirectories" => "AdditionalLibraryDirectories",
  108. # Input
  109. "AdditionalDependencies" => "AdditionalDependencies",
  110. "IgnoreDefaultLibraryNames" => "IgnoreSpecificLibrary",
  111. "ModuleDefinitionFile" => "ModuleDefinitionFile",
  112. "AddModuleNamesToAssembly" => "AddModuleToAssembly",
  113. "EmbedManagedResourceFile" => "EmbedManagedResourceFile",
  114. "ForceSymbolReferences" => "ForceSymbolReferences",
  115. "DelayLoadDLLs" => "DelayLoadedDLLs",
  116. "AssemblyLinkResource" => "AssemblyLinkResource",
  117. # Manifest File
  118. "ManifestFile" => "ManifestFile",
  119. "AdditionalManifestDependencies" => "AdditionalManifestDependencies",
  120. # Debugging
  121. "ProgramDatabaseFile" => "GenerateProgramDatabaseFile",
  122. "StripPrivateSymbols" => "StripPrivateSymbols",
  123. "MapFileName" => "MapFileName",
  124. # System
  125. "HeapReserveSize" => "HeapReserverSize",
  126. "HeapCommitSize" => "HeapCommitSize",
  127. "StackReserveSize" => "StackReserveSize",
  128. "StackCommitSize" => "StackCommitSize",
  129. # Optimization
  130. "FunctionOrder" => "FunctionOrder",
  131. "ProfileGuidedDatabase" => "ProfileGuidedDatabase",
  132. # Embedded IDL
  133. "MidlCommandFile" => "MIDLCommands",
  134. "MergedIDLBaseFileName" => "MergedIDLBaseFileName",
  135. "TypeLibraryFile" => "TypeLibrary",
  136. "TypeLibraryResourceID" => "TypeLibResourceID",
  137. # Advanced
  138. "EntryPointSymbol" => "EntryPoint",
  139. "BaseAddress" => "BaseAddress",
  140. "ImportLibrary" => "ImportLibrary",
  141. "MergeSections" => "MergeSections",
  142. "KeyFile" => "KeyFile",
  143. "KeyContainer" => "KeyContainer",
  144. # Command LIne
  145. "AdditionalOptions" => "AdditionalOptions",
  146. },
  147. # Resources
  148. "VCResourceCompilerTool" =>
  149. {
  150. # General
  151. "PreprocessorDefinitions" => "PreprocessorDefinitions",
  152. "AdditionalIncludeDirectories" => "AdditionalIncludeDirectories",
  153. "ResourceOutputFileName" => "ResourceFileName",
  154. # Command LIne
  155. "AdditionalOptions" => "AdditionalOptions",
  156. },
  157. # Build Events
  158. "VCPreBuildEventTool" =>
  159. {
  160. # Pre-Build Event
  161. "CommandLine" => "CommandLine",
  162. "Description" => "Description",
  163. "ExcludedFromBuild" => "ExcludedFromBuild",
  164. },
  165. "VCPreLinkEventTool" =>
  166. {
  167. # Pre-Link Event
  168. "CommandLine" => "CommandLine",
  169. "Description" => "Description",
  170. "ExcludedFromBuild" => "ExcludedFromBuild",
  171. },
  172. "VCPostBuildEventTool" =>
  173. {
  174. # Post-Build Event
  175. "CommandLine" => "CommandLine",
  176. "Description" => "Description",
  177. "ExcludedFromBuild" => "ExcludedFromBuild",
  178. },
  179. # Custom Build Step
  180. "VCCustomBuildTool" =>
  181. {
  182. # Pre-Build Event
  183. "CommandLine" => "CommandLine",
  184. "Description" => "Description",
  185. "Outputs" => "Outputs",
  186. "AdditionalDependencies" => "AdditionalDependencies",
  187. },
  188. );
  189. ##############################################################################
  190. # Match vcproj option keywords with vpc keywords - only multi-value options
  191. # String on the left matches the option name in the VCProj.
  192. # String on the right matches the option name in vpc
  193. my(%configOptionsMultiValue) = (
  194. # General
  195. "ConfigurationType" => "ConfigurationType",
  196. "UseOfMFC" => "UseOfMFC",
  197. "UseOfAtl" => "UseOfATL",
  198. "CharacterSet" => "CharacterSet",
  199. # Debugging
  200. # C/C++
  201. # General
  202. "DebugInformationFormat" => "DebugInformationFormat",
  203. "SuppressStartupBanner" => "SuppressStartupBanner",
  204. "WarningLevel" => "WarningLevel",
  205. "Detect64BitPortabilityProblems" => "Detect64BitPortabilityIssues",
  206. "WarnAsError" => "TreatWarningsAsErrors",
  207. "UseUnicodeResponseFiles" => "UseUNICODEResponseFiles",
  208. # Optimization
  209. "Optimization" => "Optimization",
  210. "InlineFunctionExpansion" => "InlineFunctionExpansion",
  211. "EnableIntrinsicFunctions" => "EnableIntrinsicFunctions",
  212. "FavorSizeOrSpeed" => "FavorSizeOrSpeed",
  213. "OmitFramePointers" => "OmitFramePointers",
  214. "EnableFiberSafeOptimizations" => "EnableFiberSafeOptimizations",
  215. "WholeProgramOptimization" => "WholeProgramOptimization",
  216. # Preprocessor
  217. "IgnoreStandardIncludePath" => "IgnoreStandardIncludePath",
  218. "GeneratePreprocessedFile" => "GeneratePreprocessedFile",
  219. "KeepComments" => "KeepComments",
  220. # Code Generation
  221. "StringPooling" => "EnableStringPooling",
  222. "MinimalRebuild" => "EnableMinimalRebuild",
  223. "ExceptionHandling" => "EnableC++Exceptions",
  224. "SmallerTypeCheck" => "SmallerTypeCheck",
  225. "BasicRuntimeChecks" => "BasicRuntimeChecks",
  226. "RuntimeLibrary" => "RuntimeLibrary",
  227. "StructMemberAlignment" => "StructMemberAlignement",
  228. "BufferSecurityCheck" => "BufferSecurityCheck",
  229. "EnableFunctionLevelLinking" => "EnableFunctionLevelLinking",
  230. "EnableEnhancedInstructionSet" => "EnableEnhancedInstructionSet",
  231. "FloatingPointModel" => "FloatingPointModel",
  232. "FloatingPointExceptions" => "EnableFloatingPointExceptions",
  233. # Language
  234. "DisableLanguageExtensions" => "DisableLanguageExtensions",
  235. "DefaultCharIsUnsigned" => "DefaultCharUnsigned",
  236. "TreatWChar_tAsBuiltInType" => "TreatWchar_tAsBuiltinType",
  237. "ForceConformanceInForLoopScope" => "ForceConformanceInForLoopScope",
  238. "RuntimeTypeInfo" => "EnableRunTimeTypeInfo",
  239. "OpenMP" => "OpenMPSupport",
  240. # Precompiled Headers
  241. "UsePrecompiledHeader" => "Create/UsePrecompiledHeader",
  242. # Output Files
  243. "ExpandAttributedSource" => "ExpandAttributedSource",
  244. "AssemblerOutput" => "AssemblerOutput",
  245. "GenerateXMLDocumentationFiles" => "GenerateXMLDocumentationFiles",
  246. # Browse Information
  247. "BrowseInformation" => "EnableBrowseInformation",
  248. # Advanced
  249. "CallingConvention" => "CallingConvention",
  250. "CompileAs" => "CompileAs",
  251. "UndefineAllPreprocessorDefinitions" => "UndefineAllPreprocessorDefinitions",
  252. "UseFullPaths" => "UseFullPaths",
  253. "OmitDefaultLibName" => "OmitDefaultLibraryNames",
  254. "ErrorReporting" => "ErrorReporting",
  255. # Librarian
  256. # General
  257. "SuppressStartupBanner" => "SuppressStartupBanner",
  258. "IgnoreAllDefaultLibraries" => "IgnoreAllDefaultLibraries",
  259. "UseUnicodeResponseFiles" => "UseUNICODEResponseFiles",
  260. "LinkLibraryDependencies" => "LinkLibraryDependencies",
  261. # Linker
  262. # General
  263. "ShowProgress" => "ShowProgress",
  264. "LinkIncremental" => "EnableIncrementalLinking",
  265. "SuppressStartupBanner" => "SuppressStartupBanner",
  266. "IgnoreImportLibrary" => "IgnoreImportLibrary",
  267. "RegisterOutput" => "RegisterOutput",
  268. "LinkLibraryDependencies" => "LinkLibraryDependencies",
  269. "UseLibraryDependencyInputs" => "UseLibraryDependencyInputs",
  270. "UseUnicodeResponseFiles" => "UseUNICODEResponseFiles",
  271. # Input
  272. "IgnoreAllDefaultLibraries" => "IgnoreAllDefaultLibraries",
  273. # Manifest File
  274. "GenerateManifest" => "GenerateManifest",
  275. "AllowIsolation" => "AllowIsolation",
  276. # Debugging
  277. "GenerateDebugInformation" => "GenerateDebugInfo",
  278. "GenerateMapFile" => "GenerateMapFile",
  279. "MapExports" => "MapExports",
  280. "AssemblyDebug" => "DebuggableAssembly",
  281. # System
  282. "SubSystem" => "SubSystem",
  283. "LargeAddressAware" => "EnableLargeAddresses",
  284. "TerminalServerAware" => "TerminalServer",
  285. "SwapRunFromCD" => "SwapRunFromCD",
  286. "SwapRunFromNet" => "SwapRunFromNetwork",
  287. "Driver" => "Driver",
  288. # Optimization
  289. "OptimizeReferences" => "References",
  290. "EnableCOMDATFolding" => "EnableCOMDATFolding",
  291. "OptimizeForWindows98" => "OptimizeForWindows98",
  292. "LinkTimeCodeGeneration" => "LinkTimeCodeGeneration",
  293. # Embedded IDL
  294. "IgnoreEmbeddedIDL" => "IgnoreEmbeddedIDL",
  295. # Advanced
  296. "ResourceOnlyDLL" => "NoEntryPoint",
  297. "SetChecksum" => "SetChecksum",
  298. "FixedBaseAddress" => "FixedBaseAddress",
  299. "TurnOffAssemblyGeneration" => "TurnOffAssemblyGeneration",
  300. "SupportUnloadOfDelayLoadedDLL" => "DelayLoadedDLL",
  301. "TargetMachine" => "TargetMachine",
  302. "Profile" => "Profile",
  303. "CLRThreadAttribute" => "CLRThreadAttribute",
  304. "CLRImageType" => "CLRImageType",
  305. "DelaySign" => "DelaySign",
  306. "ErrorReporting" => "ErrorReporting",
  307. "CLRUnmanagedCodeCheck" => "CLRUnmanagedCodeCheck",
  308. # Resources
  309. # General
  310. "Culture" => "Culture",
  311. "IgnoreStandardIncludePath" => "IgnoreStandardIncludePath",
  312. "ShowProgress" => "ShowProgress",
  313. );
  314. ##############################################################################
  315. # Match user option names to their lists of possible values
  316. my(%configOptionValues) = (
  317. # General
  318. "ConfigurationType" =>
  319. {
  320. "0" => "Makefile",
  321. "1" => "Application \(\.exe\)",
  322. "2" => "Dynamic Library \(\.dll\)",
  323. "3" => "Static Library \(\.lib\)",
  324. "4" => "Utility",
  325. },
  326. "UseOfMFC" =>
  327. {
  328. "0" => "Use Standard Windows Libraries",
  329. "1" => "Use MFC In A Static Library",
  330. "2" => "Use MFC In A Shared DLL",
  331. },
  332. "UseOfATL" =>
  333. {
  334. "0" => "Not Using ATL",
  335. "1" => "Static Link To ATL",
  336. "2" => "Dynamic Link To ATL",
  337. },
  338. "CharacterSet" =>
  339. {
  340. "0" => "Not Set",
  341. "1" => "Use Unicode Character Set",
  342. "2" => "Use Multi-Byte Character Set",
  343. },
  344. # Debugging
  345. # C/C++
  346. # General
  347. "DebugInformationFormat" =>
  348. {
  349. # These skip a number on purpose (per VS2005)
  350. "0" => "Disabled",
  351. "1" => "C7 Compatible \(\/Z7\)",
  352. "3" => "Program Database \(\/Zi\)",
  353. "4" => "Program Database for Edit & Continue \(\/ZI\)",
  354. },
  355. "SuppressStartupBanner" =>
  356. {
  357. "false" => "No",
  358. "true" => "Yes \(\/nologo\)",
  359. },
  360. "WarningLevel" =>
  361. {
  362. "0" => "Off: Turn Off All Warnings \(\/W0\)",
  363. "1" => "Level 1 \(\/W1\)",
  364. "2" => "Level 2 \(\/W2\)",
  365. "3" => "Level 3 \(\/W3\)",
  366. "4" => "Level 4 \(\/W4\)",
  367. },
  368. "Detect64BitPortabilityProblems" =>
  369. {
  370. "false" => "No",
  371. "true" => "Yes \(\/Wp64\)",
  372. },
  373. "WarnAsError" =>
  374. {
  375. "false" => "No",
  376. "true" => "Yes \(\/WX\)",
  377. },
  378. "UseUnicodeResponseFiles" =>
  379. {
  380. "false" => "No",
  381. "true" => "Yes",
  382. },
  383. # Optimization
  384. "Optimization" =>
  385. {
  386. "0" => "Disabled \(\/Od\)",
  387. "1" => "Minimize Size \(\/O1\)",
  388. "2" => "Maximize Speed \(\/O2\)",
  389. "3" => "Full Optimization \(\/Ox\)",
  390. "4" => "Custom",
  391. },
  392. "InlineFunctionExpansion" =>
  393. {
  394. "0" => "Default",
  395. "1" => "Only __inline \(\/Ob1\)",
  396. "2" => "Any Suitable \(\/Ob2\)",
  397. },
  398. "EnableIntrinsicFunctions" =>
  399. {
  400. "false" => "No",
  401. "true" => "Yes \(\/Oi\)",
  402. },
  403. "FavorSizeOrSpeed" =>
  404. {
  405. "0" => "Neither",
  406. "1" => "Favor Fast Code \(\/Ot\)",
  407. "2" => "Favor Small Code \(\/Os\)",
  408. },
  409. "OmitFramePointers" =>
  410. {
  411. "false" => "No",
  412. "true" => "Yes \(\/Oy\)",
  413. },
  414. "EnableFiberSafeOptimizations" =>
  415. {
  416. "false" => "No",
  417. "true" => "Yes \(\/GT\)",
  418. },
  419. "WholeProgramOptimization" =>
  420. {
  421. "false" => "No",
  422. "true" => "Enable link-time code generation \(\/GL\)",
  423. },
  424. # Preprocessor
  425. "IgnoreStandardIncludePath" =>
  426. {
  427. "false" => "No",
  428. "true" => "Yes \(\/X\)",
  429. },
  430. "GeneratePreprocessedFile" =>
  431. {
  432. "0" => "No",
  433. "1" => "With Line Numbers \(\/P\)",
  434. "2" => "Without Line Numbers \(\/EP \/P\)",
  435. },
  436. "KeepComments" =>
  437. {
  438. "false" => "No",
  439. "true" => "Yes \(\/C\)",
  440. },
  441. # Code Generation
  442. "StringPooling" =>
  443. {
  444. "false" => "No",
  445. "true" => "Yes \(\/GF\)",
  446. },
  447. "MinimalRebuild" =>
  448. {
  449. "false" => "No",
  450. "true" => "Yes \(\/Gm\)",
  451. },
  452. "ExceptionHandling" =>
  453. {
  454. "0" => "No",
  455. "1" => "Yes \(\/EHsc\)",
  456. "2" => "Yes With SEH Exceptions \(\/EHa\)",
  457. },
  458. "SmallerTypeCheck" =>
  459. {
  460. "false" => "No",
  461. "true" => "Yes \(\/RTCc\)",
  462. },
  463. "BasicRuntimeChecks" =>
  464. {
  465. "0" => "Default",
  466. "1" => "Stack Frames \(\/RTCs\)",
  467. "2" => "Uninitialized Variables \(\/RTCu\)",
  468. "3" => "Both \(\/RTC1, equiv\. to \/RTCsu\)",
  469. },
  470. "RuntimeLibrary" =>
  471. {
  472. "0" => "Multi-threaded \(\/MT\)",
  473. "1" => "Multi-threaded Debug \(\/MTd\)",
  474. "2" => "Multi-threaded DLL \(\/MD\)",
  475. "3" => "Multi-threaded Debug DLL \(\/MDd\)",
  476. },
  477. "StructMemberAlignment" =>
  478. {
  479. "0" => "Default",
  480. "1" => "1 Byte \(\/Zp1\)",
  481. "2" => "2 Bytes \(\/Zp2\)",
  482. "3" => "4 Bytes \(\/Zp4\)",
  483. "4" => "8 Bytes \(\/Zp8\)",
  484. "5" => "16 Bytes \(\/Zp16\)",
  485. },
  486. "BufferSecurityCheck" =>
  487. {
  488. "false" => "No (/GS-)",
  489. "true" => "Yes",
  490. },
  491. "EnableFunctionLevelLinking" =>
  492. {
  493. "false" => "No",
  494. "true" => "Yes \(/Gy\)",
  495. },
  496. "EnableEnhancedInstructionSet" =>
  497. {
  498. "0" => "Not Set",
  499. "1" => "Streaming SIMD Extensions \(\/arch:SSE\)",
  500. "2" => "Streaming SIMD Extensions 2 \(\/arch:SSE2\)",
  501. },
  502. "FloatingPointModel" =>
  503. {
  504. "0" => "Precise \(\/fp:precise\)",
  505. "1" => "Strict \(\/fp:strict\)",
  506. "2" => "Fast \(\/fp:fast\)",
  507. },
  508. "FloatingPointExceptions" =>
  509. {
  510. "false" => "No",
  511. "true" => "Yes \(\/fp:except\)",
  512. },
  513. # Language
  514. "DisableLanguageExtensions" =>
  515. {
  516. "false" => "No",
  517. "true" => "Yes \(/Za\)",
  518. },
  519. "DefaultCharIsUnsigned" =>
  520. {
  521. "false" => "No",
  522. "true" => "Yes \(\/J\)",
  523. },
  524. "TreatWChar_tAsBuiltInType" =>
  525. {
  526. "false" => "No \(\/Zc:wchar_t-\)",
  527. "true" => "Yes",
  528. },
  529. "ForceConformanceInForLoopScope" =>
  530. {
  531. "false" => "No \(\/Zc:forScope-\)",
  532. "true" => "Yes",
  533. },
  534. "RuntimeTypeInfo" =>
  535. {
  536. "false" => "No \(\/GR-\)",
  537. "true" => "Yes",
  538. },
  539. "OpenMP" =>
  540. {
  541. "false" => "No",
  542. "true" => "Yes \(\/openmp\)",
  543. },
  544. # Precompiled Headers
  545. "UsePrecompiledHeader" =>
  546. {
  547. "0" => "Not Using Precompiled Headers",
  548. "1" => "Create Precompiled Header \(\/Yc\)",
  549. "2" => "Use Precompiled Header \(\/Yu\)",
  550. },
  551. # Output Files
  552. "ExpandAttributedSource" =>
  553. {
  554. "false" => "No",
  555. "true" => "Yes \(\/Fx\)",
  556. },
  557. "AssemblerOutput" =>
  558. {
  559. "0" => "No Listing",
  560. "1" => "Assembly-Only Listing \(\/FA\)",
  561. "2" => "Assembly, Machine Code and Source \(\/FAcs\)",
  562. "3" => "Assembly With Machine Code \(\/FAc\)",
  563. "4" => "Assembly With Source Code \(\/FAs\)",
  564. },
  565. "GenerateXMLDocumentationFiles" =>
  566. {
  567. "false" => "No",
  568. "true" => "Yes (/doc)",
  569. },
  570. # Browse Information
  571. "BrowseInformation" =>
  572. {
  573. "0" => "None",
  574. "1" => "Include All Browse Information \(\/FR\)",
  575. "2" => "No Local Symbols \(\/Fr\)",
  576. },
  577. # Advanced
  578. "CallingConvention" =>
  579. {
  580. "0" => "__cdecl \(\/Gd\)",
  581. "1" => "__fastcall \(\/Gr\)",
  582. "2" => "__stdcall \(\/Gz\)",
  583. },
  584. "CompileAs" =>
  585. {
  586. "0" => "Default",
  587. "1" => "Compile as C Code \(\/TC\)",
  588. "2" => "Compile as C\+\+ Code \(\/TP\)",
  589. },
  590. "ShowIncludes" =>
  591. {
  592. "false" => "No",
  593. "true" => "Yes \(\/showIncludes\)",
  594. },
  595. "UndefineAllPreprocessorDefinitions" =>
  596. {
  597. "false" => "No",
  598. "true" => "Yes \(\/u\)",
  599. },
  600. "UseFullPaths" =>
  601. {
  602. "false" => "No",
  603. "true" => "Yes \(\/FC\)",
  604. },
  605. "OmitDefaultLibName" =>
  606. {
  607. "false" => "No",
  608. "true" => "Yes \(\/Zl\)",
  609. },
  610. "ErrorReporting" =>
  611. {
  612. "0" => "Default",
  613. "1" => "Prompt Immediately \(\/errorReport:prompt\)",
  614. "2" => "Queue For Next Login \(\/errorReport:queue\)",
  615. },
  616. # Librarian
  617. # General
  618. "SuppressStartupBanner" =>
  619. {
  620. "false" => "No",
  621. "true" => "Yes \(\/NOLOGO\)",
  622. },
  623. "IgnoreAllDefaultLibraries" =>
  624. {
  625. "false" => "No",
  626. "true" => "Yes \(\/NODEFAULTLIB\)",
  627. },
  628. "UseUnicodeResponseFiles" =>
  629. {
  630. "false" => "No",
  631. "true" => "Yes",
  632. },
  633. "LinkLibraryDependencies" =>
  634. {
  635. "false" => "No",
  636. "true" => "Yes",
  637. },
  638. # Linker
  639. #General
  640. "ShowProgress" =>
  641. {
  642. "0" => "Not Set",
  643. "1" => "Display All Progress Messages \(\/VERBOSE\)",
  644. "2" => "Displays Some Progress Messages \(\/VERBOSE:LIB\)",
  645. },
  646. "LinkIncremental" =>
  647. {
  648. "0" => "Default",
  649. "1" => "No \(\/INCREMENTAL:NO\)",
  650. "2" => "Yes \(\/INCREMENTAL\)",
  651. },
  652. "SuppressStartupBanner" =>
  653. {
  654. "false" => "No",
  655. "true" => "Yes \(\/NOLOGO\)",
  656. },
  657. "IgnoreImportLibrary" =>
  658. {
  659. "false" => "No",
  660. "true" => "Yes",
  661. },
  662. "RegisterOutput" =>
  663. {
  664. "false" => "No",
  665. "true" => "Yes",
  666. },
  667. "LinkLibraryDependencies" =>
  668. {
  669. "false" => "No",
  670. "true" => "Yes",
  671. },
  672. "UseLibraryDependencyInputs" =>
  673. {
  674. "false" => "No",
  675. "true" => "Yes",
  676. },
  677. "UseUnicodeResponseFiles" =>
  678. {
  679. "false" => "No",
  680. "true" => "Yes",
  681. },
  682. # Input
  683. "IgnoreAllDefaultLibraries" =>
  684. {
  685. "false" => "No",
  686. "true" => "Yes \(\/NODEFAULTLIB\)",
  687. },
  688. # Manifest File
  689. "GenerateManifest" =>
  690. {
  691. "false" => "No",
  692. "true" => "Yes",
  693. },
  694. "AllowIsolation" =>
  695. {
  696. "false" => "Don't allow side-by-side isolation \(\/ALLOWISOLATION:NO\)",
  697. "true" => "Yes",
  698. },
  699. # Debugging
  700. "GenerateDebugInformation" =>
  701. {
  702. "false" => "No",
  703. "true" => "Yes \(\/DEBUG\)",
  704. },
  705. "GenerateMapFile" =>
  706. {
  707. "false" => "No",
  708. "true" => "Yes \(\/MAP\)",
  709. },
  710. "MapExports" =>
  711. {
  712. "false" => "No",
  713. "true" => "Yes \(\/MAPINFO:EXPORTS\)",
  714. },
  715. "AssemblyDebug" =>
  716. {
  717. "0" => "No Debuggable attribute emitted",
  718. "1" => "Runtime tracking and disable optimizations \(\/ASSEMBLYDEBUG\)",
  719. "2" => "No runtime tracking and enable optimizations \(\/ASSEMBLYDEBUG:DISABLE\)",
  720. },
  721. # System
  722. "SubSystem" =>
  723. {
  724. "0" => "Not Set",
  725. "1" => "Console \(\/SUBSYSTEM:CONSOLE\)",
  726. "2" => "Windows \(\/SUBSYSTEM:WINDOWS\)",
  727. "3" => "Native \(\/SUBSYSTEM:NATIVE\)",
  728. "4" => "EFI Application \(\/SUBSYSTEM:EFI_APPLICATION\)",
  729. "5" => "EFI Boot Service Driver \(\/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER\)",
  730. "6" => "EFI ROM \(\/SUBSYSTEM:EFI_ROM\)",
  731. "7" => "EFI Runtime \(\/SUBSYSTEM:EFI_RUNTIME_DRIVER\)",
  732. "8" => "Posix \(\/SUBSYSTEM:POSIX\)",
  733. "9" => "WindowsCE \(\/SUBSYSTEM:WINDOWSCE\)",
  734. },
  735. "LargeAddressesAware" =>
  736. {
  737. "0" => "Default",
  738. "1" => "Do Not Support Addresses Larger Than 2 Gigabytes \(\/LARGEADDRESSAWARE:NO\)",
  739. "2" => "Support Addresses Larger Than 2 Gigabytes \(\/LARGEADDRESSAWARE\)",
  740. },
  741. "TerminalServerAware" =>
  742. {
  743. "0" => "Default",
  744. "1" => "Not Terminal Server Aware \(\/TSAWARE:NO\)",
  745. "2" => "Application is Terminal Server Aware \(\/TSAWARE\)",
  746. },
  747. "SwapRunFromCD" =>
  748. {
  749. "false" => "No",
  750. "true" => "Yes \(\/SWAPRUN:CD\)",
  751. },
  752. "SwapRunFromNet" =>
  753. {
  754. "false" => "No",
  755. "true" => "Yes \(\/SWAPRUN:NET\)",
  756. },
  757. "Driver" =>
  758. {
  759. "0" => "Not Set",
  760. "1" => "Driver \(\/DRIVER\)",
  761. "2" => "Up Only \(\/DRIVER:UPONLY\)",
  762. "3" => "WDM \(\/DRIVER:WDM\)",
  763. },
  764. #Optimization
  765. "OptimizeReferences" =>
  766. {
  767. "0" => "Default",
  768. "1" => "Keep Unreferenced Data \(\/OPT:NOREF\)",
  769. "2" => "Eliminate Unreferenced Data \(\/OPT:REF\)",
  770. },
  771. "EnableCOMDATFolding" =>
  772. {
  773. "0" => "Default",
  774. "1" => "Do Not Remove Redundant COMDATs \(\/OPT:NOICF\)",
  775. "2" => "Remove Redundant COMDATs \(\/OPT:ICF\)",
  776. },
  777. "OptimizeForWindows98" =>
  778. {
  779. "0" => "Default",
  780. "1" => "No \(\/OPT:NOWIN98\)",
  781. "2" => "Yes \(\/OPT:WIN98\)",
  782. },
  783. "LinkTimeCodeGeneration" =>
  784. {
  785. "0" => "Default",
  786. "1" => "Use Link Time Code Generation \(\/ltcg\)",
  787. "2" => "Profile Guided Optimization - Instrument \(\/ltcg:pginstrument\)",
  788. "3" => "Profile Guided Optimization - Optimize \(\/ltcg:pgoptimize\)",
  789. "4" => "Profile Guided Optimization - Update \(\/ltcg:pgupdate\)",
  790. },
  791. # Embedded IDL
  792. "IgnoreEmbeddedIDL" =>
  793. {
  794. "false" => "No",
  795. "true" => "Yes \(\/IGNOREIDL\)",
  796. },
  797. #Advanced
  798. "ResourceOnlyDLL" =>
  799. {
  800. "false" => "No",
  801. "true" => "Yes \(\/NOENTRY\)",
  802. },
  803. "SetChecksum" =>
  804. {
  805. "false" => "No",
  806. "true" => "Yes \(\/RELEASE\)",
  807. },
  808. "FixedBaseAddress" =>
  809. {
  810. "0" => "Default",
  811. "1" => "Generate a relocation section \(\/FIXED:NO\)",
  812. "2" => "Image must be loaded at a fixed address \(\/FIXED\)",
  813. },
  814. "TurnOffAssemblyGeneration" =>
  815. {
  816. "false" => "No",
  817. "true" => "Yes \(\/NOASSEMBLY\)",
  818. },
  819. "SupportUnloadOfDelayLoadedDLL" =>
  820. {
  821. "0" => "Don't Support Unload",
  822. "1" => "Support Unload \(\/DELAY:UNLOAD\)",
  823. },
  824. "TargetMachine" =>
  825. {
  826. "0" => "Not Set",
  827. "1" => "MachineX86 \(\/MACHINE:X86\)",
  828. "2" => "MachineAM33 \(\/MACHINE:AM33\)",
  829. "3" => "MachineARM \(\/MACHINE:ARM\)",
  830. "4" => "MachineEBC \(\/MACHINE:EBC\)",
  831. "5" => "MachineIA64 \(\/MACHINE:IA64\)",
  832. "6" => "MachineM32R \(\/MACHINE:M32R\)",
  833. "7" => "MachineMIPS \(\/MACHINE:MIPS\)",
  834. "8" => "MachineMIPS16 \(\/MACHINE:MIPS16\)",
  835. "9" => "MachineMIPSFPU \(\/MACHINE:MIPSFPU\)",
  836. "10" => "MachineMIPSFPU16 \(\/MACHINE:MIPSFPU16\)",
  837. "11" => "MachineMIPSR41XX \(\/MACHINE:MIPSR41XX\)",
  838. "12" => "MachineSH3 \(\/MACHINE:SH3\)",
  839. "13" => "MachineSH4 \(\/MACHINE:SH4\)",
  840. "14" => "MachineSH5 \(\/MACHINE:SH5\)",
  841. "15" => "MachineTHUMB \(\/MACHINE:THUMB\)",
  842. "16" => "MachineX64 \(\/MACHINE:X64\)",
  843. },
  844. "Profile" =>
  845. {
  846. "false" => "No",
  847. "true" => "Enable Profiling information \(\/PROFILE\)",
  848. },
  849. "CLRThreadAttribute" =>
  850. {
  851. "0" => "No threading attribute set",
  852. "1" => "MTA threading attribute \(\/CLRTHREADATTRIBUTE:MTA\)",
  853. "2" => "STA threading attribute \(\/CLRTHREADATTRIBUTE:STA\)",
  854. },
  855. "CLRImageType" =>
  856. {
  857. "0" => "Default image type",
  858. "1" => "Force IJW image \(\/CLRIMAGETYPE:IJW\)",
  859. "2" => "Force pure IL image \(\/CLRIMAGETYPE:PURE\)",
  860. "3" => "Force safe IL image \(\/CLRIMAGETYPE:SAFE\)",
  861. },
  862. "DelaySign" =>
  863. {
  864. "false" => "No",
  865. "true" => "Yes \(\/DELAYSIGN\)",
  866. },
  867. "ErrorReporting" =>
  868. {
  869. "0" => "Default",
  870. "1" => "Prompt Immediately \(\/ERRORREPORT:PROMPT\)",
  871. "2" => "Queue For Next Login \(\/ERRORREPORT:QUEUE\)",
  872. },
  873. "CLRUnmanagedCodeCheck" =>
  874. {
  875. "false" => "No",
  876. "true" => "Apply Unmanaged Code Check \(\/CLRUNMANAGEDCODECHECK\)",
  877. },
  878. # Resources
  879. # General
  880. "Culture" =>
  881. {
  882. "1000" => "Default",
  883. "1001" => "Afrikaans \(0x436\)",
  884. "1002" => "Albanian \(0x41c\)",
  885. "1003" => "Arabic (Saudi Arabia) \(0x401\)",
  886. "1004" => "Arabic (Iraq) \(0x801\)",
  887. "1005" => "Arabic (Egypt) \(0xc01\)",
  888. "1006" => "Arabic (Libya) \(0x1001\)",
  889. "1007" => "Arabic (Algeria) \(0x1401\)",
  890. "1008" => "Arabic (Morocco) \(0x1801\)",
  891. "1009" => "Arabic (Tunisia) \(0x1c01\)",
  892. "1010" => "Arabic (Oman) \(0x2001\)",
  893. "1011" => "Arabic (Yemen) \(0x2401\)",
  894. "1012" => "Arabic (Syria) \(0x2801\)",
  895. "1013" => "Arabic (Jordan) \(0x2c01\)",
  896. "1014" => "Arabic (Lebanon) \(0x3001\)",
  897. "1015" => "Arabic (Kuwait) \(0x3401\)",
  898. "1016" => "Arabic (U.A.E.) \(0x3801\)",
  899. "1017" => "Arabic (Bahrain) \(0x3c01\)",
  900. "1018" => "Arabic (Qatar) \(0x4001\)",
  901. "1019" => "Basque \(0x42d\)",
  902. "1020" => "Bulgarian \(0x402\)",
  903. "1021" => "Belarusian \(0x423\)",
  904. "1022" => "Catalan \(0x403\)",
  905. "1023" => "Chinese (Taiwan) \(0x404\)",
  906. "1024" => "Chinese (PRC) \(0x804\)",
  907. "1025" => "Chinese (Hong Kong S.A.R.) \(0xc04\)",
  908. "1026" => "Chinese (Singapore) \(0x1004\)",
  909. "1027" => "Croatian \(0x41a\)",
  910. "1028" => "Czech \(0x405\)",
  911. "1029" => "Danish \(0x406\)",
  912. "1030" => "Dutch (Netherlands) \(0x413\)",
  913. "1031" => "Dutch (Belgium) \(0x813\)",
  914. "1032" => "English (United States) \(0x409\)",
  915. "1033" => "English (United Kingdom) \(0x809\)",
  916. "1034" => "English (Australia) \(0xc09\)",
  917. "1035" => "English (Canada) \(0x1009\)",
  918. "1036" => "English (New Zealand) \(0x1409\)",
  919. "1037" => "English (Ireland) \(0x1809\)",
  920. "1038" => "English (South Africa) \(0x1c09\)",
  921. "1039" => "English (Jamaica) \(0x2009\)",
  922. "1040" => "English (Caribbean) \(0x2409\)",
  923. "1041" => "Estonian \(0x425\)",
  924. "1042" => "Farsi \(0x429\)",
  925. "1043" => "Finnish \(0x40b)",
  926. "1044" => "French (France) \(0x40c\)",
  927. "1045" => "French (Belgium) \(0x80c\)",
  928. "1046" => "French (Canada) \(0xc0c\)",
  929. "1047" => "French (Switzerland) \(0x100c\)",
  930. "1048" => "French (Luxembourg) \(0x140c\)",
  931. "1049" => "German (Germany) \(0x407\)",
  932. "1050" => "German (Switzerland) \(0x807\)",
  933. "1051" => "German (Austria) \(0xc07\)",
  934. "1052" => "German (Luxembourg) \(0x1007\)",
  935. "1053" => "German (Liechtenstein) \(0x1407\)",
  936. "1054" => "Greek \(0x408\)",
  937. "1055" => "Hebrew \(0x40d\)",
  938. "1056" => "Hungarian \(0x40e\)",
  939. "1057" => "Icelandic \(0x40f\)",
  940. "1058" => "Indonesian \(0x421\)",
  941. "1059" => "Italian (Italy) \(0x410\)",
  942. "1060" => "Italian (Switzerland) \(0x810\)",
  943. "1061" => "Japanese \(0x411\)",
  944. "1062" => "Korean \(0x412\)",
  945. "1063" => "0x812",
  946. "1064" => "Latvian \(0x426\)",
  947. "1065" => "Lithuanian \(0x427\)",
  948. "1066" => "Norwegian (Bokmal) \(0x414\)",
  949. "1067" => "Norwegian (Nynorsk) \(0x814\)",
  950. "1068" => "Polish \(0x415\)",
  951. "1069" => "Portuguese (Brazil) \(0x416\)",
  952. "1070" => "Portuguese (Portugal) \(0x816\)",
  953. "1071" => "Romanian \(0x418\)",
  954. "1072" => "Russian \(0x419\)",
  955. "1073" => "Slovak \(0x41b\)",
  956. "1074" => "Spanish (Traditional Sort) \(0x40a\)",
  957. "1075" => "Spanish (Mexico) \(0x80a\)",
  958. "1076" => "Spanish (International Sort) \(0xc0a\)",
  959. "1077" => "Spanish (Guatemala) \(0x100a\)",
  960. "1078" => "Spanish (Costa Rica) \(0x140a\)",
  961. "1079" => "Spanish (Panama) \(0x180a\)",
  962. "1080" => "Spanish (Dominican Republic) \(0x1c0a\)",
  963. "1081" => "Spanish (Venezuela) \(0x200a\)",
  964. "1082" => "Spanish (Colombia) \(0x240a\)",
  965. "1083" => "Spanish (Peru) \(0x280a\)",
  966. "1084" => "Spanish (Argentina) \(0x2c0a\)",
  967. "1085" => "Spanish (Ecuador) \(0x300a\)",
  968. "1086" => "Spanish (Chile) \(0x340a\)",
  969. "1087" => "Spanish (Uruguay) \(0x380a\)",
  970. "1088" => "Spanish (Paraguay) \(0x3c0a\)",
  971. "1089" => "Spanish (Bolivia) \(0x400a\)",
  972. "1090" => "Swedish \(0x41d\)",
  973. "1091" => "Thai \(0x41e\)",
  974. "1092" => "Turkish \(0x41f\)",
  975. "1093" => "Ukrainian \(0x422\)",
  976. "1094" => "Serbian (Latin) \(0x81a\)",
  977. "1095" => "Urdu \(0x420\)",
  978. },
  979. "IgnoreStandardIncludePath" => "IgnoreStandardIncludePath",
  980. {
  981. "1" => "No",
  982. "2" => "Yes \(\/X\)",
  983. },
  984. "ShowProgress" => "ShowProgress",
  985. {
  986. "1" => "No",
  987. "2" => "Yes \(\/v\)",
  988. },
  989. );
  990. # Hash matches vcproj configuration names with their output versions
  991. my(%configurationNames) = ( "Base" => "base",
  992. "DoD" => "dod",
  993. "CounterStrike" => "cstrike",
  994. "HL1" => "hl1",
  995. "HL2" => "hl2",
  996. "Episodic HL2" => "episodic",
  997. "TF" => "tf",
  998. "SDK" => "sdk",
  999. "HL2MP" => "hl2mp",
  1000. "LostCoast" => "lostcoast",
  1001. "Portal" => "portal",
  1002. "Dedicated" => "dedicated",
  1003. );
  1004. my(@configurations) = keys %configurationNames;
  1005. my(%toolNames) = (
  1006. "VCCLCompilerTool" => "Compiler",
  1007. "VCCustomBuildTool" => "CustomBuildStep",
  1008. "VCLinkerTool" => "Linker",
  1009. "VCPostBuildEventTool" => "PostBuildEvent",
  1010. "VCPreBuildEventTool" => "PreBuildEvent",
  1011. "VCPreLinkEventTool" => "PreLinkEvent",
  1012. "VCResourceCompilerTool" => "Resources",
  1013. "VCLibrarianTool" => "Librarian",
  1014. );
  1015. my(@tools) = values %toolNames;
  1016. my($baseConfiguration) = "Application (.exe)";
  1017. my(%baseConfigurationTypes) = (
  1018. "Dynamic Library (.dll)" => "dll",
  1019. "Application (.exe)" => "exe",
  1020. "Static Library (.lib)" => "lib",
  1021. "Utility" => "lib",
  1022. );
  1023. my($configurationSubsystem) = "con";
  1024. my(%outputs);
  1025. my(%excludes);
  1026. my(%filesAdded);
  1027. for ( @configurations )
  1028. {
  1029. $outputs{$_} = ();
  1030. $excludes{$_} = 0;
  1031. $filesAdded{$_} = 0;
  1032. }
  1033. my(%keytabs) = ( 0 => "\t\t\t\t\t\t\t\t\t\t",
  1034. 4 => "\t\t\t\t\t\t\t\t\t",
  1035. 8 => "\t\t\t\t\t\t\t\t",
  1036. 12 => "\t\t\t\t\t\t\t",
  1037. 16 => "\t\t\t\t\t\t",
  1038. 20 => "\t\t\t\t\t",
  1039. 24 => "\t\t\t\t",
  1040. 28 => "\t\t\t",
  1041. 32 => "\t\t",
  1042. 36 => "\t",
  1043. );
  1044. ######################################################
  1045. # Subroutines
  1046. ######################################################
  1047. sub break
  1048. {
  1049. return;
  1050. }
  1051. sub outputToAllConfigurations
  1052. {
  1053. for ( @configurations )
  1054. {
  1055. push( @{ $outputs{$_} }, @lineToPrint );
  1056. }
  1057. }
  1058. sub compare_arrays
  1059. {
  1060. my ($first, $second) = @_;
  1061. return 0 unless @$first == @$second;
  1062. for (my $i = 0; $i < @$first; $i++)
  1063. {
  1064. if ( $first->[$i] =~ /^(Debug|Release)$/ )
  1065. {
  1066. next;
  1067. }
  1068. return 0 if $first->[$i] ne $second->[$i];
  1069. }
  1070. return 1;
  1071. }
  1072. sub set_current_configuration
  1073. {
  1074. my($line) = shift;
  1075. $line =~ ( /Name="(\w+) ([\w\s]*)\|/ );
  1076. my($name1) = $1;
  1077. my($name2) = $2;
  1078. if ( $name2 =~ /Release|Debug/ )
  1079. {
  1080. $currentConfig = $name1;
  1081. }
  1082. else
  1083. {
  1084. $currentConfig = $name2;
  1085. }
  1086. if ( $line =~ ( /Name="(Release|Debug)\|/ ) )
  1087. {
  1088. # default configurations
  1089. $currentConfig = "Base";
  1090. }
  1091. }
  1092. ####################################################
  1093. sub processFileConfig
  1094. {
  1095. $spaceBeforeFile = 1;
  1096. my($splitFiles) = 0;
  1097. my($line) = $_[++$lineCt];
  1098. # Set the current configuration
  1099. set_current_configuration( $line );
  1100. push( @tabs, "\t" );
  1101. $line =~ ( /Name="([\w\s]*)\|/ );
  1102. my($configName) = ( $1 =~ /(Debug|Release)/ );
  1103. push( @{ $configOutput{$currentConfig} }, @tabs, "\$Configuration\t\"", $configName, "\"\n" );
  1104. push( @{ $configOutput{$currentConfig} }, @tabs, "\{\n" );
  1105. # Process the configuration
  1106. my($configResult) = processConfiguration( @_ );
  1107. # end if this configuration
  1108. push( @{ $configOutput{$currentConfig} }, @tabs, "\}\n" );
  1109. if ( $configResult == 1 )
  1110. {
  1111. # Mark this file as excluded for the current configuration
  1112. $excludes{$currentConfig} = 1;
  1113. $splitFiles = 1;
  1114. }
  1115. elsif ( $configResult == -1 )
  1116. {
  1117. # Configuration is empty, so clear it
  1118. @{ $configOutput{$currentConfig} } = ();
  1119. }
  1120. pop( @tabs );
  1121. return $splitFiles;
  1122. }
  1123. ####################################################
  1124. sub processFile
  1125. {
  1126. # get the file name and path
  1127. @lineToPrint = ();
  1128. if ( $spaceBeforeFile == 1 )
  1129. {
  1130. $spaceBeforeFile = 0;
  1131. # push( @lineToPrint, "\n" );
  1132. }
  1133. $_[++$lineCt] =~ ( /RelativePath="([^"]+)"/ );
  1134. my $line = $1;
  1135. # replace ..\ and .\ in filenames
  1136. $line =~ s/^\Q$srcdirBackslash\E\\/\$SRCDIR\\/;
  1137. $line =~ s/^\Q$srcdirForwardslash\E\//\$SRCDIR\\/;
  1138. $line =~ s/^\.\\//;
  1139. push( @lineToPrint, @tabs, "\t\$File\t\"", $line, "\"\n" );
  1140. push( @tabs, "\t" );
  1141. my($splitFiles) = 0;
  1142. my($configFound) = 0;
  1143. # loop until the </File> tag
  1144. %configOutput = ();
  1145. while ( $_[++$lineCt] !~ /^\s*\<\/File\>$/ )
  1146. {
  1147. # Check for file specific configurations
  1148. if ( $_[$lineCt] =~ /^\s*\<FileConfiguration/ )
  1149. {
  1150. $configFound = 1;
  1151. $splitFiles += processFileConfig( @_ );
  1152. }
  1153. }
  1154. # Compare the configurations to see if the files should be split
  1155. if ( $configFound && !$splitFiles )
  1156. {
  1157. for ( @configurations )
  1158. {
  1159. if ( $_ eq "Base" || $_ eq "Dedicated" )
  1160. {
  1161. next;
  1162. }
  1163. if ( !compare_arrays( \@{ $configOutput{"HL2"} }, \@{ $configOutput{$_} } ) )
  1164. {
  1165. $splitFiles = 1;
  1166. last;
  1167. }
  1168. }
  1169. if ( !$splitFiles )
  1170. {
  1171. push( @{ $configOutput{"Base"} }, @{ $configOutput{"HL2"} } );
  1172. }
  1173. }
  1174. # Add the file and configuration to the appropriate projects
  1175. if ( !$splitFiles )
  1176. {
  1177. if ( @{ $configOutput{"Base"} } > 0 )
  1178. {
  1179. push( @{ $outputs{"Base"} }, @lineToPrint, @tabs, "\{\n" );
  1180. push( @{ $outputs{"Base"} }, @{ $configOutput{"Base"} } );
  1181. push( @{ $outputs{"Base"} }, @tabs, "\}\n\n" );
  1182. }
  1183. else
  1184. {
  1185. push( @{ $outputs{"Base"} }, @lineToPrint );
  1186. }
  1187. $filesAdded{"Base"} = 1;
  1188. }
  1189. else
  1190. {
  1191. $excludes{"Base"} = 1;
  1192. $exclusionsFound = 1;
  1193. for ( @configurations )
  1194. {
  1195. if ( !$excludes{$_} )
  1196. {
  1197. if ( @{ $configOutput{$_} } > 0 )
  1198. {
  1199. push( @{ $outputs{$_} }, @lineToPrint, @tabs, "\{\n" );
  1200. push( @{ $outputs{$_} }, @{ $configOutput{$_} } );
  1201. push( @{ $outputs{$_} }, @tabs, "\}\n\n" );
  1202. }
  1203. else
  1204. {
  1205. push( @{ $outputs{$_} }, @lineToPrint );
  1206. }
  1207. $filesAdded{$_} = 1;
  1208. }
  1209. else
  1210. {
  1211. # reset the exclude flag
  1212. $excludes{$_} = 0;
  1213. }
  1214. }
  1215. }
  1216. pop( @tabs );
  1217. }
  1218. ####################################################
  1219. sub processFolder
  1220. {
  1221. push( @tabs, "\t" );
  1222. # Grab the folder name and add it to all configuration's outputs
  1223. $_[++$lineCt] =~ ( /Name="([^"]+)"/ );
  1224. @lineToPrint = ( @tabs, "\$Folder\t\"", $1, "\"\n", @tabs, "\{\n" );
  1225. outputToAllConfigurations();
  1226. # Loop until the </Filter> tag
  1227. while ( $_[++$lineCt] !~ /^\s*\<\/Filter\>$/ )
  1228. {
  1229. if ( $_[$lineCt] =~ /^\s*\<Filter$/ )
  1230. {
  1231. # Start of a new folder
  1232. if ( $spaceBeforeFolder == 1 )
  1233. {
  1234. $spaceBeforeFolder = 0;
  1235. @lineToPrint = "\n";
  1236. outputToAllConfigurations();
  1237. }
  1238. processFolder( @_ );
  1239. }
  1240. elsif ( $_[$lineCt] =~ /^\s*\<File$/ )
  1241. {
  1242. # Start of a new file
  1243. processFile( @_ );
  1244. $spaceBeforeFolder = 1;
  1245. }
  1246. }
  1247. # End of the folder
  1248. @lineToPrint = ( @tabs, "\}\n" );
  1249. for ( @configurations )
  1250. {
  1251. push( @{ $outputs{$_} }, @lineToPrint );
  1252. }
  1253. pop( @tabs );
  1254. }
  1255. ####################################################
  1256. sub processConfigOption
  1257. {
  1258. my($line) = shift;
  1259. my($tool) = shift;
  1260. # Get the keyname and value
  1261. if ( $line !~ /(\w+)="([^"\n]*)(.*)/ )
  1262. {
  1263. return;
  1264. }
  1265. my($keyname) = $1;
  1266. my($keyvalue) = $2;
  1267. my($lastChar) = $3;
  1268. my($outputvalue);
  1269. # Lookup the keyname
  1270. if ( $outputvalue = $configOptionsSingleValue{$tool}{$keyname} )
  1271. {
  1272. # A single value option - outputvalue is the VPC defined keyname
  1273. # Translate true/false to Yes/No
  1274. $keyvalue =~ s/true/Yes/;
  1275. $keyvalue =~ s/false/No/;
  1276. $keyname = $outputvalue;
  1277. }
  1278. elsif ( $outputvalue = $configOptionValues{$keyname}{$keyvalue} )
  1279. {
  1280. # A multi-value option - outputvalue is the desired option setting in string form
  1281. my($translatedName) = $configOptionsMultiValue{$keyname};
  1282. # Do some bookkeeping for later
  1283. if ( $translatedName =~ /^SubSystem$/ && $outputvalue =~ /Windows/ )
  1284. {
  1285. $configurationSubsystem = "win";
  1286. }
  1287. elsif ( $translatedName =~ /^ConfigurationType$/ )
  1288. {
  1289. $baseConfiguration = $outputvalue;
  1290. }
  1291. if ( $usestring )
  1292. {
  1293. return $translatedName, $outputvalue;
  1294. }
  1295. else
  1296. {
  1297. return $translatedName, $keyvalue;
  1298. }
  1299. }
  1300. else
  1301. {
  1302. # For debugging
  1303. print( "Line ", $lineCt, ": Error, no config found for Tool: ", $tool, ", ", $keyname, "=", $keyvalue, "\n" );
  1304. # push( @tempOutput, "\/\/" );
  1305. }
  1306. # special handling for multi-line options
  1307. if ( !$lastChar )
  1308. {
  1309. my($nextline) = ( @lines[++$lineCt] =~ /([^\n]*)/ );
  1310. while( $nextline !~ /\"/ )
  1311. {
  1312. $keyvalue = join( '', $keyvalue, "\" \\ \"\\n\"\n", @tabs, $keytabs{0}, "\"", $nextline );
  1313. ($nextline) = ( @lines[++$lineCt] =~ /([^\n]*)/ );
  1314. }
  1315. }
  1316. # replace &quot; and ..\ and .\ in option values
  1317. $keyvalue =~ s/(?<=[^\\])\Q$srcdirBackslash\E\\/\$SRCDIR\\/g;
  1318. $keyvalue =~ s/(?<=[^\/])\Q$srcdirForwardslash\E\//\$SRCDIR\\/g;
  1319. $keyvalue =~ s/^\Q$srcdirBackslash\E\\/\$SRCDIR\\/g;
  1320. $keyvalue =~ s/^\Q$srcdirForwardslash\E\//\$SRCDIR\\/g;
  1321. $keyvalue =~ s/^\.\\//g;
  1322. $keyvalue =~ s/\&quot\;/\$QUOTE/g;
  1323. return $keyname, $keyvalue;
  1324. }
  1325. ####################################################
  1326. sub processBuildTool
  1327. {
  1328. push( @tabs, "\t" );
  1329. # Grab the tool name
  1330. $_[++$lineCt] =~ ( /Name="([^"]+)"/ );
  1331. my($toolName) = $1;
  1332. if ( !$toolNames{$toolName} )
  1333. {
  1334. pop( @tabs );
  1335. while ( $_[$lineCt] !~ /\/\>$/ )
  1336. {
  1337. ++$lineCt;
  1338. }
  1339. return;
  1340. }
  1341. my( @tempOutput );
  1342. if ( !$parsingFiles )
  1343. {
  1344. push( @tempOutput, "\n" );
  1345. }
  1346. push( @tempOutput, @tabs, "\$", $toolNames{$toolName}, "\n" );
  1347. push( @tempOutput, @tabs, "\{\n" );
  1348. # Loop until the /> tag
  1349. my($keyname);
  1350. my($keyvalue);
  1351. my($optionsFound) = 0;
  1352. while ( $_[$lineCt] !~ /\/\>$/ )
  1353. {
  1354. ($keyname, $keyvalue) = processConfigOption( $_[++$lineCt], $toolName );
  1355. if ( $keyname )
  1356. {
  1357. if ( $keyvalue || !$stripEmptyOptions )
  1358. {
  1359. $optionsFound = 1;
  1360. }
  1361. my($len) = $tabstop * int( (length( $keyname ) + $tabstop + 1) / $tabstop );
  1362. push( @tempOutput, @tabs, "\t\$", $keyname, $keytabs{$len}, "\"", $keyvalue, "\"\n" );
  1363. }
  1364. }
  1365. pop( @tabs );
  1366. # End of the tool
  1367. if ( $optionsFound )
  1368. {
  1369. push( @{ $configOutput{$currentConfig} }, @tempOutput, @tabs, "\t}\n" );
  1370. return 1;
  1371. }
  1372. return 0;
  1373. }
  1374. ####################################################
  1375. sub processConfiguration
  1376. {
  1377. my( $configOptionsFound ) = 0;
  1378. my( $startedGeneral ) = 0;
  1379. # Loop until the </Configuration> tag
  1380. while ( $_[++$lineCt] !~ /^\s*\<\/(File)*Configuration\>$/ )
  1381. {
  1382. if ( $_[$lineCt] =~ /^\s*\<Tool$/ )
  1383. {
  1384. if ( $startedGeneral )
  1385. {
  1386. # close out the faked "General" category
  1387. $startedGeneral = 0;
  1388. push( @{ $configOutput{$currentConfig} }, @tabs, "\}\n" );
  1389. pop( @tabs );
  1390. }
  1391. # Start of a new build tool
  1392. $configOptionsFound += processBuildTool( @_ );
  1393. }
  1394. elsif ( $_[$lineCt] =~ /=/ )
  1395. {
  1396. # Process the main configuration properties
  1397. if ( !$startedGeneral && !$parsingFiles )
  1398. {
  1399. # start the fake "General" category
  1400. $startedGeneral = 1;
  1401. push( @tabs, "\t" );
  1402. push( @{ $configOutput{$currentConfig} }, @tabs, "\$General\n" );
  1403. push( @{ $configOutput{$currentConfig} }, @tabs, "\{\n" );
  1404. }
  1405. my($keyname);
  1406. my($keyvalue);
  1407. ($keyname, $keyvalue) = processConfigOption( $_[$lineCt], "General" );
  1408. if ( $keyname )
  1409. {
  1410. # Handle some special cases
  1411. if ( $keyname =~ /^ExcludedFromBuild$/ && $keyvalue =~ /^Yes$/ )
  1412. {
  1413. @{ $configOutput{$currentConfig} } = ();
  1414. return 1;
  1415. }
  1416. ++$configOptionsFound;
  1417. my($len) = $tabstop * int( (length( $keyname ) + $tabstop + 1) / $tabstop );
  1418. push( @{ $configOutput{$currentConfig} }, @tabs, "\t\$", $keyname, $keytabs{$len}, "\"", $keyvalue, "\"\n" );
  1419. }
  1420. }
  1421. }
  1422. # See if any config options were recorded
  1423. if ( !$configOptionsFound )
  1424. {
  1425. return -1;
  1426. }
  1427. return 0;
  1428. }
  1429. ######################################################
  1430. # Code section
  1431. ######################################################
  1432. if ( !$ARGV[0] )
  1433. {
  1434. print( "Error: no project name specified\n" );
  1435. exit;
  1436. }
  1437. # Read in the source file
  1438. my $infile = $ARGV[0];
  1439. $infile =~ s/.vcproj//;
  1440. open(INFILE, "$infile.vcproj" );
  1441. @lines = <INFILE>;
  1442. close( INFILE );
  1443. my(@pathArray) = split(/\\/, $infile );
  1444. my($vcprojname) = $pathArray[$#pathArray];
  1445. unless ( $outputPath )
  1446. {
  1447. $outputPath = $infile;
  1448. $outputPath =~ s/$vcprojname//;
  1449. }
  1450. # build the fileheader
  1451. my(@fileheader);
  1452. push( @fileheader, "\/\/-----------------------------------------------------------------------------\n" );
  1453. push( @fileheader, "\/\/\t",uc($vcprojname),".VPC\n" );
  1454. push( @fileheader, "\/\/\n" );
  1455. push( @fileheader, "\/\/\tProject Script\n" );
  1456. push( @fileheader, "\/\/-----------------------------------------------------------------------------\n" );
  1457. push( @fileheader, "\/\/ ***** AUTO-GENERATED: PLEASE FIXUP MANUALLY BEFORE USING THIS SCRIPT! *****\n" );
  1458. push( @fileheader, "\n" );
  1459. push( @fileheader, "\$Macro SRCDIR\t\t\".." );
  1460. $srcdirBackslash = "..";
  1461. my($dirct) = $#pathArray - 2;
  1462. for ( my($i) = 0; $i < $dirct; ++$i )
  1463. {
  1464. push( @fileheader, "\\.." );
  1465. $srcdirBackslash = join( "\\", $srcdirBackslash, ".." );
  1466. }
  1467. $srcdirForwardslash = $srcdirBackslash;
  1468. $srcdirForwardslash =~ s/\\/\//g;
  1469. push( @fileheader, "\"\n" );
  1470. # Process the file one line at a time
  1471. my $folderOpenBrace = 0;
  1472. for( $lineCt = 0; $lineCt < @lines; ++$lineCt )
  1473. {
  1474. my($line) = @lines[$lineCt];
  1475. if ( !$nameFound && $line =~ ( /Name="([^"]+)"/ ) )
  1476. {
  1477. $projectName = $1;
  1478. # Print the project name
  1479. my $capName = $projectName;
  1480. $capName =~ s/\b(\w)/\U$1/g;
  1481. @lineToPrint = ( "\$Project \"", $capName, "\"\n\{\n" );
  1482. for ( @configurations )
  1483. {
  1484. push( @{ $outputs{$_} }, @lineToPrint );
  1485. }
  1486. $nameFound = 1;
  1487. $folderOpenBrace = 1;
  1488. # Clean up the directory
  1489. # for ( @configurations )
  1490. # {
  1491. # # delete the existing files
  1492. # my($filename) = join('_', $vcprojname, $configurationNames{$_} );
  1493. # if( $outputPath )
  1494. # {
  1495. # $filename = join('/', $outputPath, $filename );
  1496. # $filename =~ s/\//\\/g;
  1497. # }
  1498. # system( "del /Q $filename.vpc" );
  1499. # }
  1500. }
  1501. if ( $line =~ /^\s*\<Configuration$/ )
  1502. {
  1503. # Start of a new configuration
  1504. # Get the configuration name and then process the configuration
  1505. my($configLine) = @lines[++$lineCt];
  1506. set_current_configuration( $configLine );
  1507. $configLine =~ ( /Name="([\w\s]*)\|/ );
  1508. my($configName) = ( $1 =~ /(Debug|Release)/ );
  1509. $currentConfig = join( '_', $currentConfig, $configName );
  1510. push( @{ $configOutput{$currentConfig} }, "\$Configuration\t\"", $configName, "\"\n" );
  1511. push( @{ $configOutput{$currentConfig} }, "\{\n" );
  1512. processConfiguration( @lines );
  1513. # end if this configuration
  1514. push( @{ $configOutput{$currentConfig} }, "\}\n\n" );
  1515. }
  1516. elsif ( $line =~ /^\s*\<Files\>$/ )
  1517. {
  1518. # end of configurations section - write out the files
  1519. # first, finish filling in the header info
  1520. my($configtype) = $baseConfigurationTypes{$baseConfiguration};
  1521. if ( $configtype =~ /lib/ )
  1522. {
  1523. push( @fileheader, "\$Macro OUTLIBDIR\t\"\$SRCDIR\\lib\\XXXX\"\n" );
  1524. }
  1525. else
  1526. {
  1527. push( @fileheader, "\$Macro OUTBINDIR\t\"\$SRCDIR\\..\\game\\bin\"\n" );
  1528. }
  1529. push( @fileheader, "\n" );
  1530. push( @fileheader, "\$Include \"\$SRCDIR\\vpc_scripts\\source_" );
  1531. push( @fileheader, $configtype );
  1532. if ( $configtype =~ /exe/ )
  1533. {
  1534. push( @fileheader, "_", $configurationSubsystem );
  1535. }
  1536. push( @fileheader, "_win32_base.vpc\"\n" );
  1537. # push( @fileheader, "_win32_base.vpc\"\t\[\$WIN32\|\|\$LINUX\]\n" );
  1538. # push( @fileheader, "\$Include \"\$SRCDIR\\vpc_scripts\\source_" );
  1539. # push( @fileheader, $configtype );
  1540. # push( @fileheader, "_x360_base.vpc\"\t\t\[\$X360\]\n" );
  1541. push( @fileheader, "\n" );
  1542. for ( @configurations )
  1543. {
  1544. my $joinedname = join( '_', $_, "Debug" );
  1545. # print the configs
  1546. if ( @{ $configOutput{$joinedname} } > 0 )
  1547. {
  1548. my($filename) = join('_', $vcprojname, $configurationNames{$_} );
  1549. if( $outputPath )
  1550. {
  1551. $filename = join('/', $outputPath, $filename );
  1552. }
  1553. open ( OUTFILE, ">$filename.vpc" );
  1554. print OUTFILE @fileheader;
  1555. print OUTFILE @{ $configOutput{$joinedname} };
  1556. $joinedname = join( '_', $_, "Release" );
  1557. print OUTFILE @{ $configOutput{$joinedname} };
  1558. close ( OUTFILE );
  1559. }
  1560. }
  1561. $parsingFiles = 1;
  1562. }
  1563. elsif ( $line =~ /^\s*\<Filter$/ )
  1564. {
  1565. # Start of a new folder
  1566. if ( $spaceBeforeFolder == 1 )
  1567. {
  1568. $spaceBeforeFolder = 0;
  1569. for ( @configurations )
  1570. {
  1571. push( @{ $outputs{$_} }, "\n" );
  1572. }
  1573. }
  1574. processFolder( @lines );
  1575. }
  1576. elsif ( $line =~ /^\s*\<File$/ )
  1577. {
  1578. # Start of a new file
  1579. if ( $spaceBeforeFolder == 1 )
  1580. {
  1581. $spaceBeforeFolder = 0;
  1582. for ( @configurations )
  1583. {
  1584. push( @{ $outputs{$_} }, "\n" );
  1585. }
  1586. }
  1587. processFile( @lines );
  1588. }
  1589. }
  1590. my $projectCt = 0;
  1591. for ( @configurations )
  1592. {
  1593. push( @{ $outputs{$_} }, "\}\n" );
  1594. if ( $filesAdded{$_} )
  1595. {
  1596. ++$projectCt;
  1597. # print the files
  1598. my($filename) = join('_', $vcprojname, $configurationNames{$_} );
  1599. if( $outputPath )
  1600. {
  1601. $filename = join('/', $outputPath, $filename );
  1602. }
  1603. open ( OUTFILE, ">>$filename.vpc" );
  1604. print OUTFILE @{ $outputs{$_} };
  1605. close ( OUTFILE );
  1606. }
  1607. }
  1608. if ( $projectCt == 1 )
  1609. {
  1610. my $oldname = join('_', $vcprojname, "base.vpc" );
  1611. my $newname = join('', $vcprojname, ".vpc" );
  1612. if( $outputPath )
  1613. {
  1614. $oldname = join('/', $outputPath, $oldname );
  1615. $newname = join('/', $outputPath, $newname );
  1616. }
  1617. rename $oldname, $newname;
  1618. }