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.

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