Leaked source code of windows server 2003
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.

1276 lines
36 KiB

  1. # __________________________________________________________________________________
  2. #
  3. # Purpose:
  4. # PERL Module to handle common tasks for PERL SLM wrapper scripts
  5. #
  6. # Parameters:
  7. # Specific to subroutine
  8. #
  9. # Output:
  10. # Specific to subroutine
  11. #
  12. # __________________________________________________________________________________
  13. #
  14. # Some Global Definitions
  15. #
  16. $TRUE = 1;
  17. $FALSE = 0;
  18. $Callee = "";
  19. $SourceControlClient = "sd";
  20. package SlmSubs;
  21. sub ParseArgs
  22. # __________________________________________________________________________________
  23. #
  24. # Parses command line arguments to verify the right syntax is being used
  25. #
  26. # Parameters:
  27. # Command Line Arguments
  28. #
  29. # Output:
  30. # Errors if the wrong syntax is used otherwise sets the appropriate variables
  31. # based on the command line arguments
  32. #
  33. # __________________________________________________________________________________
  34. {
  35. #
  36. # Initialize global flags to global value of $FALSE
  37. #
  38. $main::CrossBranches = $main::FALSE;
  39. $main::AllFiles = $main::FALSE;
  40. $main::FileVersion = $main::FALSE;
  41. $main::Force = $main::FALSE;
  42. $main::Ghost = $main::FALSE;
  43. $main::Ignore = $main::FALSE;
  44. $main::InvalidFlag = $main::FALSE;
  45. $main::Library = $main::FALSE;
  46. $main::NoArgumentsGiven = $main::FALSE;
  47. $main::NoHeaders = $main::FALSE;
  48. $main::OutOfDateFiles = $main::FALSE;
  49. $main::OutlineView = $main::FALSE;
  50. $main::NetSend = $main::FALSE;
  51. $main::PerverseComparison = $main::FALSE;
  52. $main::Recursive = $main::FALSE;
  53. $main::Reverse = $main::FALSE;
  54. $main::SaveList = $main::FALSE;
  55. $main::SaveListDifferent = $main::FALSE;
  56. $main::SaveListExit = $main::FALSE;
  57. $main::SaveListLeft = $main::FALSE;
  58. $main::SaveListRight = $main::FALSE;
  59. $main::SaveListSame = $main::FALSE;
  60. $main::UnGhost = $main::FALSE;
  61. $main::Usage = $main::FALSE;
  62. $main::Verbose = $main::FALSE;
  63. $main::WindiffRecursive = $main::FALSE;
  64. #
  65. # Initialize local flags to global value of $FALSE
  66. #
  67. $DeletedDirectories = $main::FALSE;
  68. $ProjectPath = $main::FALSE;
  69. #
  70. # Initialize variables to null
  71. #
  72. $main::AllFilesSymbol = "";
  73. $main::Comment = "";
  74. $main::Cwd = "";
  75. $main::ErrorMessage = "";
  76. $main::ExtraSsyncFlags = "";
  77. $main::NetSendTarget = "";
  78. $main::Number = "";
  79. $main::ProjectPathName = "";
  80. $main::SaveListName = "";
  81. $main::ServerPortName = "";
  82. @main::CurrentClientList = ();
  83. @main::DirList = ();
  84. @main::FileList = ();
  85. @main::LocalDirs = ();
  86. @main::OriginalFileList = ();
  87. #
  88. # Initialize local flag to global value of $FALSE
  89. #
  90. $CommentArg = $main::FALSE;
  91. #
  92. # Initialize local counter
  93. #
  94. $ArgCounter = 0;
  95. #
  96. # Find current working directory by calling 'cd' in the command shell.
  97. #
  98. open(CWD, 'cd 2>&1|');
  99. #
  100. # Just get the first line
  101. #
  102. $main::Cwd = <CWD>;
  103. close(CWD);
  104. #
  105. # Chop \n off of $Cwd
  106. #
  107. chop $main::Cwd;
  108. #
  109. # Find out how the depot maps to the local machine by calling Perforce's where command
  110. #
  111. open(WHERE, qq/$main::SourceControlClient where "*" 2>&1|/);
  112. #
  113. # Just get the first line
  114. #
  115. @WhereList = <WHERE>;
  116. close(WHERE);
  117. @ReversedWhereList = reverse @WhereList;
  118. #
  119. # Get the first line from the bottom that matches the current directory, skipping lines
  120. # that start with '-'
  121. #
  122. $WhereLine = <WHERE>;
  123. foreach $ReversedWhereLine (@ReversedWhereList)
  124. {
  125. if ($ReversedWhereLine =~ /^-/)
  126. {
  127. next;
  128. }
  129. if ($ReversedWhereLine =~ /\Q$main::Cwd\E\\\%1/i)
  130. {
  131. $WhereLine = $ReversedWhereLine;
  132. last;
  133. }
  134. }
  135. #
  136. # There are basically two parts of the line that are interesting. The first one is
  137. # the depot location that maps to where we currently are. The second is the local
  138. # directory in Perforce agreeable syntax.
  139. #
  140. if ($WhereLine =~ /([^\%1]*)\%1\s*([^\%1]*)\/\%1.*/)
  141. {
  142. $main::DepotMap = $1;
  143. $main::LocalMap = $2;
  144. }
  145. #
  146. # Sometimes $main::SourceControlClient where does not return a line with %1 on it. Account for this case.
  147. #
  148. else
  149. {
  150. $WhereLine =~ /(\/\/.*\/)[^\/]*\s*(\/\/.*)\/[^\\]*\s*.*/;
  151. $main::DepotMap = $1;
  152. $main::LocalMap = $2;
  153. }
  154. #
  155. # Cycle through parameters
  156. #
  157. ParameterLoop: while ($_[$ArgCounter])
  158. {
  159. #
  160. # if -c flag on last parameter, set $Comment equal to this parameter
  161. # Clear $CommentArg flag when done
  162. #
  163. if ($CommentArg)
  164. {
  165. $main::Comment = $_[$ArgCounter];
  166. $CommentArg = $main::FALSE;
  167. $ArgCounter++;
  168. next ParameterLoop;
  169. }
  170. #
  171. # if -p flag on last parameter, set $main::ProjectPathName equal to this parameter
  172. # Clear $ProjectPath flag when done
  173. #
  174. if ($ProjectPath)
  175. {
  176. $main::ProjectPathName = $_[$ArgCounter];
  177. $ProjectPath = $main::FALSE;
  178. $ArgCounter++;
  179. next ParameterLoop;
  180. }
  181. #
  182. # if -n flag on last parameter, set $NetSendTarget equal to this parameter
  183. # Clear $NetSend flag when done
  184. #
  185. if ($main::NetSend)
  186. {
  187. $main::NetSendTarget = $_[$ArgCounter];
  188. $main::NetSend = $main::FALSE;
  189. $ArgCounter++;
  190. next ParameterLoop;
  191. }
  192. #
  193. # if -s flag on last parameter, set $main::SaveListName equal to this parameter
  194. # Also set $main::ServerPortName to this parameter. Clear $main::SaveList flag when done
  195. #
  196. if ($main::SaveList)
  197. {
  198. $main::SaveListName = $_[$ArgCounter];
  199. $main::ServerPortName = $_[$ArgCounter];
  200. $main::SaveList = $main::FALSE;
  201. $ArgCounter++;
  202. next ParameterLoop;
  203. }
  204. #
  205. # If '-' is the first character in the parameter then this is a flag
  206. #
  207. if (($_[$ArgCounter] =~ /^-/) or ($_[$ArgCounter] =~ /^\//))
  208. {
  209. $ArgPosition = 0;
  210. CASE: while ($SubArg = substr $_[$ArgCounter], ++$ArgPosition)
  211. {
  212. #
  213. # -! equals add '-f' to $ExtraSsyncFlags
  214. #
  215. if ($SubArg =~ /^!/i)
  216. {
  217. $main::ExtraSsyncFlags = "-f";
  218. next CASE;
  219. }
  220. #
  221. # -b equals $CrossBranches
  222. #
  223. if ($SubArg =~ /^b/i)
  224. {
  225. $main::CrossBranches = $main::TRUE;
  226. next CASE;
  227. }
  228. #
  229. # -x equals $AllFiles
  230. #
  231. if ($SubArg =~ /^x/i)
  232. {
  233. $main::AllFiles = $main::TRUE;
  234. next CASE;
  235. }
  236. #
  237. # If 'c' is the next character of the flag then the next parameter is a comment
  238. #
  239. if ($SubArg =~ /^c$/i)
  240. {
  241. $CommentArg = $main::TRUE;
  242. next CASE;
  243. }
  244. #
  245. # -d equals $DeletedDirectories
  246. #
  247. if ($SubArg =~ /^d$/i)
  248. {
  249. $DeletedDirectories = $main::TRUE;
  250. next CASE;
  251. }
  252. #
  253. # -f is valid slm syntax but unecessary in Perforce
  254. #
  255. if ($SubArg =~ /^f/i)
  256. {
  257. $main::Force = $main::TRUE;
  258. next CASE;
  259. }
  260. #
  261. # -g equals $Ghost
  262. #
  263. if ($SubArg =~ /^g/i)
  264. {
  265. $main::Ghost = $main::TRUE;
  266. next CASE;
  267. #
  268. # Set Thorough so that we use a more thorough albeit slower dirs command
  269. #
  270. $Thorough = $TRUE;
  271. }
  272. #
  273. # -i equals $Ignore
  274. #
  275. if ($SubArg =~ /^i/i)
  276. {
  277. $main::Ignore = $main::TRUE;
  278. next CASE;
  279. }
  280. #
  281. # -l equals $Library for windiff
  282. #
  283. if ($SubArg =~ /^l/i)
  284. {
  285. $main::Library = $main::TRUE;
  286. next CASE;
  287. }
  288. #
  289. # -z equals $NoHeaders (implies $Verbose)
  290. #
  291. if ($SubArg =~ /^z/i)
  292. {
  293. $main::NoHeaders = $main::TRUE;
  294. $main::Verbose = $main::TRUE;
  295. next CASE;
  296. }
  297. #
  298. # -n equals $NetSend
  299. #
  300. if ($SubArg =~ /^n/i)
  301. {
  302. $main::NetSend = $main::TRUE;
  303. next CASE;
  304. }
  305. #
  306. # -o equals $OutOfDateFiles
  307. #
  308. if ($SubArg =~ /^o/i)
  309. {
  310. $main::OutOfDateFiles = $main::TRUE;
  311. $main::OutlineView = $main::TRUE;
  312. next CASE;
  313. }
  314. #
  315. # -p equals $PerverseComparison and $ProjectPath
  316. #
  317. if ($SubArg =~ /^p/i)
  318. {
  319. $main::PerverseComparison = $main::TRUE;
  320. $ProjectPath = $main::TRUE;
  321. next CASE;
  322. }
  323. #
  324. # -r equals $Recursive
  325. #
  326. if (($SubArg =~ /^r/i))
  327. {
  328. if ($main::Callee eq "windiff.pl")
  329. {
  330. $main::Reverse = $main::TRUE;
  331. }
  332. else
  333. {
  334. $main::Recursive = $main::TRUE;
  335. }
  336. next CASE;
  337. }
  338. #
  339. # -s equals $main::SaveList
  340. #
  341. if ($SubArg =~ /^s/i)
  342. {
  343. $SaveArgPosition = $ArgPosition;
  344. SAVELISTCASE: while ($SaveSubArg = substr $_[$ArgCounter], ++$SaveArgPosition)
  345. {
  346. #
  347. # -d equals $main::SaveListDifferent
  348. #
  349. if ($SaveSubArg =~ /^d/i)
  350. {
  351. $main::SaveListDifferent = $main::TRUE;
  352. next SAVELISTCASE;
  353. }
  354. #
  355. # -x equals $main::SaveListExit
  356. #
  357. if ($SaveSubArg =~ /^x/i)
  358. {
  359. $main::SaveListExit = $main::TRUE;
  360. next SAVELISTCASE;
  361. }
  362. #
  363. # -l equals $main::SaveListLeft
  364. #
  365. if ($SaveSubArg =~ /^l/i)
  366. {
  367. $main::SaveListLeft = $main::TRUE;
  368. next SAVELISTCASE;
  369. }
  370. #
  371. # -r equals $main::SaveListRight
  372. #
  373. if ($SaveSubArg =~ /^r/i)
  374. {
  375. $main::SaveListRight = $main::TRUE;
  376. next SAVELISTCASE;
  377. }
  378. #
  379. # -s equals $main::SaveListSame
  380. #
  381. if ($SaveSubArg =~ /^s/i)
  382. {
  383. $main::SaveListSame = $main::TRUE;
  384. next SAVELISTCASE;
  385. }
  386. #
  387. # Default: Set invalid flag flag
  388. #
  389. $main::InvalidFlag = $main::TRUE;
  390. print "\n";
  391. print 'Error: Invalid Flag "' . substr ($SaveSubArg, 0, 1) . qq/"\n/;
  392. print "\n";
  393. last CASE;
  394. }
  395. $ArgPosition = $SaveArgPosition - 1;
  396. $main::SaveList = $main::TRUE;
  397. next CASE;
  398. }
  399. #
  400. # -t equals $WindiffRecursive
  401. #
  402. if (($SubArg =~ /^t/i))
  403. {
  404. $main::WindiffRecursive = $main::TRUE;
  405. next CASE;
  406. }
  407. #
  408. # -u equals $UnGhost
  409. #
  410. if ($SubArg =~ /^u/i)
  411. {
  412. $main::UnGhost = $main::TRUE;
  413. next CASE;
  414. #
  415. # Set Thorough so that we use a more thorough albeit slower dirs command
  416. #
  417. $Thorough = $TRUE;
  418. }
  419. #
  420. # -v equals $Verbose
  421. #
  422. if ($SubArg =~ /^v/i)
  423. {
  424. $main::Verbose = $main::TRUE;
  425. next CASE;
  426. }
  427. #
  428. # -h or -? equals $Usage
  429. #
  430. if (($SubArg =~ /^h/i) or ($SubArg =~ /^\?/))
  431. {
  432. $main::Usage = $main::TRUE;
  433. last CASE;
  434. }
  435. #
  436. # if there are numbers in the flag set $Number equal to them
  437. #
  438. if ($SubArg =~ /([0-9]+)/i)
  439. {
  440. $main::Number = "$main::Number$1";
  441. next CASE;
  442. }
  443. #
  444. # Default: Set invalid flag flag
  445. #
  446. $main::InvalidFlag = $main::TRUE;
  447. print "\n";
  448. print 'Error: Invalid Flag "' . substr ($SubArg, 0, 1) . qq/"\n/;
  449. print "\n";
  450. last CASE;
  451. }
  452. }
  453. else
  454. {
  455. if ($_[$ArgCounter] eq "*.*")
  456. {
  457. $_[$ArgCounter] = "*";
  458. }
  459. push @main::OriginalFileList, $_[$ArgCounter];
  460. if ((!$main::FileVersion) and ($_[$ArgCounter] =~ /#\d+$/))
  461. {
  462. $main::FileVersion = $main::TRUE;
  463. }
  464. }
  465. $ArgCounter++;
  466. }
  467. if ($main::Recursive and @main::OriginalFileList)
  468. {
  469. if ($Thorough)
  470. {
  471. #
  472. # Get a list of dirs to find out which files in @main::OriginalFileList are really directories
  473. #
  474. open (P4Dirs, "$main::SourceControlClient dirs -D $main::DepotMap\* 2>&1|");
  475. @P4DepotDirsList = <P4Dirs>;
  476. close (P4Dirs);
  477. }
  478. elsif ($DeletedDirectories)
  479. {
  480. #
  481. # Get a list of dirs to find out which files in @main::OriginalFileList are really directories
  482. #
  483. open (P4Dirs, qq/$main::SourceControlClient dirs -D "*" 2>&1|/);
  484. @P4DepotDirsList = <P4Dirs>;
  485. close (P4Dirs);
  486. }
  487. else
  488. {
  489. #
  490. # Get a list of dirs to find out which files in @main::OriginalFileList are really directories
  491. #
  492. opendir CurrentDir, ".";
  493. @P4DepotDirsList = grep !/^\.\.?$/, (grep -d, readdir CurrentDir);
  494. closedir CurrentDir;
  495. @DesiredDirList = ();
  496. foreach $DirEntry (@P4DepotDirsList)
  497. {
  498. push @DesiredDirList, "$main::DepotMap$DirEntry\n";
  499. }
  500. @P4DepotDirsList = @DesiredDirList;
  501. }
  502. #
  503. # Split up @main::OriginalFileList into files and directories
  504. #
  505. @TempFileList = @main::OriginalFileList;
  506. foreach $FileName (@TempFileList)
  507. {
  508. if ($FileName =~ /\*/)
  509. {
  510. push @main::DirList, $FileName;
  511. push @main::FileList, $FileName;
  512. }
  513. else
  514. {
  515. if (grep /\Q$main::DepotMap\E$FileName\n/i, @P4DepotDirsList)
  516. {
  517. push @main::DirList, $FileName;
  518. }
  519. else
  520. {
  521. push @main::FileList, $FileName;
  522. }
  523. }
  524. }
  525. }
  526. else
  527. {
  528. @main::FileList = @main::OriginalFileList;
  529. }
  530. #
  531. # Create RecursiveFileList if -r on the command line
  532. #
  533. if ($main::Recursive)
  534. {
  535. #
  536. # Add .../ to each file in @main::FileList and append it on to the list
  537. #
  538. foreach $FileListEntry (@main::FileList)
  539. {
  540. $TempFileListEntry = ".../$FileListEntry";
  541. push @RecursiveFileList, $TempFileListEntry;
  542. }
  543. push @main::FileList, @RecursiveFileList;
  544. }
  545. #
  546. # Add /... to each dir in @main::DirList
  547. #
  548. foreach $DirListEntry (@main::DirList)
  549. {
  550. $TempDirListEntry = "$DirListEntry/...";
  551. push @RecursiveDirList, $TempDirListEntry;
  552. }
  553. push @main::DirList, @RecursiveDirList;
  554. #
  555. # Add "'s to every entry in @main::DirList and @main::FileList
  556. #
  557. foreach $DirListEntry (@main::DirList)
  558. {
  559. $TempDirListEntry = qq/"$DirListEntry"/;
  560. push @QuotedDirList, $TempDirListEntry;
  561. }
  562. @main::DirList = @QuotedDirList;
  563. foreach $FileListEntry (@main::FileList)
  564. {
  565. $TempFileListEntry = qq/"$FileListEntry"/;
  566. push @QuotedFileList, $TempFileListEntry;
  567. }
  568. @main::FileList = @QuotedFileList;
  569. #
  570. # Set $main::AllFilesSymbol differently for recursive and non-recursive
  571. #
  572. if ($main::Recursive)
  573. {
  574. $main::AllFilesSymbol = '...';
  575. }
  576. else
  577. {
  578. $main::AllFilesSymbol = '"*"';
  579. }
  580. #
  581. # Set Comment to empty if -f used
  582. #
  583. if ($main::Force)
  584. {
  585. if (! $main::Comment)
  586. {
  587. $main::Comment = " ";
  588. }
  589. }
  590. #
  591. # Check if any parameters were given. If not set NoArgumentsGiven flag
  592. #
  593. if ($ArgCounter == 0)
  594. {
  595. $main::NoArgumentsGiven = $main::TRUE;
  596. }
  597. #
  598. # Can't have both a file list and use -o
  599. #
  600. if ( ( (@main::FileList) or (@main::DirList)) and ($main::OutOfDateFiles))
  601. {
  602. $main::Usage = $main::TRUE;
  603. $main::ErrorMessage = "\nError: must specify either files or -o\n\n";
  604. }
  605. }
  606. sub InList
  607. # __________________________________________________________________________________
  608. #
  609. # Finds out if first parameter is in second parameter
  610. #
  611. # Parameters:
  612. # Name, List reference
  613. #
  614. # Output:
  615. # $main::TRUE if first parameter is in second parameter otherwise $main::FALSE
  616. #
  617. # __________________________________________________________________________________
  618. {
  619. $InList = $main::FALSE;
  620. #
  621. # Initialize and counter
  622. #
  623. $ListCounter = 0;
  624. #
  625. # Set $Name to First Parameter
  626. #
  627. $Name = $_[0];
  628. #
  629. # Set @List to Second Parameter
  630. #
  631. @List = @{$_[1]};
  632. #
  633. # See if $Name is in @List
  634. #
  635. SearchLoop: while ($List[$ListCounter])
  636. {
  637. $SearchableListValue = $List[$ListCounter];
  638. #
  639. # Turn *'s and ...'s into .*'s and \'s into /'s
  640. #
  641. $SearchableListValue =~ s/\*/\.\*/g;
  642. $SearchableListValue =~ s/\.\.\./\.\*/g;
  643. $SearchableListValue =~ s/\\/\\\//g;
  644. $SearchableListValue =~ s/"//g;
  645. if ($Name =~ /$SearchableListValue$/i)
  646. {
  647. $InList = $main::TRUE;
  648. last SearchLoop;
  649. }
  650. $ListCounter++;
  651. }
  652. return $InList
  653. }
  654. sub PerforceRequest
  655. # __________________________________________________________________________________
  656. #
  657. # Submits @SubmitList (a list of files and actions) to the Perforce Server
  658. #
  659. # Parameters:
  660. # $PerforceAction, @SubmitList reference
  661. #
  662. # Output:
  663. # Output from the submit process
  664. #
  665. # __________________________________________________________________________________
  666. {
  667. #
  668. # Set @SubmitList to First Parameter
  669. #
  670. @SubmitList = @{$_[1]};
  671. #
  672. # Set $PerfoceAction to Second Parameter
  673. #
  674. $PerforceAction = $_[0];
  675. #
  676. # If no comment given on command line, prompt for one
  677. #
  678. if (! $main::Comment)
  679. {
  680. print "\n@SubmitList";
  681. print "\nEnter description for the previous file list\n";
  682. $main::Comment = <STDIN>;
  683. }
  684. #
  685. # Create description file to pass in to $main::SourceControlClient submit
  686. #
  687. open( TemporaryDescriptionFile, ">$ENV{tmp}\\TmpDescriptionFile");
  688. print TemporaryDescriptionFile "Change:\tnew\n";
  689. print TemporaryDescriptionFile "\n";
  690. print TemporaryDescriptionFile "Description:\n";
  691. print TemporaryDescriptionFile "\t$main::Comment\n";
  692. print TemporaryDescriptionFile "\n";
  693. print TemporaryDescriptionFile "Files:\n";
  694. print TemporaryDescriptionFile @SubmitList;
  695. close (TemporaryDescriptionFile);
  696. #
  697. # Call to perforce to do the $PerforceAction
  698. #
  699. open(PERFORCEOUT, "$main::SourceControlClient $PerforceAction -i < $ENV{tmp}\\TmpDescriptionFile |");
  700. @PerforceOutput = <PERFORCEOUT>;
  701. close (PERFORCEOUT);
  702. #
  703. # Delete temporary file
  704. #
  705. unlink "$ENV{tmp}\\TmpDescriptionFile";
  706. return @PerforceOutput;
  707. }
  708. sub CreateSubmitList
  709. # __________________________________________________________________________________
  710. #
  711. # Adds names from 'opened files' to SubmitList which match the $Action criteria
  712. #
  713. # Parameters:
  714. # Action, @SubmitList reference
  715. #
  716. # Output:
  717. # Files from the '$main::SourceControlClient opened' command which pass the $Action criteria are added
  718. # to @{$SubmitListReference}
  719. #
  720. # __________________________________________________________________________________
  721. {
  722. #
  723. # Set $Action to First Parameter
  724. #
  725. $Action = $_[0];
  726. #
  727. # Set reference of @SubmitList to Second Parameter so that we can change it
  728. #
  729. $SubmitListReference = $_[1];
  730. #
  731. # Get list of opened files
  732. #
  733. open(OPENED, "$main::SourceControlClient opened $main::AllFilesSymbol |");
  734. #
  735. # Create $OpenedList to go into $main::SourceControlClient submit statement
  736. #
  737. while ( $OpenedLine = <OPENED>)
  738. {
  739. $OpenedLine =~ /(\Q$main::DepotMap\E)(.*)#[0-9]* - (\S*) (\S*) (\S*).*/i;
  740. #
  741. # Don't submit edit files or addfiles
  742. #
  743. if ($3 eq $Action)
  744. {
  745. #
  746. # Get formatted version of $main::SourceControlClient opened output ready
  747. # to be put into submit statement
  748. #
  749. $FileName = "$1$2";
  750. $FileAndAction = "$1$2 # $3";
  751. #
  752. # Find out if file is in default change list or has change associated with it
  753. #
  754. if ($4 eq "change")
  755. {
  756. system "$main::SourceControlClient reopen -c default $FileName";
  757. system "$main::SourceControlClient change -d $5";
  758. }
  759. #
  760. # If $FileName is in @main::FileList add file to list
  761. #
  762. if (($main::OutOfDateFiles) or (SlmSubs::InList($FileName, \@main::FileList)))
  763. {
  764. #
  765. # Append to @SubmitList
  766. #
  767. push @{$SubmitListReference}, "\t$FileAndAction\n";
  768. }
  769. #
  770. # If $FileName is in @main::DirList add file to list
  771. #
  772. elsif (SlmSubs::InList($FileName, \@main::DirList))
  773. {
  774. #
  775. # Append to @SubmitList
  776. #
  777. push @{$SubmitListReference}, "\t$FileAndAction\n";
  778. }
  779. }
  780. }
  781. close(OPENED);
  782. }
  783. sub Recurser
  784. # __________________________________________________________________________________
  785. #
  786. # Recursive routine that calls the subroutine (referenced by the first parameter)
  787. # in the appropriate directories
  788. #
  789. # Parameters:
  790. # FunctionName, Optional Subdirectory
  791. #
  792. # Output:
  793. # None
  794. #
  795. # __________________________________________________________________________________
  796. {
  797. #
  798. # FirstInitialize $FunctionName
  799. #
  800. my $FunctionName;
  801. if ($_[0])
  802. {
  803. $FunctionName = $_[0];
  804. }
  805. else
  806. {
  807. $FunctionName = "";
  808. }
  809. #
  810. # Initialize $SubDirectory
  811. #
  812. my $SubDirectory;
  813. if ($_[1])
  814. {
  815. $SubDirectory = $_[1];
  816. }
  817. else
  818. {
  819. $SubDirectory = "";
  820. }
  821. #
  822. # Don't recurse if -r not on the command line
  823. #
  824. if ($main::Recursive)
  825. {
  826. my @allp4dirs;
  827. if ($DeletedDirectories)
  828. {
  829. #
  830. # Get the list of directories that Perforce knows about
  831. #
  832. open (DIRS, qq/$main::SourceControlClient dirs -D "$SubDirectory\*" 2>&1|/);
  833. @allp4dirs = <DIRS>;
  834. close DIRS;
  835. }
  836. else
  837. {
  838. #
  839. # Get a list of dirs to find out which files in @main::OriginalFileList are really directories
  840. #
  841. if ($SubDirectory)
  842. {
  843. #
  844. # Make a chopped version of $SubDirectory to print out
  845. #
  846. $ChoppedSubDirectory = $SubDirectory;
  847. chop $ChoppedSubDirectory;
  848. opendir CurrentDir, $ChoppedSubDirectory;
  849. }
  850. else
  851. {
  852. opendir CurrentDir, ".";
  853. }
  854. while (defined($file = readdir(CurrentDir)))
  855. {
  856. if (grep -d, "$SubDirectory$file")
  857. {
  858. if (grep !/^\.\.?$/, $file)
  859. {
  860. push @allp4dirs, $file;
  861. }
  862. }
  863. }
  864. closedir CurrentDir;
  865. foreach $Dir (@allp4dirs)
  866. {
  867. $Dir = "$main::DepotMap$SubDirectory$Dir\n";
  868. }
  869. }
  870. if (!@main::DirList or @main::FileList or $SubDirectory)
  871. {
  872. @main::LocalDirs = @allp4dirs;
  873. #
  874. # Call $FunctionName on the current directory before recursing
  875. #
  876. &$FunctionName($SubDirectory);
  877. }
  878. foreach $Dir (@allp4dirs)
  879. {
  880. if (!@main::DirList or @main::FileList or (SlmSubs::InList($Dir, \@main::DirList)))
  881. {
  882. if ($Dir =~ s/\Q$main::DepotMap$SubDirectory\E(.*)\n/$1/i)
  883. {
  884. &Recurser($FunctionName, "$SubDirectory$Dir\/");
  885. }
  886. }
  887. }
  888. }
  889. else
  890. {
  891. &$FunctionName($SubDirectory);
  892. }
  893. }
  894. sub DeleteDuplicateLines
  895. # __________________________________________________________________________________
  896. #
  897. # Gets rid of duplicate lines in List
  898. #
  899. # Parameters:
  900. # List reference
  901. #
  902. # Output:
  903. # None
  904. # __________________________________________________________________________________
  905. {
  906. #
  907. # Initialize variables
  908. #
  909. %ListHash = ();
  910. @DesiredList = ();
  911. #
  912. # Set $ListRef to Second Parameter
  913. #
  914. $ListRef = $_[0];
  915. #
  916. # Reverse list so that the last duplicate is preserved
  917. #
  918. @ReversedList = reverse @{$ListRef};
  919. foreach $Line (@ReversedList)
  920. {
  921. $Desired = $main::TRUE;
  922. if (($Linee =~ /^\t\/\//) or ($Line =~ /^\t-\/\//))
  923. {
  924. #
  925. # Check if $Line is already in the %ListHash. If it is don't add it to @DesiredList.
  926. #
  927. if (! ($ListHash{$Line}))
  928. {
  929. $ListHash{$Line}++;
  930. }
  931. else
  932. {
  933. $Desired = $main::FALSE;
  934. }
  935. }
  936. if ($Desired)
  937. {
  938. push @DesiredList, $Line;
  939. }
  940. }
  941. @{$ListRef} = reverse @DesiredList;
  942. }
  943. sub DeleteNegatedLines
  944. # __________________________________________________________________________________
  945. #
  946. # Gets rid of negated duplicate lines in List
  947. #
  948. # Parameters:
  949. # List reference
  950. #
  951. # Output:
  952. # None
  953. # __________________________________________________________________________________
  954. {
  955. #
  956. # Initialize variables
  957. #
  958. %ListHash = ();
  959. @DesiredList = ();
  960. #
  961. # Set $ListRef to Second Parameter
  962. #
  963. $ListRef = $_[0];
  964. #
  965. # Reverse list so that the last duplicate is preserved
  966. #
  967. @ReversedList = reverse @{$ListRef};
  968. foreach $Line (@ReversedList)
  969. {
  970. $Desired = $main::TRUE;
  971. if (($Containee =~ /^\t\/\//) or ($Containee =~ /^\t-\/\//))
  972. {
  973. #
  974. # Initialize variable
  975. #
  976. $NegatedLine = "";
  977. if ($Line =~ /^\t(.)(.*\n)/)
  978. {
  979. if ($1 eq '-')
  980. {
  981. $NegatedLine = "\t$2";
  982. }
  983. else
  984. {
  985. $NegatedLine = "\t-$1$2";
  986. }
  987. }
  988. #
  989. # Check if $Line is already in the %ListHash. If it is don't add it to @DesiredList.
  990. #
  991. if (! ($ListHash{$NegatedLine}))
  992. {
  993. $ListHash{$Line}++;
  994. }
  995. else
  996. {
  997. $Desired = $main::FALSE;
  998. }
  999. }
  1000. if ($Desired)
  1001. {
  1002. push @DesiredList, $Line;
  1003. }
  1004. $ContaineeCounter++;
  1005. }
  1006. @{$ListRef} = reverse @DesiredList;
  1007. }
  1008. sub DeleteContainedInLines
  1009. # __________________________________________________________________________________
  1010. #
  1011. # Gets rid of lines contained in lines above them
  1012. #
  1013. # Parameters:
  1014. # List reference
  1015. #
  1016. # Output:
  1017. # None
  1018. # __________________________________________________________________________________
  1019. {
  1020. @DesiredList = ();
  1021. #
  1022. # Set $ListRef to Second Parameter
  1023. #
  1024. $ListRef = $_[0];
  1025. #
  1026. # Reverse list because it's easier to figure out precedence this way
  1027. #
  1028. @ReversedList = reverse @{$ListRef};
  1029. $ContaineeCounter = 1;
  1030. foreach $Containee (@ReversedList)
  1031. {
  1032. $Desired = $main::TRUE;
  1033. if (($Containee =~ /^\t\/\//) or ($Containee =~ /^\t-\/\//))
  1034. {
  1035. $ContainerCounter = $ContaineeCounter;
  1036. if ($Containee =~ /^\t-\/\//)
  1037. {
  1038. $ContaineeOrientation = "-";
  1039. }
  1040. else
  1041. {
  1042. $ContaineeOrientation = "+";
  1043. }
  1044. CompareLoop: while ($Container = $ReversedList[$ContainerCounter++])
  1045. {
  1046. if (($Container =~ /^\t\/\//) or ($Container =~ /^\t-\/\//))
  1047. {
  1048. if ($Container =~ /^\t-\/\//)
  1049. {
  1050. $ContainerOrientation = "-";
  1051. }
  1052. else
  1053. {
  1054. $ContainerOrientation = "+";
  1055. }
  1056. $RegExpContainer = $Container;
  1057. $RegExpContainer =~ s/\*/[^\\\/]*&[^\@~\@]/g;
  1058. $RegExpContainer =~ s/\.\.\./\.\*/g;
  1059. $RegExpContainer =~ s/\\/\\\\/g;
  1060. $RegExpContainer =~ s/\@~\@/\\.\\.\\./g;
  1061. $RegExpContainer =~ s/^\t-*/\^\\t-\*/;
  1062. if ($Containee =~ /$RegExpContainer/)
  1063. {
  1064. if ($ContainerOrientation eq $ContaineeOrientation)
  1065. {
  1066. $Desired = $main::FALSE;
  1067. }
  1068. last CompareLoop;
  1069. }
  1070. }
  1071. }
  1072. }
  1073. if ($Desired)
  1074. {
  1075. push @DesiredList, $Containee;
  1076. }
  1077. $ContaineeCounter++;
  1078. }
  1079. @{$ListRef} = reverse @DesiredList;
  1080. }
  1081. sub DeleteSuperceededLines
  1082. # __________________________________________________________________________________
  1083. #
  1084. # Gets rid of lines superceeded by more global lines
  1085. #
  1086. # Parameters:
  1087. # List reference
  1088. #
  1089. # Output:
  1090. # None
  1091. # __________________________________________________________________________________
  1092. {
  1093. @DesiredList = ();
  1094. #
  1095. # Set $ListRef to Second Parameter
  1096. #
  1097. $ListRef = $_[0];
  1098. @List = @{$ListRef};
  1099. $ContaineeCounter = 1;
  1100. foreach $Containee (@List)
  1101. {
  1102. $Desired = $main::TRUE;
  1103. if (($Containee =~ /^\t\/\//) or ($Containee =~ /^\t-\/\//))
  1104. {
  1105. $ContainerCounter = $ContaineeCounter;
  1106. CompareLoop: while ($Container = $List[$ContainerCounter++])
  1107. {
  1108. if (($Container =~ /^\t\/\//) or ($Container =~ /^\t-\/\//))
  1109. {
  1110. $RegExpContainer = $Container;
  1111. $RegExpContainer =~ s/\*/[^\\\/]*&[^\@~\@]/g;
  1112. $RegExpContainer =~ s/\.\.\./\.\*/g;
  1113. $RegExpContainer =~ s/\\/\\\\/g;
  1114. $RegExpContainer =~ s/\@~\@/\\.\\.\\./g;
  1115. $RegExpContainer =~ s/^\t/\^\\t-\*/;
  1116. if ($Containee =~ /$RegExpContainer/)
  1117. {
  1118. $Desired = $main::FALSE;
  1119. last CompareLoop;
  1120. }
  1121. }
  1122. }
  1123. }
  1124. if ($Desired)
  1125. {
  1126. push @DesiredList, $Containee;
  1127. }
  1128. $ContaineeCounter++;
  1129. }
  1130. @{$ListRef} = @DesiredList;
  1131. }
  1132. sub CleanUpList
  1133. # __________________________________________________________________________________
  1134. #
  1135. # Parent cleanup subroutine that farms out all the work to various other routines
  1136. #
  1137. # Parameters:
  1138. # List reference
  1139. #
  1140. # Output:
  1141. # None
  1142. # __________________________________________________________________________________
  1143. {
  1144. #
  1145. # Set $ListRef to First Parameter
  1146. #
  1147. $ListRef = $_[0];
  1148. DeleteDuplicateLines($ListRef);
  1149. DeleteNegatedLines($ListRef);
  1150. DeleteSuperceededLines($ListRef);
  1151. DeleteContainedInLines($ListRef);
  1152. }
  1153. 1;