PageRenderTime 25ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/src/devtools/bin/valve_perl_helpers.pl

https://github.com/SwissCheeseKnife/Protocol-7
Perl | 543 lines | 440 code | 51 blank | 52 comment | 59 complexity | 778e56c66a98d97f588d3a9e4603afd4 MD5 | raw file
  1. sub BackToForwardSlash
  2. {
  3. my( $path ) = shift;
  4. $path =~ s,\\,/,g;
  5. return $path;
  6. }
  7. sub RemoveFileName
  8. {
  9. my( $in ) = shift;
  10. $in = &BackToForwardSlash( $in );
  11. $in =~ s,/[^/]*$,,;
  12. return $in;
  13. }
  14. sub RemovePath
  15. {
  16. my( $in ) = shift;
  17. $in = &BackToForwardSlash( $in );
  18. $in =~ s,^(.*)/([^/]*)$,$2,;
  19. return $in;
  20. }
  21. sub MakeDirHier
  22. {
  23. my( $in ) = shift;
  24. # print "MakeDirHier( $in )\n";
  25. $in = &BackToForwardSlash( $in );
  26. my( @path );
  27. while( $in =~ m,/, ) # while $in still has a slash
  28. {
  29. my( $end ) = &RemovePath( $in );
  30. push @path, $end;
  31. # print $in . "\n";
  32. $in = &RemoveFileName( $in );
  33. }
  34. my( $i );
  35. my( $numelems ) = scalar( @path );
  36. my( $curpath );
  37. for( $i = $numelems - 1; $i >= 0; $i-- )
  38. {
  39. $curpath .= "/" . $path[$i];
  40. my( $dir ) = $in . $curpath;
  41. if( !stat $dir )
  42. {
  43. # print "mkdir $dir\n";
  44. mkdir $dir, 0777;
  45. }
  46. }
  47. }
  48. sub FileExists
  49. {
  50. my $filename = shift;
  51. my @statresult = stat $filename;
  52. my $iswritable = @statresult != 0;
  53. return $iswritable;
  54. }
  55. sub MakeFileWritable
  56. {
  57. my $filename = shift;
  58. if ( &FileExists( $filename ) )
  59. {
  60. chmod 0666, $filename || die;
  61. }
  62. }
  63. sub MakeFileReadOnly
  64. {
  65. my $filename = shift;
  66. chmod 0444, $filename || die;
  67. }
  68. # Run a command and get stdout and stderr to an array
  69. sub RunCommand
  70. {
  71. my $cmd = shift;
  72. # print STDERR "command: $cmd\n";
  73. system "$cmd > cmdout.txt 2>&1" || die;
  74. local( *FILE );
  75. open FILE, "<cmdout.txt" || die;
  76. my @output = <FILE>;
  77. # print STDERR "command output: @output\n";
  78. close FILE;
  79. unlink "cmdout.txt" || die;
  80. return @output;
  81. }
  82. sub PerforceEditOrAdd
  83. {
  84. return;
  85. my $filename = shift;
  86. my $changelistarg = shift;
  87. # Is the file on the client?
  88. my $cmd = "p4 fstat \"$filename\"";
  89. my @p4output = &RunCommand( $cmd );
  90. my $p4output = join "", @p4output;
  91. if( $p4output =~ m/no such file/ )
  92. {
  93. # not on client. . add
  94. my $cmd = "p4 add $changelistarg $filename";
  95. my @p4output = &RunCommand( $cmd );
  96. my $p4output = join "", @p4output;
  97. if( $p4output =~ m/opened for add/ )
  98. {
  99. print $p4output;
  100. return;
  101. }
  102. print "ERROR: $p4output";
  103. return;
  104. }
  105. # The file is known to be on the client at this point.
  106. # Is it open for edit?
  107. if( $p4output =~ m/action edit/ )
  108. {
  109. # Is is open for edit, let's see if it's still different.
  110. # check for opened files that are not different from the revision in the depot.
  111. my $cmd = "p4 diff -sr \"$filename\"";
  112. my @p4output = &RunCommand( $cmd );
  113. my $outputstring = join "", @p4output;
  114. # check for empty string
  115. if( !( $outputstring =~ m/^\s*$/ ) )
  116. {
  117. my $cmd = "p4 revert \"$filename\"";
  118. my @p4output = &RunCommand( $cmd );
  119. my $outputstring = join "", @p4output;
  120. print $outputstring;
  121. return;
  122. }
  123. }
  124. # check for unopened files that are different from the revision in the depot.
  125. my $cmd = "p4 diff -se \"$filename\"";
  126. my @p4output = &RunCommand( $cmd );
  127. my $outputstring = join "", @p4output;
  128. # check for empty string
  129. if( $outputstring =~ m/^\s*$/ )
  130. {
  131. &MakeFileReadOnly( $filename );
  132. return;
  133. }
  134. # We need to edit the file since it is known to be different here.
  135. my $cmd = "p4 edit $changelistarg \"$filename\"";
  136. my @p4output = &RunCommand( $cmd );
  137. my $line;
  138. foreach $line ( @p4output )
  139. {
  140. if( $line =~ m/not on client/ )
  141. {
  142. #print "notonclient...";
  143. print "ERROR: @p4output\n";
  144. return;
  145. }
  146. if( $line =~ m/currently opened for edit/ )
  147. {
  148. return;
  149. }
  150. if( $line =~ m/opened for edit/ )
  151. {
  152. print $line;
  153. }
  154. }
  155. }
  156. sub FileIsWritable
  157. {
  158. local( $filename ) = shift;
  159. local( @statresult ) = stat $filename;
  160. local( $mode, $iswritable );
  161. $mode = oct( $statresult[2] );
  162. $iswritable = ( $mode & 2 ) != 0;
  163. return $iswritable;
  164. }
  165. sub TouchFile
  166. {
  167. my $filename = shift;
  168. if( !&FileExists( $filename ) )
  169. {
  170. if( !open FILE, ">$filename" )
  171. {
  172. die;
  173. }
  174. close FILE;
  175. }
  176. my $now = time;
  177. local( *FILE );
  178. utime $now, $now, $filename;
  179. }
  180. sub FileExistsInPerforce
  181. {
  182. my $filename = shift;
  183. my @output = &RunCommand( "p4 fstat $filename" );
  184. my $line;
  185. foreach $line (@output)
  186. {
  187. if( $line =~ m/no such file/ )
  188. {
  189. return 0;
  190. }
  191. }
  192. return 1;
  193. }
  194. sub PerforceWriteFile
  195. {
  196. my $filename = shift;
  197. my $filecontents = shift;
  198. # Make the target vcs writable if it exists
  199. MakeFileWritable( $filename );
  200. # Write the file.
  201. local( *FP );
  202. open FP, ">$filename";
  203. print FP $filecontents;
  204. close FP;
  205. }
  206. sub WriteFile
  207. {
  208. my $filename = shift;
  209. my $filecontents = shift;
  210. # Make the target vcs writable if it exists
  211. MakeFileWritable( $filename );
  212. # Write the file.
  213. local( *FP );
  214. open FP, ">$filename";
  215. print FP $filecontents;
  216. close FP;
  217. }
  218. sub PrintCleanPerforceOutput
  219. {
  220. my $line;
  221. while( $line = shift )
  222. {
  223. if( $line =~ m/currently opened/i )
  224. {
  225. next;
  226. }
  227. if( $line =~ m/already opened for edit/i )
  228. {
  229. next;
  230. }
  231. if( $line =~ m/also opened/i )
  232. {
  233. next;
  234. }
  235. if( $line =~ m/add of existing file/i )
  236. {
  237. next;
  238. }
  239. print $line;
  240. }
  241. }
  242. # HACK!!!! Need to pass something in to do this rather than hard coding.
  243. sub NormalizePerforceFilename
  244. {
  245. my $line = shift;
  246. # remove newlines.
  247. $line =~ s/\n//;
  248. # downcase.
  249. $line =~ tr/[A-Z]/[a-z]/;
  250. # backslash to forwardslash
  251. $line =~ s,\\,/,g;
  252. # for inc files HACK!
  253. $line =~ s/^.*(fxctmp9.*)/$1/i;
  254. $line =~ s/^.*(vshtmp9.*)/$1/i;
  255. # for vcs files. HACK!
  256. $line =~ s,^.*game/hl2/shaders/,,i;
  257. return $line;
  258. }
  259. sub MakeSureFileExists
  260. {
  261. local( $filename ) = shift;
  262. local( $testexists ) = shift;
  263. local( $testwrite ) = shift;
  264. local( @statresult ) = stat $filename;
  265. if( !@statresult && $testexists )
  266. {
  267. die "$filename doesn't exist!\n";
  268. }
  269. local( $mode, $iswritable );
  270. $mode = oct( $statresult[2] );
  271. $iswritable = ( $mode & 2 ) != 0;
  272. if( !$iswritable && $testwrite )
  273. {
  274. die "$filename isn't writable!\n";
  275. }
  276. }
  277. sub LoadShaderListFile_GetShaderType
  278. {
  279. my $shadername = shift;
  280. my $shadertype;
  281. if( $shadername =~ m/\.vsh/i )
  282. {
  283. $shadertype = "vsh";
  284. }
  285. elsif( $shadername =~ m/\.psh/i )
  286. {
  287. $shadertype = "psh";
  288. }
  289. elsif( $shadername =~ m/\.fxc/i )
  290. {
  291. $shadertype = "fxc";
  292. }
  293. else
  294. {
  295. die;
  296. }
  297. return $shadertype;
  298. }
  299. sub LoadShaderListFile_GetShaderSrc
  300. {
  301. my $shadername = shift;
  302. if ( $shadername =~ m/^(.*)-----/i )
  303. {
  304. return $1;
  305. }
  306. else
  307. {
  308. return $shadername;
  309. }
  310. }
  311. sub LoadShaderListFile_GetShaderBase
  312. {
  313. my $shadername = shift;
  314. if ( $shadername =~ m/-----(.*)$/i )
  315. {
  316. return $1;
  317. }
  318. else
  319. {
  320. my $shadertype = &LoadShaderListFile_GetShaderType( $shadername );
  321. $shadername =~ s/\.$shadertype//i;
  322. return $shadername;
  323. }
  324. }
  325. sub LoadShaderListFile
  326. {
  327. my $inputbase = shift;
  328. my @srcfiles;
  329. &MakeSureFileExists( "$inputbase.txt", 1, 0 );
  330. open SHADERLISTFILE, "<$inputbase.txt" || die;
  331. my $line;
  332. while( $line = <SHADERLISTFILE> )
  333. {
  334. $line =~ s/\/\/.*$//; # remove comments "//..."
  335. $line =~ s/^\s*//; # trim leading whitespace
  336. $line =~ s/\s*$//; # trim trailing whitespace
  337. next if( $line =~ m/^\s*$/ );
  338. if( $line =~ m/\.fxc/ || $line =~ m/\.vsh/ || $line =~ m/\.psh/ )
  339. {
  340. my $shaderbase = &LoadShaderListFile_GetShaderBase( $line );
  341. if( $ENV{"DIRECTX_FORCE_MODEL"} =~ m/^30$/i ) # forcing all shaders to be ver. 30
  342. {
  343. my $targetbase = $shaderbase;
  344. $targetbase =~ s/_ps2x/_ps30/i;
  345. $targetbase =~ s/_ps20b/_ps30/i;
  346. $targetbase =~ s/_ps20/_ps30/i;
  347. $targetbase =~ s/_vs20/_vs30/i;
  348. $targetbase =~ s/_vsxx/_vs30/i;
  349. push @srcfiles, ( $line . "-----" . $targetbase );
  350. }
  351. else
  352. {
  353. if( $shaderbase =~ m/_ps2x/i )
  354. {
  355. my $targetbase = $shaderbase;
  356. $targetbase =~ s/_ps2x/_ps20/i;
  357. push @srcfiles, ( $line . "-----" . $targetbase );
  358. $targetbase = $shaderbase;
  359. $targetbase =~ s/_ps2x/_ps20b/i;
  360. push @srcfiles, ( $line . "-----" . $targetbase );
  361. }
  362. elsif( $shaderbase =~ m/_vsxx/i )
  363. {
  364. my $targetbase = $shaderbase;
  365. $targetbase =~ s/_vsxx/_vs11/i;
  366. push @srcfiles, ( $line . "-----" . $targetbase );
  367. $targetbase = $shaderbase;
  368. $targetbase =~ s/_vsxx/_vs20/i;
  369. push @srcfiles, ( $line . "-----" . $targetbase );
  370. }
  371. else
  372. {
  373. push @srcfiles, ( $line . "-----" . $shaderbase );
  374. }
  375. }
  376. }
  377. }
  378. close SHADERLISTFILE;
  379. return @srcfiles;
  380. }
  381. sub ReadInputFileWithIncludes
  382. {
  383. local( $filename ) = shift;
  384. # print STDERR "ReadInputFileWithIncludes: $filename\n";
  385. local( *INPUT );
  386. local( $output );
  387. # print STDERR "before open\n";
  388. open INPUT, "<$filename" || die;
  389. # print STDERR "after open\n";
  390. local( $line );
  391. while( $line = <INPUT> )
  392. {
  393. # print STDERR $line;
  394. if( $line =~ m/\#include\s+\"(.*)\"/i )
  395. {
  396. $output.= ReadInputFileWithIncludes( $1 );
  397. }
  398. else
  399. {
  400. $output .= $line;
  401. }
  402. }
  403. close INPUT;
  404. return $output;
  405. }
  406. sub GetCRCFromSourceFile
  407. {
  408. my $filename = shift;
  409. my $data = &ReadInputFileWithIncludes( $filename );
  410. # print STDERR $data;
  411. $crc = crc32( $data );
  412. # print STDERR "GetCRCFromSourceFile: $crc\n";
  413. return $crc;
  414. }
  415. sub GetCRCFromVCSFile
  416. {
  417. my $filename = shift;
  418. # print STDERR "GetCRCFromVCSFile $filename\n";
  419. local( *FP );
  420. open FP, "<$filename" || die "GetCRCFromVCSFile: can't open file $filename\n";
  421. binmode( FP );
  422. # unpack arguments
  423. my $sInt = "i";
  424. my $uInt = "I";
  425. if( $filename =~ m/\.360\./ )
  426. {
  427. # Change arguments to "big endian long"
  428. $sInt = "N";
  429. $uInt = "N";
  430. }
  431. my $header;
  432. read FP, $header, 7 * 4 || die "updateshaders.pl:GetCRCFromVCSFile: can't read header for $filename\n";
  433. my $version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc;
  434. ($version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc) = unpack "$sInt$sInt$sInt$uInt$uInt$uInt$uInt", $header;
  435. unless( $version == 4 || $version == 5 || $version == 6 )
  436. {
  437. print STDERR "ERROR: GetCRCFromVCSFile: $filename is version $version\n";
  438. return 0;
  439. }
  440. # print STDERR "version: $version\n";
  441. # print STDERR "numCombos: $numCombos\n";
  442. # print STDERR "numDynamicCombos: $numDynamicCombos\n";
  443. # print STDERR "flags: $flags\n";
  444. # print STDERR "centroidMask: $centroidMask\n";
  445. # print STDERR "refSize: $refSize\n";
  446. # print STDERR "GetCRCFromVCSFile: $crc\n";
  447. close( FP );
  448. return $crc;
  449. }
  450. sub CheckCRCAgainstTarget
  451. {
  452. my $srcFileName = shift;
  453. my $vcsFileName = shift;
  454. my $warn = shift;
  455. # Make sure both files exist.
  456. # print STDERR "$srcFileName doesn't exist\n" if( !( -e $srcFileName ) );
  457. # print STDERR "$vcsFileName doesn't exist\n" if( !( -e $vcsFileName ) );
  458. if( !( -e $srcFileName ) )
  459. {
  460. if( $warn )
  461. {
  462. print "$srcFileName missing\n";
  463. }
  464. return 0;
  465. }
  466. if( !( -e $vcsFileName ) )
  467. {
  468. if( $warn )
  469. {
  470. print "$vcsFileName missing\n";
  471. }
  472. return 0;
  473. }
  474. # print STDERR "CheckCRCAgainstTarget( $srcFileName, $vcsFileName );\n";
  475. # print STDERR "vcsFileName: $vcsFileName\n";
  476. # print STDERR "vcsFileName: $srcFileName\n";
  477. my $vcsCRC = &GetCRCFromVCSFile( $vcsFileName );
  478. my $srcCRC = &GetCRCFromSourceFile( $srcFileName );
  479. if( $warn && ( $vcsCRC != $srcCRC ) )
  480. {
  481. print "$vcsFileName checksum ($vcsCRC) != $srcFileName checksum: ($srcCRC)\n";
  482. }
  483. # return 0; # use this to skip crc checking.
  484. # if( $vcsCRC == $srcCRC )
  485. # {
  486. # print STDERR "CRC passed for $srcFileName $vcsFileName $vcsCRC\n";
  487. # }
  488. return $vcsCRC == $srcCRC;
  489. }
  490. 1;