Source code of Windows XP (NT5)
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.

363 lines
9.3 KiB

  1. # __________________________________________________________________________________
  2. #
  3. # Purpose:
  4. # PERL Script to emulate SLM's 'status' command
  5. #
  6. # Parameters:
  7. # See Usage below
  8. #
  9. # Output:
  10. # Perforce output or the appropriate error message or usage statement
  11. #
  12. # __________________________________________________________________________________
  13. #
  14. # Load common SLM wrapper subroutine module
  15. #
  16. use SlmSubs;
  17. #
  18. # Parse command line arguments
  19. #
  20. SlmSubs::ParseArgs(@ARGV);
  21. #
  22. # Call usage and exit if ParseArgs has set the Usage or InvalidFlag flags
  23. #
  24. if ($Usage or $InvalidFlag)
  25. {
  26. print $ErrorMessage;
  27. &Usage;
  28. exit 1;
  29. }
  30. #
  31. # Can't have both -x and -o
  32. #
  33. if (($AllFiles) and ($OutOfDateFiles))
  34. {
  35. print "\n";
  36. print "Error: can't specify -o with -x\n";
  37. print "\n";
  38. &Usage;
  39. exit 1;
  40. }
  41. if (@FileList or @DirList)
  42. {
  43. open (P4Opened, "$SourceControlClient opened @FileList @DirList 2>&1|");
  44. }
  45. else
  46. {
  47. open (P4Opened, "$SourceControlClient opened $AllFilesSymbol 2>&1|");
  48. }
  49. @P4OpenedList = <P4Opened>;
  50. close (P4Opened);
  51. #
  52. # If -x switch used, invoke $SourceControlClient files
  53. #
  54. if ($AllFiles)
  55. {
  56. %P4OpenedHash = ();
  57. foreach $P4OpenedLine (@P4OpenedList)
  58. {
  59. if ( $P4OpenedLine =~ /.*\Q$DepotMap\E([^#]*)#[0-9]* - \S*.*/i )
  60. {
  61. $P4OpenedHash{$1}++;
  62. }
  63. }
  64. if (@FileList or @DirList)
  65. {
  66. open (P4Files, "$SourceControlClient files @FileList @DirList 2>&1|");
  67. open (P4Have, "$SourceControlClient have @FileList @DirList 2>&1|");
  68. }
  69. else
  70. {
  71. open (P4Files, "$SourceControlClient files $AllFilesSymbol 2>&1|");
  72. open (P4Have, "$SourceControlClient have $AllFilesSymbol 2>&1|");
  73. }
  74. @P4FilesList = <P4Files>;
  75. close (P4Files);
  76. @P4HaveList = <P4Have>;
  77. close (P4Have);
  78. }
  79. else
  80. {
  81. if (@FileList or @DirList)
  82. {
  83. if ($OutOfDateFiles)
  84. {
  85. open (P4Files, "$SourceControlClient sync -n @FileList @DirList 2>&1|");
  86. }
  87. }
  88. else
  89. {
  90. if ($OutOfDateFiles)
  91. {
  92. open (P4Files, "$SourceControlClient sync -n $AllFilesSymbol 2>&1|");
  93. }
  94. }
  95. @P4FilesList = <P4Files>;
  96. close (P4Files);
  97. %P4FilesHash = ();
  98. foreach $P4FilesLine (@P4FilesList)
  99. {
  100. if ( $P4FilesLine =~ /.*\Q$DepotMap\E([^#]*)#[0-9]* - \S*.*/i )
  101. {
  102. $P4FilesHash{$1}++;
  103. }
  104. }
  105. @P4OpenedNotInFilesList = ();
  106. %P4OpenedHash = ();
  107. foreach $P4OpenedLine (@P4OpenedList)
  108. {
  109. if ( $P4OpenedLine =~ /.*\Q$DepotMap\E([^#]*)#[0-9]* - \S*.*/i )
  110. {
  111. $P4OpenedHash{$1}++;
  112. if (!$P4FilesHash{$1})
  113. {
  114. push @P4OpenedNotInFilesList, $P4OpenedLine;
  115. }
  116. }
  117. }
  118. @P4OpenedList = @P4OpenedNotInFilesList;
  119. push (@P4FilesList, @P4OpenedList);
  120. $MaxCommandLineLength = 255;
  121. @HaveFileNames = ();
  122. $CommandLineLength = 8;
  123. foreach $P4FilesLine (@P4FilesList)
  124. {
  125. if ( $P4FilesLine =~ /.*\Q$DepotMap\E([^#]*)#[0-9]* - \S*.*/i )
  126. {
  127. $FileName = qq/"$1"/;
  128. $FileLength = length ($FileName);
  129. if (($CommandLineLength + $FileLength) > $MaxCommandLineLength)
  130. {
  131. open (P4HaveOutput, "$SourceControlClient have @HaveFileNames 2>&1|");
  132. @P4HaveOutput = <P4HaveOutput>;
  133. close (P4HaveOutput);
  134. push @P4HaveList, @P4HaveOutput;
  135. @HaveFileNames = ();
  136. $CommandLineLength = 8;
  137. }
  138. push @HaveFileNames, $FileName;
  139. $CommandLineLength = $CommandLineLength + $FileLength;
  140. }
  141. }
  142. open (P4HaveOutput, "$SourceControlClient have @HaveFileNames 2>&1|");
  143. @P4HaveOutput = <P4HaveOutput>;
  144. close (P4HaveOutput);
  145. push @P4HaveList, @P4HaveOutput;
  146. }
  147. #
  148. # Initialize list
  149. #
  150. @StatusCache = ();
  151. @P4FilesList = sort @P4FilesList;
  152. #
  153. # Get the output from Perforce and format it
  154. #
  155. foreach $P4FilesLine (@P4FilesList)
  156. {
  157. #
  158. # Grep current directory information out of output
  159. #
  160. if ( $P4FilesLine =~ /.*\Q$DepotMap\E([^#]*)#([0-9]*) - (\S*).*/i )
  161. {
  162. $FileName = $1;
  163. $ServerVersion = $2;
  164. $Status = "*add";
  165. if ($3 eq "delete" or $3 eq "deleted")
  166. {
  167. $Status = "(deleted)";
  168. }
  169. $LocalVersion = "0";
  170. HaveLoop: foreach $HaveLine (@P4HaveList)
  171. {
  172. if ($HaveLine =~ /\Q$DepotMap$FileName\E#([0-9]*)/i)
  173. {
  174. $LocalVersion = $1;
  175. if ($Status ne "(deleted)")
  176. {
  177. $Status = "in";
  178. if ($ServerVersion != $LocalVersion)
  179. {
  180. $Status = "*update";
  181. if ($P4OpenedHash{$FileName})
  182. {
  183. $Status = "*merge";
  184. }
  185. }
  186. elsif ($P4OpenedHash{$FileName})
  187. {
  188. $Status = "out";
  189. }
  190. }
  191. last HaveLoop;
  192. }
  193. }
  194. push @StatusCache, "$FileName, $LocalVersion, $ServerVersion, $Status\n";
  195. }
  196. }
  197. #
  198. # Call subroutine that handles recursion and calls the RetrieveStatus subroutine that
  199. # pulls 'Status' information from @StatusCache
  200. #
  201. &SlmSubs::Recurser("main::RetrieveStatus");
  202. sub RetrieveStatus
  203. # __________________________________________________________________________________
  204. #
  205. # Does all the interaction with the SLM server and reformatting of results to look
  206. # like SLM's 'Status' output
  207. #
  208. # Parameters:
  209. # Optional Subdirectory
  210. #
  211. # Output:
  212. # Regular SLM 'Status' output
  213. #
  214. # __________________________________________________________________________________
  215. {
  216. if ($_[0])
  217. {
  218. #
  219. # Modify $_[0] to have forward slashes
  220. #
  221. $ForwardSlashSubDirectory = $_[0];
  222. $ForwardSlashSubDirectory =~ s/\//\//g;
  223. #
  224. # Make a chopped version of $_[0] to print out
  225. #
  226. $ChoppedSubDirectory = $_[0];
  227. chop $ChoppedSubDirectory;
  228. }
  229. else
  230. {
  231. #
  232. # Initialize string to null
  233. #
  234. $ForwardSlashSubDirectory = "";
  235. }
  236. #
  237. # Initialize flags and lists
  238. #
  239. $FirstPass = $TRUE;
  240. @FormattedStatusList = ();
  241. #
  242. # Get the current directory only information from the cache and format it
  243. #
  244. foreach $StatusCacheLine (@StatusCache)
  245. {
  246. #
  247. # Append the current directory to the root depot map and grep for only those files in the cache that are in this
  248. # subdirectory
  249. #
  250. if ($StatusCacheLine =~ /^\Q$ForwardSlashSubDirectory\E([^,]*), ([^,]*), ([^,]*), ([^,]*)\n/i )
  251. {
  252. $FileName = $1;
  253. $ServerVersion = $2;
  254. $LocalVersion = $3;
  255. $Status = $4;
  256. $FirstFileSubdir = "";
  257. $FileName =~ /([^\/]*)\/.*/;
  258. $FirstFileSubdir =$1;
  259. #
  260. # Don't pick up files in subdirectories unless they are addfiles which won't be revealed recursively
  261. #
  262. if ((! ($FileName =~ /\//)) or ((!grep { /\/\Q$FirstFileSubdir\E$/i } @LocalDirs) and ($Status == "*add")))
  263. {
  264. #
  265. # Print out header if this is the first time through
  266. #
  267. if ($FirstPass)
  268. {
  269. print "\n";
  270. if ($ChoppedSubDirectory)
  271. {
  272. print "Status for $LocalMap\/$ChoppedSubDirectory:\n";
  273. }
  274. else
  275. {
  276. print "Status for $LocalMap:\n";
  277. }
  278. print "\n";
  279. print "file local-ver ver status\n";
  280. print "\n";
  281. $FirstPass = $FALSE;
  282. }
  283. #
  284. # Format the output to look like SLM's 'Status' output
  285. #
  286. $FormattedFileName = sprintf "%-19s", "$FileName";
  287. $FormattedServerVersion = sprintf "%9s", "$ServerVersion";
  288. $FormattedLocalVersion = sprintf "%4s", "$LocalVersion";
  289. $FormattedStatus = $Status;
  290. push @FormattedStatusList, "$FormattedFileName $FormattedServerVersion $FormattedLocalVersion $FormattedStatus\n";
  291. }
  292. }
  293. }
  294. print @FormattedStatusList;
  295. }
  296. sub Usage
  297. # __________________________________________________________________________________
  298. #
  299. # Prints out a usage statement for this script. In this case usurped from SLM's
  300. # 'status' usage statement
  301. #
  302. # Parameters:
  303. # None
  304. #
  305. # Output:
  306. # The usage statement
  307. #
  308. # __________________________________________________________________________________
  309. {
  310. print q/status - prints the status of a project
  311. Usage: status [-?fhrox] [file1] [file2... ]
  312. Arguments:
  313. -h prints out this message.
  314. -r (recursive) applies the command to a given directory and in every
  315. subdirectory beneath it. If a pattern is given, matches the pattern.
  316. -o (out) list the status of all files that are either checked out, or
  317. which are out of synchronization with the master versions.
  318. -x list the status of ALL files
  319. /;
  320. }