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.

1759 lines
51 KiB

  1. if (!$__IITPRINTLPM ) { use iit::printl; }
  2. if (!$__IITUTILPM ) { use iit::util; }
  3. if (!$__IITFILEPM ) { use iit::file; }
  4. if (!$__IITSENDHTMLMAILPM ) { use iit::sendhtmlmail; }
  5. package main;
  6. use strict 'subs';
  7. use Carp; #debugging library (carp, carp, etc.)
  8. use Env; #allows use of $ENVVAR instead of $ENV{ENVVAR}
  9. use win32::console;
  10. $PROC = $PROCESSOR_ARCHITECTURE; # prefer constant PROC (see below)
  11. # CONSTANTS
  12. use constant PROC => $PROCESSOR_ARCHITECTURE;
  13. use constant BC_FAILED => 2;
  14. use constant BC_NOTHINGDONE => 4;
  15. use constant BC_COPYFAILED => 8;
  16. use constant BC_BVTFAILED => 16;
  17. use constant BC_CABFAILED => 32;
  18. use constant BC_CHKSHIPFAILED => 64;
  19. ####################################################################################
  20. # SetLocalGlobalsAndBegin()
  21. # creates a separate enclosed variable scope for your script through use of 'local' variables
  22. # any variable declared in this function will be visible in all child functions, but invisible
  23. # in parent functions
  24. # pass a function name (with syntax *main::<fcnname>) as first argument, and any arguments
  25. # to pass to that function as additional arguments
  26. # return value is return value of the function name passed
  27. # a-jbilas, 05/10/99 - created
  28. ####################################################################################
  29. sub SetLocalGlobalsAndBegin
  30. {
  31. local($sShortBuildName) = $_[0]; #get filenames from the function name
  32. $sShortBuildName =~ s/\*main\:\://;
  33. if ($PROJROOT eq "")
  34. {
  35. die("Project root MUST be defined");
  36. }
  37. #status
  38. local($bcStatus) = BC_NOTHINGDONE;
  39. #numbers
  40. local($nMajorVersion) = 3;
  41. local($nMinorVersion) = 0;
  42. local($nBuildStartYear) = 1999;
  43. local($nErrorNumber) = 1;
  44. local($nMaxErrLines) = 10;
  45. local($nScriptStartTime) = time();
  46. local($nLoggingMode) = 2; # 0 (least) - 2 (most)
  47. local($nTotalBuilds) = 0;
  48. local($nFailedBuilds) = 0;
  49. #paths
  50. local($sLibDir) = $PROJROOT."\\lib\\".PROC;
  51. local($sBinExeDir) = $PROJROOT."\\bin\\".PROC;
  52. local($sBinBatDir) = $PROJROOT."\\bin";
  53. local($sOldPath) = $PATH;
  54. local($sOldInclude) = $INCLUDE;
  55. local($sOldLib) = $LIB;
  56. #strings
  57. local($sBuildName) = "*Unknown Build*";
  58. local($sLanguage) = "ENGLISH";
  59. local($sBuildNumber) = "0000";
  60. local($sLogDir) = $PROJROOT."\\logs";
  61. local($sRootDropDir) = "\\\\b11nlbuilds\\".$PROJ;
  62. local($sTestRootDropDir) = "\\\\nlp\\build\\".$PROJ."\\testdrop";
  63. local($sDropDir) = $sRootDropDir."\\".$sLanguage."\\".$sBuildNumber."\\".PROC;
  64. local($sLogDropDir) = $sDropDir."\\logs";
  65. local($sRemoteBuildLog) = $sShortBuildName.PROC.$sBuildNumber.".html";
  66. local($sRemoteTOC) = "";
  67. local($sMailfile) = $sLogDir."\\".$sShortBuildName."msg.html";
  68. local($sBuildLog) = $sLogDir."\\".$sShortBuildName."log.html";
  69. local($sVarsLog) = $sLogDir."\\".$sShortBuildName."vars.log";
  70. local($sTyposLog) = $sLogDir."\\".$sShortBuildName."typos.log";
  71. local($sSyncLog) = $sLogDir."\\".$sShortBuildName."sync.log";
  72. local($sUpdateLog) = $sLogDir."\\".$sShortBuildName."update.log";
  73. local($sDHTMLIncFile) = $sBinBatDir."\\htmlinc.htm";
  74. local($sOfficialBuildAccount) = "";
  75. local($sRegKeyBase) = "Software\\Microsoft\\Intelligent Interface Technologies\\".$PROJ;
  76. if (!defined $strBuildMsg)
  77. {
  78. $strBuildMsg = ""; #one of our few 'absolute' globals
  79. }
  80. #bools (flags)
  81. local($bGlobalsSet) = 1;
  82. local($bBVT) = 0;
  83. local($bNoCopy) = 0;
  84. local($bOfficialBuild) = 0;
  85. local($bShipBuild) = 0;
  86. local($bColor) = 1;
  87. local($bUpdate) = 0;
  88. local($bWin98) = 0;
  89. local($bCopyFailed) = 0;
  90. local($bBuildFailed) = 0;
  91. local($bAddLanguageString) = 0; # <- TODO: is there a better way to do this?
  92. local($bNothingDone) = 1;
  93. local($bVerbose) = 0;
  94. local($bSendMail) = 0;
  95. local($bErrorConcat) = 0;
  96. local($bDieOnError) = 0;
  97. #lists
  98. local(@lArgs) = ();
  99. local(@lBuilds) = ();
  100. local(@lLanguages) = ();
  101. local(@lModifiers) = ();
  102. local(@lComponents) = ();
  103. local(@lAllowedArgs) = ();
  104. local(@lAllowedComponents) = ();
  105. local(@lAllowedLanguages) = ();
  106. local(@lAllowedBuilds) = ("DEBUG", "RELEASE");
  107. local(@lAllowedModifiers) = ("ALL", "REBUILD", "RESYNC", "TYPO", "UPDATE", "QUIET",
  108. "DEFAULT", "VERBOSE", "TEST", "MAIL");
  109. local(@lAccelList) = ();
  110. local(@lAccelParam) = ();
  111. local(@lDefaultArgs) = ("SHIP", "REBUILD");
  112. local(@lMailRecipients) = ($USERNAME);
  113. local(@lOfficialMailRecipients)= ($USERNAME);
  114. local(@lSyncDirs) = ();
  115. local(@lCleanDirs) = ();
  116. local(@lStdSyncDirs) = ("RECURSE:".$sLibDir,
  117. "RECURSE:".$sBinExeDir,
  118. "RECURSE:".$sBinBatDir,
  119. "RECURSE:".$PROJROOT."\\inc");
  120. #commands
  121. local($cmdIn) = $sBinExeDir."\\in.exe";
  122. local($cmdOut) = $sBinExeDir."\\out.exe";
  123. local($cmdSync) = $sBinExeDir."\\ssync.exe";
  124. local($cmdShowVer) = $sBinExeDir."\\showver.exe";
  125. local($cmdWindiff) = $sBinExeDir."\\windiff.exe";
  126. local($cmdChkShip) = $sBinExeDir."\\chkship.exe";
  127. local($cmdKillOpen) = $sBinExeDir."\\killopen.exe";
  128. if (!-d $sLogDir)
  129. {
  130. EchoedMkdir($sLogDir);
  131. }
  132. # Set OS version
  133. my($x, $sOSVer) = `ver`; #first line is blank
  134. $bWin98 = ($sOSVer =~ /windows 98/i);
  135. local(*Main) = "*main::".$sShortBuildName;
  136. shift(@_);
  137. if (!IsMemberOf("NONEWLOG", @_))
  138. {
  139. local($fhBuildLog) = ""; #fwd declaration (so that begin build can use it)
  140. if (defined &SetLocalGlobalsAndBeginCustom)
  141. {
  142. return(SetLocalGlobalsAndBeginCustom(@_));
  143. }
  144. else
  145. {
  146. return(Main(@_));
  147. }
  148. }
  149. else
  150. {
  151. if (defined &SetLocalGlobalsAndBeginCustom)
  152. {
  153. return(SetLocalGlobalsAndBeginCustom(@_));
  154. }
  155. else
  156. {
  157. return(Main(@_));
  158. }
  159. }
  160. }
  161. ####################################################################################
  162. # HASHES
  163. ####################################################################################
  164. #descriptions of available options (if you don't define it here, it won't show up in usage)
  165. #capitalized letters are used as 'accelerators' (make sure there are no duplicates, the
  166. #script doesn't check for that)
  167. #no single quotes or parens allowed (tooltips don't like them)
  168. %hOptionDescription =
  169. (
  170. # <----------------------------- SCREEN WIDTH -------------------------------------> (accel)
  171. "Debug" => " include debug version - default", #D
  172. "Release" => " include release version", #R
  173. "All" => " include all buildtypes for this build", #A
  174. "REbuild" => " delete old build files and rebuild", #RE
  175. "TYpo" => " check for typos after build finishes", #TY
  176. "Test" => " test build - don't do official build", #T
  177. "DEFault" => " (+) include the default parameters with your custom parameters", #DEF
  178. "Verbose" => " increased script output", #V
  179. "Mail" => " send mail after build completes", #M
  180. "NoCopy" => " prevent copying of files", #NC
  181. "NoNewLog" => "don't open new log for build - log to currently open log, if exist", #NNL
  182. "ReSync" => " resync dirs before building - may not get all dependencies", #RS
  183. "Ship" => " build buildtypes for each specific component -shipping- to server", #S
  184. "bvt" => " run BVT tests after building", #BVT
  185. "bbt" => " BBT optimize build product (available in release build only)", #BBT
  186. "Halt" => " halt on error", #H
  187. "Quiet" => " suppress pop-up windows [html log open on exit, windiff, etc.]", #Q
  188. "AllLang" => " include all languages", #AL
  189. "AllComp" => " include all components", #AC
  190. # <----------------------------- SCREEN WIDTH -------------------------------------> (accel)
  191. );
  192. ####################################################################################
  193. # ChangeTextColor()
  194. # changes current html logging text to color passed in argument
  195. # if null argument, reverts to previous color
  196. # a-jbilas, 04/20/99 - created
  197. ####################################################################################
  198. sub ChangeTextColor
  199. {
  200. if ($bColor)
  201. {
  202. local($sColor) = @_;
  203. if ($sColor eq "") #reset color
  204. {
  205. # system("color 0f");
  206. if ($fhBuildLog)
  207. {
  208. print($fhBuildLog "<\/font>");
  209. }
  210. }
  211. else
  212. {
  213. if ($fhBuildLog)
  214. {
  215. print($fhBuildLog "<font color\=\"$sColor\">"); #remember to reset color first (so that there are no hanging font tags)
  216. }
  217. # system("color $colorcodes{$sColor}");
  218. }
  219. }
  220. return(1);
  221. }
  222. ####################################################################################
  223. # ParseArgs()
  224. # Check all passed args, ensure that they are valid (members of @lAllowedArgs) and returns them
  225. # removes leading whitespace,-,/ and is case insensitive
  226. # takes expanded language names (english => en) and a buildnumber
  227. # if __BUILDNUMBER is member of @lAllowedArgs, will set 4-digit input to $sBuildNumber
  228. # a-jbilas, 04/10/99
  229. ####################################################################################
  230. sub ParseArgs
  231. {
  232. local(@args) = @_;
  233. @lPassedArguments = ();
  234. if (@args == ())
  235. {
  236. if (@lDefaultArgs == ())
  237. {
  238. print(GetUsage());
  239. exit(1);
  240. }
  241. print(STDOUT "No arguments specified, using build defaults : ");
  242. foreach $item (@lDefaultArgs)
  243. {
  244. print(STDOUT $item." ");
  245. }
  246. print(STDOUT "\n\n");
  247. return("DEFAULT", @lDefaultArgs);
  248. }
  249. else
  250. {
  251. foreach $item (@args)
  252. {
  253. if ($item ne "")
  254. {
  255. $item =~ s/^\s*(\/|\-)//; #remove spaces, '/', '-' from beginning (allow -debug, /debug opt.)
  256. if ($item eq "?")
  257. {
  258. print(GetUsage());
  259. exit(1);
  260. }
  261. # is the argument in AllowedArgs? (test expanded short languages as well)
  262. if (!IsMemberOf($item, @lAllowedArgs) && !IsMemberOf($longtoshlang{lc($item)}, @lAllowedArgs))
  263. {
  264. # if we allow buildnumbers, is the argument a 4 digit build number?
  265. if ((IsMemberOf("__BUILDNUMBER", @lAllowedArgs) || IsMemberOf("__BUILDNUMBER", @args))
  266. && $item =~ /^\d\d\d\d$/)
  267. {
  268. $sBuildNumber = $item;
  269. }
  270. # is the argument an accelerator abbreviation?
  271. elsif (IsMemberOf($item, @lAccelList))
  272. {
  273. my($bAccelFound) = 0;
  274. for ($index = 0 ; !$bAccelFound ; ++$index)
  275. {
  276. if (lc($lAccelList[$index]) eq lc($item))
  277. {
  278. if (!IsMemberOf($item, @lPassedArguments))
  279. {
  280. @lPassedArguments = (uc($lAccelParam[$index]), @lPassedArguments);
  281. }
  282. $bAccelFound = 1;
  283. }
  284. elsif ($index >= @lAccelList)
  285. {
  286. carp("Error in ParseArgs(): end of accel list reached ");
  287. $bAccelFound = 1; #exit the loop
  288. }
  289. }
  290. }
  291. elsif (IsMemberOf("__IGNORE", @args))
  292. {
  293. if (!IsMemberOf($item, @lPassedArguments))
  294. {
  295. @lPassedArguments = (uc($item), @lPassedArguments);
  296. }
  297. }
  298. # must be an invalid argument, print usage list and quit
  299. else
  300. {
  301. print(STDERR "Error: What do you mean by: \'$item\' ?\n");
  302. print(STDOUT GetUsage()."\n\n");
  303. exit(1);
  304. }
  305. }
  306. # make sure the argument isn't inserted twice
  307. elsif (!IsMemberOf($item, @lPassedArguments) && !IsMemberOf($longtoshlang{lc($item)}, @lPassedArguments))
  308. {
  309. if ($longtoshlang{lc($item)} ne "")
  310. {
  311. @lPassedArguments = (uc($longtoshlang{lc($item)}), @lPassedArguments);
  312. }
  313. else
  314. {
  315. @lPassedArguments = (uc($item), @lPassedArguments);
  316. }
  317. }
  318. }
  319. }
  320. # append the default arguments (if DEFAULT was passed)
  321. if (IsMemberOf("DEFAULT", @lPassedArguments) && (@lDefaultArgs != ()))
  322. {
  323. foreach $elem (@lDefaultArgs)
  324. {
  325. if (!IsMemberOf($elem, @lPassedArguments))
  326. {
  327. push(@lPassedArguments, $elem);
  328. }
  329. }
  330. }
  331. }
  332. return(@lPassedArguments);
  333. }
  334. ####################################################################################
  335. # Execute()
  336. # executes first argument in eval block and tees output all to log (if open), failures to $sBuildMsg
  337. # if second argument non-null, will exit the script when an error is hit
  338. # outputs results to log and screen; returns 1 upon success, 0 upon failure
  339. # a-jbilas, 04/20/99 - created
  340. # a-jbilas, 05/24/99 - added win98 support
  341. # a-jbilas, 06/15/99 - added bookmark support
  342. # a-jbilas, 06/16/99 - added $_Execute string support (will write output to $_Execute if equal to 1)
  343. ####################################################################################
  344. sub Execute($;$$$)
  345. {
  346. my($sCmd, $bDieIfError, $bQuiet, $bIgnoreError) = @_;
  347. my($rc) = 1;
  348. my($sMsg) = "";
  349. my($bLogExecute) = 0;
  350. if ($_ExecuteQuiet)
  351. {
  352. $bQuiet = 1;
  353. }
  354. if ($_Execute == 1)
  355. {
  356. $_Execute = "";
  357. $bLogExecute = 1;
  358. }
  359. if (!$bQuiet)
  360. {
  361. PrintL(" - Executing \'".($bVerbose ? $sCmd : RemovePath($sCmd))."\'\n", PL_BLUE);
  362. }
  363. eval
  364. {
  365. if ($bWin98)
  366. {
  367. open (CMDIN, $sCmd.' |');
  368. }
  369. else
  370. {
  371. open (CMDIN, $sCmd.' 2>&1 |');
  372. }
  373. while (<CMDIN>)
  374. {
  375. if ($bLogExecute)
  376. {
  377. $_Execute .= $_;
  378. }
  379. elsif (!$bQuiet)
  380. {
  381. PrintL($_);
  382. }
  383. $sMsg .= $_;
  384. }
  385. close (CMDIN);
  386. };
  387. if (!$bIgnoreError && $CHILD_ERROR)
  388. {
  389. if (!$bQuiet)
  390. {
  391. if (IsCritical())
  392. {
  393. PrintLTip("Execution of ".RemovePath($sCmd)." FAILED\n", "Return code: ".($CHILD_ERROR/256),
  394. PL_BIGERROR | PL_SETERROR);
  395. PrintMsgBlock(split(/\n/, $sMsg));
  396. }
  397. else
  398. {
  399. PrintLTip("Execution of ".RemovePath($sCmd)." FAILED\n", "Return code: ".($CHILD_ERROR/256),
  400. PL_ERROR | PL_SETERROR);
  401. }
  402. }
  403. if ($bDieIfError || (IsCritical() && $bDieOnError)) # NOTE: bDieOnError is global, bDieIfError is local
  404. {
  405. exit($CHILD_ERROR/256);
  406. }
  407. $rc = 0;
  408. }
  409. if (!$bIgnoreError && !$rc && IsCritical())
  410. {
  411. $bBuildFailed = 1;
  412. $bcStatus |= BC_FAILED;
  413. }
  414. return($rc);
  415. }
  416. ####################################################################################
  417. # ExecuteAndOutputToFile()
  418. # Executes the command in the first argument (string) and outputs it to a file
  419. # named in the second argument (string)
  420. # if the third argument is non-null, it will die() upon failure
  421. # reports success to screen and log; returns 1 upon success, 0 otherwise
  422. # a-jbilas, 04/20/99 - created
  423. # a-jbilas, 06/15/99 - added bookmark support
  424. ####################################################################################
  425. sub ExecuteAndOutputToFile($$;$$$)
  426. {
  427. my($sCmd, $sFile, $bDieIfError, $bQuiet, $bIgnoreError) = @_;
  428. my($rc) = 1;
  429. my($sMsg) = "";
  430. my($pipe) = ($_ExecuteNoSTDERR ? "" : " 2>&1")." |";
  431. if ($_ExecuteQuiet)
  432. {
  433. $bQuiet = 1;
  434. }
  435. if (!open(FOUT, ">>$sFile"))
  436. {
  437. PrintL("Cannot open output file for $sCmd \>\> $sFile\n", PL_STDERR | PL_RED);
  438. $rc = 0;
  439. }
  440. else
  441. {
  442. if (!$bQuiet)
  443. {
  444. PrintL(" - Executing '".RemovePath($sCmd)." >> ".$sFile."'\n", PL_BLUE);
  445. }
  446. eval
  447. {
  448. if ($bWin98)
  449. {
  450. open (CMDIN, $sCmd.' |');
  451. }
  452. else
  453. {
  454. open (CMDIN, $sCmd.' '.$pipe);
  455. }
  456. while (<CMDIN>)
  457. {
  458. print(FOUT $_);
  459. }
  460. close (CMDIN);
  461. };
  462. if (!$bIgnoreError && $CHILD_ERROR)
  463. {
  464. if (!$bQuiet)
  465. {
  466. if (IsCritical())
  467. {
  468. PrintLTip("Execution of ".RemovePath($sCmd)." FAILED\n", "Return code: ".($CHILD_ERROR/256),
  469. PL_BIGERROR | PL_SETERROR);
  470. }
  471. else
  472. {
  473. PrintLTip("Execution of ".RemovePath($sCmd)." FAILED\n", "Return code: ".($CHILD_ERROR/256),
  474. PL_ERROR | PL_SETERROR);
  475. }
  476. }
  477. if ($bDieIfError || (IsCritical() && $bDieOnError))
  478. {
  479. exit($CHILD_ERROR/256);
  480. }
  481. $rc = 0;
  482. }
  483. close(FOUT);
  484. }
  485. if (!$bIgnoreError && !$rc && IsCritical())
  486. {
  487. $bBuildFailed = 1;
  488. $bcStatus |= BC_FAILED;
  489. }
  490. return($rc);
  491. }
  492. ####################################################################################
  493. # GetArgs()
  494. # Builds and returns a list of allowed args in build
  495. # a-jbilas, 06/21/99 - created
  496. ####################################################################################
  497. sub GetArgs()
  498. {
  499. local(@m_lArgs) = @lAllowedArgs;
  500. @m_lArgs = Union(*m_lArgs, *lAllowedLanguages); #TODO: fix
  501. @m_lArgs = Union(*m_lArgs, *lAllowedBuilds);
  502. @m_lArgs = Union(*m_lArgs, *lAllowedModifiers);
  503. @m_lArgs = Union(*m_lArgs, *lAllowedComponents);
  504. return(@m_lArgs);
  505. }
  506. ####################################################################################
  507. # GetSummary()
  508. # returns a text summary of the build, based upon messages in $strBuildMsg
  509. # removes any html/non-interesting info before returning (preserves old $strBuildMsg as well)
  510. # a-jbilas, 05/27/99 - created
  511. ####################################################################################
  512. sub GetSummary
  513. {
  514. local($strTempBuildMsg) = $strBuildMsg;
  515. $strTempBuildMsg =~ s/\n//g;
  516. $strTempBuildMsg =~ s/<BR>/\n/ig;
  517. $strTempBuildMsg =~ s/<dd>/\n/ig;
  518. $strTempBuildMsg =~ s/<dl compact>.+?<\/dl>//igs;
  519. $strTempBuildMsg =~ s/<! DHTML ACTIVATION SCRIPT >.+?<! END DHTML ACTIVATION SCRIPT >//gs;
  520. $strTempBuildMsg =~ s/<[^>]*>//g;
  521. $strTempBuildMsg =~ s/\n[^\n]*log file[^\n]*\n//g;
  522. return("\n SUMMARY:\n-------------------------------------------------\n".$strTempBuildMsg."\n");
  523. }
  524. ####################################################################################
  525. # PrintToLogLarge()
  526. # Prints string argument to STDOUT and, if $fhBuildLog is defined, to the
  527. # html log (in strong font)
  528. # -USE FOR SECTION HEADER OUTPUT-
  529. # a-jbilas, 04/20/99 - created
  530. # a-jbilas, 08/13/99 - Legacy, prefer PrintL()
  531. ####################################################################################
  532. sub PrintToLogLarge
  533. {
  534. if ($fhBuildLog)
  535. {
  536. print($fhBuildLog "<font size=\"4\"><strong>");
  537. PrintToLog(@_);
  538. print($fhBuildLog "<\/font><\/strong>");
  539. }
  540. else
  541. {
  542. PrintL(@_);
  543. }
  544. }
  545. ####################################################################################
  546. # PrintToLog()
  547. # prints string argument to STDOUT and, if $fhBuildLog is defined, to the html log
  548. # searches input string on words such as 'fail' and 'warn', changes text color if found
  549. # -USE FOR NORMAL OUTPUT-
  550. # a-jbilas, 04/20/99 - created
  551. # a-jbilas, 08/13/99 - Legacy, prefer PrintL()
  552. ####################################################################################
  553. sub PrintToLog
  554. {
  555. local(@output) = @_;
  556. local($sColor) = "";
  557. foreach $elem (@output)
  558. {
  559. if (/fail/i)
  560. {
  561. $sColor = "red";
  562. }
  563. elsif ((/warn/i) && ($sColor ne "red"))
  564. {
  565. $sColor = "purple";
  566. }
  567. }
  568. if ($sColor ne "")
  569. {
  570. ChangeTextColor($sColor);
  571. }
  572. print(STDOUT @output);
  573. if ($fhBuildLog)
  574. {
  575. foreach $elem (@output)
  576. {
  577. $elem =~ s/\n/<br>\n/g;
  578. print($fhBuildLog $elem);
  579. }
  580. }
  581. if ($sColor ne "")
  582. {
  583. ChangeTextColor();
  584. }
  585. }
  586. ####################################################################################
  587. # PrintToLogErr()
  588. # Prints string argument to STDERR and, if $fhBuildLog is defined, to the
  589. # html log (in red text)
  590. # -USE FOR ERROR OUTPUT-
  591. # a-jbilas, 04/20/99 - created
  592. # a-jbilas, 08/13/99 - Legacy, prefer PrintL()
  593. ####################################################################################
  594. sub PrintToLogErr
  595. {
  596. local(@lOutput) = @_;
  597. ChangeTextColor("red");
  598. print(STDERR @lOutput);
  599. if ($fhBuildLog)
  600. {
  601. foreach $elem (@lOutput)
  602. {
  603. $elem =~ s/\n/<br>\n/g;
  604. print($fhBuildLog $elem);
  605. }
  606. }
  607. ChangeTextColor();
  608. }
  609. ####################################################################################
  610. # DumpVars()
  611. # Appends huge list of every var in perl environment to file $sVarsLog
  612. # useful only for doing searches on specific variables
  613. # a-jbilas, 04/10/99 - created
  614. ####################################################################################
  615. sub DumpVars()
  616. {
  617. open(VARSLOG, ">>$sVarsLog");
  618. print(VARSLOG "\n\n***********************************************************\nVARS AT ");
  619. local($package, $file, $line) = caller();
  620. print(VARSLOG $package.' '.$file.' line: '.$line."\n\n\n");
  621. foreach $i (%main::)
  622. {
  623. print(VARSLOG $i."=".$$i."\n");
  624. }
  625. close(VARSLOG);
  626. }
  627. ####################################################################################
  628. # SLMOperation
  629. # does a slm operation, ignores the return
  630. # (it doesn't seem to mean anything)
  631. # and suppresses all the warnings - which are pretty much noise
  632. # second argument is for teeing output to file
  633. # (useful for checking if anything was changed)
  634. # dougp, 04/10/99 - created
  635. ####################################################################################
  636. sub SLMOperation
  637. {
  638. carp("Usage: SLMOperation(args, [teeToFile]) ")
  639. unless(@_ == 1 || @_ == 2);
  640. my ($cmd, $sFileName) = @_;
  641. my ($op, $args) = split ' ', $cmd, 2;
  642. # echo to user
  643. $op .= ' "-f&"'; # this has to be on all commands anyway
  644. $cmd = "$op $args";
  645. print $cmd, "\n";
  646. # run
  647. eval
  648. {
  649. if ($sFileName ne "")
  650. {
  651. if(!open(FOUT, ">>$sFileName"))
  652. {
  653. PrintToLogErr("SLMOperation(@_) error: cannot open $sFileName for output");
  654. }
  655. }
  656. if ($bWin98)
  657. {
  658. open(FPSYS, $cmd. ' |');
  659. }
  660. else
  661. {
  662. open(FPSYS, $cmd. ' 2>&1 |');
  663. }
  664. while (<FPSYS>)
  665. {
  666. if (!/warning:/ && !/^$/ && !/is not ghosted/)
  667. {
  668. print;
  669. if ($sFileName ne "")
  670. {
  671. print(FOUT);
  672. }
  673. }
  674. }
  675. if ($sFileName ne "")
  676. {
  677. close(FOUT);
  678. }
  679. close(FPSYS);
  680. };
  681. if ($@)
  682. {
  683. warn("Run Time Error: $@");
  684. }
  685. sleep 1;
  686. return $? == 0;
  687. }
  688. ####################################################################################
  689. # CopyWithEchoOnError
  690. # copies file in argument, echoes errors to $strBuildMsg on failure
  691. # dougp, 5/10/99
  692. ####################################################################################
  693. sub CopyWithEchoOnError
  694. {
  695. my ($cmd) = @_;
  696. print "copy ".$cmd, "\n";
  697. if ($bWin98)
  698. {
  699. open (FPIN, 'copy '.$cmd.' |');
  700. }
  701. else
  702. {
  703. open (FPIN, 'copy '.$cmd.' 2>&1 |');
  704. }
  705. my $msg="";
  706. while (<FPIN>)
  707. {
  708. print;
  709. $msg .= "<dd>".$_;
  710. }
  711. close (FPIN);
  712. if ($? != 0)
  713. {
  714. $strBuildMsg .= "<dd>copy ".$cmd." <b>FAILED</b>\n<dl compact><em>\n".$msg."</dl></em>\n";
  715. $bCopyFailed = 1;
  716. }
  717. }
  718. ####################################################################################
  719. # CopyLogs()
  720. # copies logs to $sRootDropDir
  721. # use main build function name appended with x86/alpha and build number.html for log file name
  722. # will also append www toc for build (if exists) with build log ref and status
  723. # a-jbilas, 05/14/99 - created
  724. # a-jbilas, 05/28/99 - will now only append if no log of same build exists and will update status of
  725. # existing log
  726. # a-jbilas, 07/01/99 - use http addresses instead of unc addresses
  727. ####################################################################################
  728. sub CopyLogs()
  729. {
  730. my($rc) = 1;
  731. EchoedMkdir($sLogDropDir);
  732. if ($bOfficialBuild && !$bNoCopy)
  733. {
  734. my $sLinkCurBuild = '<td><img border=0 src="'.
  735. (($bcStatus & BC_NOTHINGDONE) ? "NothingDone" : (($bcStatus & BC_FAILED) ? "fail" : "succeed")).
  736. '.gif">&nbsp<a href="'.$sLogDropDir."\\".$sRemoteBuildLog.'">'.PROC.'</a></td>'."\n";
  737. if (!EchoedCopy($sBuildLog, $sLogDropDir."\\".$sRemoteBuildLog))
  738. {
  739. $rc = 0;
  740. }
  741. elsif (-e $sRemoteTOC)
  742. {
  743. PrintL(" - Updating web log TOC\n", PL_BLUE);
  744. my($fhTOC) = OpenFile($sRemoteTOC, "r");
  745. my($sTOC) = "";
  746. if ($fhTOC)
  747. {
  748. while (!$fhTOC->eof())
  749. {
  750. my($sCurLine) = $fhTOC->getline();
  751. if ($sCurLine =~ /Build $sBuildNumber/i)
  752. {
  753. $sTOC .= $sCurLine; # skip build header
  754. $sTOC .= $fhTOC->getline(); # skip <tr>
  755. if (PROC ne "x86")
  756. {
  757. $sTOC .= $fhTOC->getline(); # skip x86 build status link
  758. }
  759. $sCurLine = $fhTOC->getline();
  760. $sCurLine = $sLinkCurBuild;
  761. }
  762. $sTOC .= $sCurLine;
  763. }
  764. CloseFile($fhTOC);
  765. }
  766. unlink($sRemoteTOC);
  767. $fhTOC = OpenFile($sRemoteTOC, "w");
  768. if ($fhTOC)
  769. {
  770. $fhTOC->print($sTOC);
  771. CloseFile($fhTOC);
  772. }
  773. else
  774. {
  775. PrintL("Could not write to TOC (no write access?)\n", PL_ERROR);
  776. $rc = 0;
  777. }
  778. }
  779. }
  780. return($rc);
  781. }
  782. ####################################################################################
  783. # UpdateLogTOC()
  784. # Update the logging TOC to include current build with status 'yellow' and a link to log location
  785. # a-jbilas, 06/01/99 - created
  786. # a-jbilas, 06/02/99 - added to nlglib
  787. ####################################################################################
  788. sub UpdateLogTOC($$)
  789. {
  790. my($remotetoc, $logname) = @_;
  791. # TODO: potential file sync bug
  792. if ($bOfficialBuild && !$bNoCopy && (-e $remotetoc) && ($COMPUTERNAME ne ""))
  793. {
  794. PrintL(" - Updating web logs TOC ...\n\n", PL_NOLOG);
  795. my($fhTOCFile) = OpenFile($remotetoc, "r");
  796. if (!$fhTOCFile)
  797. {
  798. return(0);
  799. }
  800. my($sTOCFile) = "";
  801. my($sBuildHeader) = '<tr><td colspan="2"><center><b>Build '.$sBuildNumber.'</b></center></td></tr>'."\n";
  802. my($sBuildBlank) = '<td></td>'."\n";
  803. my($sBuildCur) = '<td><img border=0 src="waiting.gif">&nbsp<a href="'
  804. .TranslateToHTTP("\\\\".$COMPUTERNAME."\\".$PROJ."logs\\".RemovePath($logname))."\">"
  805. .PROC."</a></td>\n";
  806. my($bUpdateIt) = 1;
  807. while(!$fhTOCFile->eof())
  808. {
  809. my($sCurLine) = $fhTOCFile->getline();
  810. if ((($sCurLine =~ /Build \d\d\d\d/i) || ($sCurLine =~ /<\/table>/i)) && $bUpdateIt)
  811. {
  812. if ($sCurLine =~ /$sBuildNumber/)
  813. # we must have either done a previous build or another build beat us here
  814. # either way, make certain that the status is 'waiting'
  815. {
  816. # don't change the build header
  817. $sTOCFile .= $sCurLine;
  818. # skip the <tr>
  819. $sTOCFile .= $fhTOCFile->getline();
  820. # if alpha, skip the first (x86) build link
  821. if (IsAlpha())
  822. {
  823. $sTOCFile .= $fhTOCFile->getline();
  824. }
  825. # rewrite our waiting build line
  826. $sCurLine = $fhTOCFile->getline();
  827. $sCurLine = $sBuildCur;
  828. # if x86, skip the second (alpha) build link
  829. if (Isx86())
  830. {
  831. $sTOCFile .= $sCurLine;
  832. $sCurLine = $fhTOCFile->getline();
  833. }
  834. $bUpdateIt = 0;
  835. }
  836. else
  837. # this is not our build, insert ours before this build (or end of table)
  838. {
  839. $sTOCFile .= $sBuildHeader."<tr>\n";
  840. if (IsAlpha())
  841. {
  842. $sTOCFile .= $sBuildBlank;
  843. }
  844. $sTOCFile .= $sBuildCur;
  845. if (Isx86())
  846. {
  847. $sTOCFile .= $sBuildBlank;
  848. }
  849. $sTOCFile .= "<\/tr>\n\n";
  850. $bUpdateIt = 0;
  851. }
  852. }
  853. $sTOCFile .= $sCurLine;
  854. }
  855. CloseFile($fhTOCFile);
  856. # output everything to new revised log file
  857. unlink($remotetoc);
  858. $fhTOC = OpenFile($remotetoc, "w");
  859. if ($fhTOC)
  860. {
  861. $fhTOC->print($sTOCFile);
  862. CloseFile($fhTOC);
  863. }
  864. else
  865. {
  866. PrintL("Could not write to TOC (no write access?)\n", PL_BIGERROR);
  867. return(0);
  868. }
  869. }
  870. return(1);
  871. }
  872. ####################################################################################
  873. # InsertSummaryIntoLog()
  874. # Inserts a summarized version of $strBuildMsg into the build at first '<! $name SUMMARY ENTRY POINT >' found
  875. # a-jbilas, 06/03/99 - created
  876. ####################################################################################
  877. sub InsertSummaryIntoLog($)
  878. {
  879. local($sLogFile) = @_;
  880. local($rc) = 1;
  881. unlink($sLogFile.".tmp");
  882. if ((-e $sLogFile) && copy($sLogFile, $sLogFile.".tmp"))
  883. {
  884. unlink($sLogFile);
  885. my($fhLogIn) = OpenFile($sLogFile.".tmp", "read");
  886. my($fhLogOut) = OpenFile($sLogFile, "write");
  887. while (<$fhLogIn>)
  888. {
  889. if (/<\! $sShortBuildName $nScriptStartTime SUMMARY ENTRY POINT >/)
  890. {
  891. print($fhLogOut "<font size=5><b>".BuildCodeToHTML($bcStatus)."</font></b>".
  892. "&nbsp&nbsp<strong><font size=3>(".
  893. FmtDeltaTime(time() - $nScriptStartTime).")</strong></font><BR>\n".
  894. "<h3><strong>Summary:</h3></strong><BR>\n".$strBuildMsg."\n<BR>\n<BR>");
  895. }
  896. print($fhLogOut $_);
  897. }
  898. CloseFile($fhLogIn);
  899. CloseFile($fhLogOut);
  900. unlink($sLogFile.".tmp");
  901. }
  902. elsif ($bVerbose)
  903. {
  904. print(STDERR "InsertSummaryIntoLog() Error: Cannot copy $sLogFile to temp file");
  905. $rc = 0
  906. }
  907. return($rc);
  908. }
  909. ####################################################################################
  910. # Bookmark()
  911. # if $fhBuildLog is defined, a <a name=> bookmark will be appended to the log and
  912. # the string passed to the function will be returned with an href to the bookmark's location
  913. # (this function is meant for adding bookmarks to $strBuildMsg)
  914. # a-jbilas, 06/04/99 - created
  915. # a-jbilas, 09/20/99 - if second arg non-null, search for existing tag at beginning of str and concatinate href within
  916. ####################################################################################
  917. sub Bookmark
  918. {
  919. my($string) = $_[0];
  920. if ($fhBuildLog && $sShortBuildName && ($sBuildLog || $sRemoteBuildLog) && (defined $nErrorNumber))
  921. {
  922. print($fhBuildLog "<a name=".$sShortBuildName.$nErrorNumber."><\/a><BR>\n");
  923. my($log);
  924. if ($bOfficialBuild)
  925. {
  926. $log = TranslateToHTTP(($sLogDropDir ne "" ? $sLogDropDir."\\" : "").$sRemoteBuildLog);
  927. }
  928. else
  929. {
  930. $log = TranslateToHTTP($sBuildLog);
  931. }
  932. $log =~ s/\\/\//g; #replace \ with / for http links
  933. if ($_[1])
  934. {
  935. $string =~ s/(<a [^>]*>)//;
  936. my($hrefstr) = $1;
  937. $hrefstr =~ s/<a /<a href="$log#$sShortBuildName$nErrorNumber"/;
  938. $string = $hrefstr.$string;
  939. }
  940. else
  941. {
  942. if ($string =~ /\n$/)
  943. {
  944. $string =~ s/\n$//g;
  945. $string = "<a href=\"".$log."#".$sShortBuildName.$nErrorNumber."\">".$string."<\/a>\n";
  946. }
  947. else
  948. {
  949. $string = "<a href=\"".$log."#".$sShortBuildName.$nErrorNumber."\">".$string."<\/a>";
  950. }
  951. }
  952. ++$nErrorNumber;
  953. }
  954. return($string);
  955. }
  956. ####################################################################################
  957. # BuildAcceleratorLists()
  958. # Extracts the accelerator (abbreviation) keys and inserts them into @lAccelList
  959. # (just the accelerators) and the matching param for the accel into @lAccelParam
  960. # a-jbilas, 06/09/99 - created
  961. ####################################################################################
  962. sub BuildAcceleratorLists()
  963. {
  964. my(@lKeys) = keys(%hOptionDescription);
  965. @lAccelParam = ();
  966. @lAccelList = ();
  967. foreach $key (@lKeys)
  968. {
  969. my($keyAccel) = "";
  970. for ($index = 0 ; $index < length($key) ; ++$index)
  971. {
  972. if ((vec($key, $index, 8) > 64) && (vec($key, $index, 8) < 91))
  973. {
  974. $keyAccel .= substr($key, $index, 1);
  975. }
  976. }
  977. if ($keyAccel ne "")
  978. {
  979. push(@lAccelParam, $key);
  980. push(@lAccelList, $keyAccel);
  981. }
  982. }
  983. # special accelerator key for default settings
  984. push(@lAccelParam, "DEFAULT");
  985. push(@lAccelList, "+");
  986. }
  987. ####################################################################################
  988. # GetLatestBuildDir()
  989. # given a directory (and an optional subdirectory), will return the latest 4 digit
  990. # build number named subdirectory of the specified directory (containing the optional
  991. # subdirectory in the build (such as 'x86'), if specified)
  992. # if no valid dirs exist, will return a null string
  993. # a-jbilas, 06/15/99 - created
  994. ####################################################################################
  995. sub GetLatestBuildDir($;$)
  996. {
  997. my($sBuildDir, $sSubDir) = @_;
  998. PrintL("looking for latest build dir in $sBuildDir, $sSubDir\n", PL_VERBOSE);
  999. my($sLatestBuild) = "0000";
  1000. local(@lDirs) = grep(/\d\d\d\d$/, GetSubdirs($sBuildDir));
  1001. foreach $dir (@lDirs)
  1002. {
  1003. my($sBldNum) = $dir;
  1004. $sBldNum =~ s/.*(\d\d\d\d)$/$1/;
  1005. if ((-d $sBuildDir."\\".$sBldNum.($sSubDir ne "" ? "\\".$sSubDir : "")) && ($sBldNum > $sLatestBuild))
  1006. {
  1007. $sLatestBuild = $sBldNum;
  1008. }
  1009. }
  1010. if (($sLatestBuild eq "0000") && !(-d $sBuildDir."\\".$sLatestBuild.($sSubDir ne "" ? "\\".$sSubDir : "")))
  1011. {
  1012. return("");
  1013. }
  1014. else
  1015. {
  1016. return($sBuildDir."\\".$sLatestBuild.($sSubDir ne "" ? "\\".$sSubDir : ""));
  1017. }
  1018. }
  1019. ####################################################################################
  1020. # GrabCookie()
  1021. # Grabs the cookie -- when passed r (read) or w (write) string as parameter, if cookie
  1022. # grab fails, will wait 10 minutes before trying another grab. If cookie could not be
  1023. # grabbed after 30 attempts (5 hours), function returns 0, it otherwise returns 1
  1024. # a-jbilas, 07/14/99 - created
  1025. ####################################################################################
  1026. sub GrabCookie
  1027. {
  1028. my($rc) = 1;
  1029. my($nMaxAttempts) = 30;
  1030. my($bCookieGrabbed) = 0;
  1031. if (($_[0] ne "r") && ($_[0] ne "w"))
  1032. {
  1033. carp("Usage: GrabCookie(r/w) ");
  1034. $rc = 0;
  1035. }
  1036. else
  1037. {
  1038. PrintL("Attempting to obtain a ".$_[0]." lock on cookie\n");
  1039. for ($nAttempt = 1 ; (!$bCookieGrabbed && ($nAttempt <= $nMaxAttempts)) ; ++$nAttempt)
  1040. {
  1041. if (Execute('cookie -v'.$_[0].'c "Locked for the '.PROC.' build"'))
  1042. {
  1043. PrintL("Cookie successfully grabbed\n");
  1044. $bCookieGrabbed = 1;
  1045. }
  1046. elsif ($nAttempt != 30)
  1047. {
  1048. PrintL("Cookie grab failed, waiting 10 minutes for cookie to be freed ", PL_WARNING);
  1049. for ($time = 1 ; $time <= 10 ; ++$time) #sleep ten minutes
  1050. {
  1051. print(".");
  1052. sleep(60);
  1053. }
  1054. PrintL("\n");
  1055. }
  1056. }
  1057. }
  1058. if (!$bCookieGrabbed)
  1059. {
  1060. PrintL("GrabCookie() Error: Cookie could not be obtained\n", PL_BIGERROR);
  1061. $rc = 0;
  1062. }
  1063. return($rc);
  1064. }
  1065. sub FreeCookie()
  1066. {
  1067. return(Execute('cookie -f'));
  1068. }
  1069. ####################################################################################
  1070. # PrintToMsg()
  1071. # Outputs 1st string parameter to $strBuildMsg with optional additional string
  1072. # parameters output as subsets to 1st string (all properly formatted)
  1073. # a-jbilas, 07/22/99 - created
  1074. ####################################################################################
  1075. sub PrintToMsg
  1076. {
  1077. local(@lOutput) = @_;
  1078. if ($lOutput[0] =~ /fail/i)
  1079. {
  1080. PrintToLogErr($lOutput[0]);
  1081. }
  1082. else
  1083. {
  1084. PrintToLog($lOutput[0]);
  1085. }
  1086. $lOutput[0] =~ s/(failed|succeeded|succeeds)/<bold>$1<\/bold>/gi;
  1087. $strBuildMsg .= "<dd>".$lOutput[0]."\n";
  1088. shift(@lOutput);
  1089. if ($lOutput)
  1090. {
  1091. $strBuildMsg .= "<dl compact><em>\n";
  1092. foreach $msg (@lOutput)
  1093. {
  1094. PrintToLog($msg);
  1095. $msg =~ s/\n/<BR>\n/g;
  1096. $strBuildMsg .= "<dd>".$msg;
  1097. }
  1098. $strBuildMsg .= "<\/dl><\/em>\n";
  1099. }
  1100. }
  1101. sub PrintMsgBlock
  1102. {
  1103. if (scalar(@_) == 0)
  1104. {
  1105. return();
  1106. }
  1107. my($lineNum) = 0;
  1108. my($maxReached) = 0;
  1109. PrintL("<dl compact>", PL_MSGONLY | PL_MSGCONCAT);
  1110. foreach $elem (@_)
  1111. {
  1112. foreach $line (split(/\n+/, $elem))
  1113. {
  1114. if ((!defined $nMaxErrLines) || (!$maxReached && ($lineNum < $nMaxErrLines)))
  1115. {
  1116. if ($line eq "")
  1117. {
  1118. PrintL("<BR>\n", PL_MSGONLY);
  1119. }
  1120. else
  1121. {
  1122. PrintL($line."\n", PL_ITALIC | PL_MSGONLY);
  1123. }
  1124. }
  1125. elsif (!$maxReached)
  1126. {
  1127. PrintL("Too many errors to display, click here to view continuation\n",
  1128. PL_ITALIC | PL_MSGONLY | PL_RED | PL_BOLD | PL_BOOKMARK);
  1129. $maxReached = 1;
  1130. }
  1131. ++$lineNum;
  1132. }
  1133. }
  1134. PrintL("</dl>", PL_MSG | PL_NOSTD | PL_NOLOG | PL_MSGCONCAT);
  1135. }
  1136. sub GetSLMLog
  1137. {
  1138. my($strArg) = "";
  1139. my($dir) = "";
  1140. my($time) = "";
  1141. my(%log) = "";
  1142. foreach $i (@_)
  1143. {
  1144. if ($i eq "today")
  1145. {
  1146. my($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
  1147. $strArg .= " -t ".($mon + 1)."/$mday/$year";
  1148. }
  1149. elsif ($i eq "user")
  1150. {
  1151. $strArg .= " -u $ENV{COMPUTERNAME}";
  1152. }
  1153. else
  1154. {
  1155. $strArg .= " $i";
  1156. }
  1157. }
  1158. open(FPIN, 'log "-rfvi&" '.$strArg.' |');
  1159. while (<FPIN>)
  1160. {
  1161. if (/^time/ || /^log : warning: /)
  1162. {
  1163. # skip header and warnings
  1164. }
  1165. elsif (/Log for (.*):/)
  1166. {
  1167. $dir = $1.$2;
  1168. #print "Directory is ".$dir."\n";
  1169. }
  1170. elsif (/^(\d\d)-(\d\d)-(\d\d)\@(\d\d):(\d\d):(\d\d)\b(.*)$/)
  1171. {
  1172. $time = "$3/$1/$2 $4:$5:$6 ";
  1173. my($day, $who, $what, $file, $ver1, $comment) = split ' ', $7, 6;
  1174. if ($file =~ /.+\\([\w.]+)/)
  1175. {
  1176. $file = "$dir\\$1";
  1177. }
  1178. if ($comment =~ /I\d+ +(.*)/)
  1179. {
  1180. $comment = $1;
  1181. }
  1182. if ($what ne "release")
  1183. {
  1184. $log{"$time $who $what $file"} = " - $comment\n";
  1185. }
  1186. }
  1187. }
  1188. close(FPIN);
  1189. my($retVal) = "";
  1190. foreach $k (reverse sort keys %log)
  1191. {
  1192. $retVal .= $k.$log{$k};
  1193. }
  1194. return($retVal);
  1195. }
  1196. sub FormatLogAsHTML($)
  1197. {
  1198. if ($_[0] eq "")
  1199. {
  1200. return('<font size=4><b>No History Available</b></font>');
  1201. }
  1202. my($result) = "<table border=1><caption><font size=4><b>Recent History</b></font></caption>\n".
  1203. "<tr><th>when</th><th>who</th><th>what</th><th>file</th><th>comment</th></tr>\n";
  1204. foreach $line (split(/\n/, $_[0]))
  1205. {
  1206. my($date, $time, $who, $what, $file, $comment) = split(' ', $line, 6);
  1207. if ($comment =~ /^- (.*)/)
  1208. {
  1209. $comment = $1;
  1210. }
  1211. $result .= "<tr><td>$date $time</td><td>$who</td><td>$what</td><td>$file</td><td>$comment</td></tr>\n";
  1212. }
  1213. close (FPIN);
  1214. return($result."</table>\n");
  1215. }
  1216. sub IsCritical()
  1217. {
  1218. if (!defined $__CRITICAL_SECTION)
  1219. {
  1220. $__CRITICAL_SECTION = 1;
  1221. }
  1222. if ($__CRITICAL_SECTION > 0)
  1223. {
  1224. return(1);
  1225. }
  1226. else
  1227. {
  1228. return(0);
  1229. }
  1230. }
  1231. sub UpdateDir
  1232. {
  1233. my($sSLMDir, $sSrcDir, $bRecurse, $bCheckForNew, $bForceAdd, $bCheckInAfterUpdate) = @_;
  1234. PushD($sSrcDir);
  1235. foreach $dir (GetSubdirs("", $bRecurse))
  1236. {
  1237. if (!-e $sSLMDir."\\".$dir."\\slm.ini")
  1238. {
  1239. if ($bCheckForNew)
  1240. {
  1241. my($ret) = "";
  1242. if (!$bForceAdd)
  1243. {
  1244. PrintL("Add new dir ".$dir."? (y\/n\/a) ");
  1245. $ret = <STDIN>;
  1246. }
  1247. if ($ret =~ /a/)
  1248. {
  1249. $bForceAdd = 1;
  1250. }
  1251. if ($bForceAdd || ($ret =~ /y/i))
  1252. {
  1253. EchoedMkdir($sSLMDir."\\".$dir);
  1254. PushD(GetPath($sSLMDir));
  1255. Execute("addfile -f -c \"ActivePerl Update Dir\" ".$dir);
  1256. PopD();
  1257. }
  1258. }
  1259. else
  1260. {
  1261. PrintL("Warning: ".$dir." not found in current perl version\n", PL_WARNING);
  1262. }
  1263. }
  1264. }
  1265. # foreach $file (grep(!/\.dll$/, GetFiles("", $bRecurse)))
  1266. foreach $file (grep(!/^slm\.ini$/i, GetFiles("", $bRecurse)))
  1267. {
  1268. if (!-e $sSLMDir."\\".$file)
  1269. {
  1270. if ($bCheckForNew)
  1271. {
  1272. my($ret) = "";
  1273. if (!$bForceAdd)
  1274. {
  1275. PrintL("Add new file ".$file."? (y\/n\/a) ");
  1276. $ret = <STDIN>;
  1277. }
  1278. if ($ret =~ /a/)
  1279. {
  1280. $bForceAdd = 1;
  1281. }
  1282. if ($bForceAdd || ($ret =~ /y/i))
  1283. {
  1284. Execute("copy ".$file." ".$sSLMDir."\\".$file);
  1285. PushD(GetPath($sSLMDir."\\".$file));
  1286. Execute("addfile -f -c \"ActivePerl Build 519 File\" ".RemovePath($file));
  1287. PopD();
  1288. }
  1289. }
  1290. else
  1291. {
  1292. PrintL("Warning: ".$file." not found in current perl version\n", PL_WARNING);
  1293. }
  1294. }
  1295. else
  1296. {
  1297. if (!EchoedCompare($file, $sSLMDir."\\".$file))
  1298. {
  1299. PrintL(" - Updating ".$file."\n", PL_BLUE);
  1300. PushD(GetPath($sSLMDir."\\".$file));
  1301. Execute("out -f ".RemovePath($file));
  1302. PopD();
  1303. Execute("copy ".$file." ".$sSLMDir."\\".$file);
  1304. if ($bCheckInAfterUpdate)
  1305. {
  1306. PushD(GetPath($sSLMDir."\\".$file));
  1307. Execute("in -f -c \"Update\" ".RemovePath($file));
  1308. PopD();
  1309. }
  1310. }
  1311. }
  1312. }
  1313. PopD(); #$sSrcDir
  1314. }
  1315. sub Depends
  1316. {
  1317. foreach $var (@_)
  1318. {
  1319. if (!defined $$var)
  1320. {
  1321. PrintL("build script warning: variable dependency ".$var." not defined\n", PL_BIGWARNING);
  1322. carp("Location:");
  1323. }
  1324. }
  1325. }
  1326. sub BuildCodeToHTML($)
  1327. {
  1328. my($str) = "";
  1329. if ($_[0] & BC_FAILED)
  1330. {
  1331. $str .= "<font color=\"red\">FAILED<\/font> ";
  1332. }
  1333. elsif ($_[0] & BC_NOTHINGDONE)
  1334. {
  1335. $str .= "<font color=\"blue\">NOTHING DONE<\/font> ";
  1336. }
  1337. else
  1338. {
  1339. $str .= "<font color=\"green\">SUCCEEDED<\/font> ";
  1340. }
  1341. local(@lSecondaryFailures) = ();
  1342. if ($_[0] & BC_COPYFAILED)
  1343. {
  1344. push(@lSecondaryFailures, "copy");
  1345. }
  1346. if ($_[0] & BC_BVTFAILED)
  1347. {
  1348. push(@lSecondaryFailures, "bvt");
  1349. }
  1350. if ($_[0] & BC_CABFAILED)
  1351. {
  1352. push(@lSecondaryFailures, "msi build");
  1353. }
  1354. if ($_[0] & BC_CHKSHIPFAILED)
  1355. {
  1356. push(@lSecondaryFailures, "chkship");
  1357. }
  1358. if (@lSecondaryFailures != ())
  1359. {
  1360. $str .= "<font color=\"orange\">(with ".join(" and ", @lSecondaryFailures)." failures)<\/font>";
  1361. }
  1362. return($str);
  1363. }
  1364. # ARGS:
  1365. # [str] err
  1366. # OPT ARGS:
  1367. # [bool] concat (default=0)
  1368. sub SetError($;$)
  1369. {
  1370. if ($bErrorConcat)
  1371. {
  1372. if ($_[1] || ($_[0] =~ /\n$/))
  1373. {
  1374. $ERROR .= $_[0];
  1375. }
  1376. else
  1377. {
  1378. $ERROR .= $_[0]."\n";
  1379. }
  1380. }
  1381. else
  1382. {
  1383. $ERROR = $_[0];
  1384. }
  1385. }
  1386. sub ResetError()
  1387. {
  1388. $ERROR = "";
  1389. }
  1390. ########################################################################
  1391. ######################## SECTION BLOCKS ################################
  1392. ########################################################################
  1393. sub BEGIN_CRITICAL_SECTION()
  1394. {
  1395. if (!defined $__CRITICAL_SECTION)
  1396. {
  1397. $__CRITICAL_SECTION = 1;
  1398. }
  1399. else
  1400. {
  1401. ++$__CRITICAL_SECTION;
  1402. }
  1403. }
  1404. sub END_CRITICAL_SECTION()
  1405. {
  1406. if (!defined $__CRITICAL_SECTION)
  1407. {
  1408. $__CRITICAL_SECTION = 0;
  1409. }
  1410. else
  1411. {
  1412. --$__CRITICAL_SECTION;
  1413. }
  1414. }
  1415. sub BEGIN_NON_CRITICAL_SECTION()
  1416. {
  1417. END_CRITICAL_SECTION();
  1418. }
  1419. sub END_NON_CRITICAL_SECTION()
  1420. {
  1421. BEGIN_CRITICAL_SECTION();
  1422. }
  1423. sub BEGIN_DHTML_NODE
  1424. {
  1425. if ($bDHTMLActive)
  1426. {
  1427. PrintL("<div class=\"parent\">"
  1428. ."<img src=http://iit/images/node.bmp> ".(($_[0] eq "") ? "(click to expand)" : $_[0])
  1429. ."<BR><span class=\"childContainer\"><div>",
  1430. PL_NOSTD);
  1431. }
  1432. }
  1433. sub END_DHTML_NODE()
  1434. {
  1435. if ($bDHTMLActive)
  1436. {
  1437. PrintL("</div></span></div>", PL_NOSTD);
  1438. }
  1439. }
  1440. sub ParseArgs2
  1441. {
  1442. local(@lUnparsedArgs) = @_;
  1443. local(%hArgs) = ();
  1444. foreach $elem (@_)
  1445. {
  1446. # first make sure that no spaces were paired with commas
  1447. if (($elem =~ /^\,/) || ($elem =~ /\,$/))
  1448. {
  1449. PrintL("ParseArgs() Fatal Error: separate sub-elements with commas only (no spaces)\n\n", PL_BIGERROR);
  1450. %hArgs->{"__FATAL"} = 1;
  1451. }
  1452. elsif ($elem =~ /:/)
  1453. {
  1454. my($arg, $subargs) = split(":", $elem, 2);
  1455. $subargs =~ s/\,/ /g;
  1456. %hArgs->{uc($arg)} = uc($subargs);
  1457. }
  1458. else
  1459. {
  1460. %hArgs->{uc($elem)} = 1;
  1461. }
  1462. }
  1463. return(%hArgs);
  1464. }
  1465. sub CheckArgs
  1466. {
  1467. my($hArgs, $hAcceptedArgs) = @_;
  1468. # local(%hArgs) = %$phArgs;
  1469. # local(%hAcceptedArgs) = %$phAcceptedArgs;
  1470. my($rc) = 1;
  1471. %hAcceptedArgs->{"__OFFICIAL"} = 1;
  1472. %hAcceptedArgs->{"__BUILDNUMBER"} = 1;
  1473. if (%hArgs->{"__FATAL"})
  1474. {
  1475. $rc = 0;
  1476. }
  1477. elsif (!%hArgs->{"__IGNORE"})
  1478. {
  1479. foreach $arg (keys(%hArgs))
  1480. {
  1481. local(@lAcceptedVals) = StrToL(%hAcceptedArgs->{$arg});
  1482. if (@lAcceptedVals == ())
  1483. {
  1484. PrintL("CheckArgs() Error: ".$arg." is not a valid parameter\n\n", PL_BIGERROR);
  1485. $rc = 0;
  1486. }
  1487. foreach $val (StrToL(%hArgs->{$arg}))
  1488. {
  1489. if (!IsMemberOf($val, @lAcceptedVals))
  1490. {
  1491. PrintL("CheckArgs() Error: ".$val." is not a valid sub-parameter to ".$arg."\n\n", PL_BIGERROR);
  1492. $rc = 0;
  1493. }
  1494. }
  1495. }
  1496. }
  1497. return($rc);
  1498. }
  1499. $__IITENVPM = 1;
  1500. 1;