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.

467 lines
13 KiB

  1. # ---------------------------------------------------------------------------
  2. # Script: A2U
  3. #
  4. # (c) 2000 Microsoft Corporation. All rights reserved.
  5. #
  6. # Purpose: This script is an example of a perl module in the NT postbuild
  7. # environment.
  8. #
  9. # Version: <1.00> (<mm/dd/yyyy>) : (<your alias>) <Purpose>
  10. # <1.01> (<mm/dd/yyyy>) : (<your alias>) <Purpose>
  11. #---------------------------------------------------------------------
  12. # Set Package
  13. # <Set your package name of your perl module>
  14. package A2U;
  15. # Set the script name
  16. # <Set your script name>
  17. $ENV{script_name} = 'A2U.pm';
  18. # Set version
  19. # <Set the version of your script>
  20. $VERSION = '1.00';
  21. # Set required perl version
  22. # <Set the version of perl that your script requires>
  23. require 5.003;
  24. # Use section
  25. use lib $ENV{ "RazzleToolPath" };
  26. use lib $ENV{ "RazzleToolPath" } . "\\PostBuildScripts";
  27. use GetParams;
  28. use LocalEnvEx;
  29. use ParseTable;
  30. use Logmsg;
  31. use strict;
  32. use cklang;
  33. use cksku;
  34. no strict 'vars';
  35. no strict 'refs';
  36. # <Add any perl modules that you will be using for this script>
  37. # Require section
  38. require Exporter;
  39. # <Add any perl pl files that you will be using>
  40. # Global variable section
  41. # <Add any global variables here using my to preserve namespace>
  42. local *CMDOUT;
  43. my (@A2U, $A2UEX, @A2USKUs, $SKU, $pbuildpath, %list, $TempFile, %Codes);
  44. my %RelateSubdir = (
  45. PER => "perinf",
  46. PRO => "\.",
  47. BLA => "blainf",
  48. SBS => "sbsinf",
  49. SRV => "srvinf",
  50. ADS => "entinf",
  51. DTC => "dtcinf",
  52. );
  53. my (@PER, @WKS, @BLA, @SBS, @SRV, @ENT, @DTC);
  54. my (@ruleitems);
  55. sub Main {
  56. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  57. # Begin Main code section
  58. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  59. # Return when you want to exit on error
  60. # <Implement your code here>
  61. return if ($lang=~/(usa)|(psu)|(mir)/i);
  62. my $KeyFileName = "cddata.txt.full";
  63. my $TempDir = $ENV{ "TMP" };
  64. my $BinDiffFile = $ENV{_NTPostBld} . "\\build_logs\\bindiff.txt";
  65. my (@files, %BinDiff);
  66. @ruleitems = split(/,/, $ruleitem);
  67. if ((-e "$TempDir\\$KeyFileName") && (!$full)) {
  68. # Put here instead outside of this if-statement is
  69. # because CdDataUpdate calls init itself for compatible with calls from cddata.cmd
  70. &init or return;
  71. logmsg( "Create the A2U list from $TempDir\\$KeyFileName..." );
  72. open(F1, "$TempDir\\$KeyFileName") or do {errmsg( "Can not open cddata file $TempDir\\$KeyFileName." ); return;};
  73. if (-e $BinDiffFile) {
  74. # Create BinDiffFile to the hash for easy to search
  75. open(F, $BinDiffFile) or do {errmsg( "Can not open bindiff file $BinDiffFile." ); return;};
  76. %BinDiff = map({chomp;s/$ENV{_NTPostBld}//; $_ => 1} <F>);
  77. close(F);
  78. # Filter all filename in cddata.txt with is defined in bindiff and Unicode's field is 't' (true)
  79. @files = map({
  80. chomp;
  81. my ($file,$flag)=(split(/ = |:/))[0,7];
  82. ((exists $BinDiff{$file}) && ($flag eq "t"))?$file:()} <F1>);
  83. } else {
  84. # Filter all filename in cddata.txt with Unicode's field is 't' (true)
  85. @files = map({
  86. chomp;
  87. my ($file,$flag)=(split(/ = |:/))[0,7];
  88. ($flag eq "t")?$file:()} <F1>);
  89. }
  90. close(F1);
  91. # Convert the files to unicode.
  92. Convert(\@files);
  93. } else {
  94. # Create its file list if not cddata.txt exists
  95. logmsg( "Create the A2U list from A2U.txt..." );
  96. @files = &CdDataUpdate(@ruleitems);
  97. Convert(\@files);
  98. }
  99. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  100. # End Main code section
  101. # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  102. }
  103. # <Implement your subs here>
  104. sub init {
  105. # Read a2u.txt
  106. my @A2UEX;
  107. parse_table_file("$ENV{RazzleToolPath}\\PostbuildScripts\\a2u.txt", \@A2U);
  108. parse_table_file("$ENV{RazzleToolPath}\\codes.txt", \%Codes);
  109. # Read a2uex.txt
  110. # open F, "$ENV{RazzleToolPath}\\PostbuildScripts\\a2uex.txt" or do { errmsg("A2UEX.TXT cannot be open"); return 0;};
  111. # $A2UEX = join(",", map({chomp;(/^\;/ || /^\s*$/)?():$_} <F>));
  112. # close F;
  113. parse_table_file("$ENV{RazzleToolPath}\\PostbuildScripts\\a2uex.txt", \@A2UEX);
  114. $A2UEX = join(",", map {$_->{Exclude}} @A2UEX);
  115. # Get Language's SKUs
  116. @A2USKUs = map({$sku=$_;(cksku::CkSku($sku, $lang, $ENV{_BuildArch}) eq 1)?$sku:()} reverse qw(PRO PER BLA SBS SRV ADS DTC));
  117. $TempFile = $ENV{tmpfile};
  118. $TempFile =~ /(.+)\\[^\\]+/; # Get it's path
  119. $TempFile = `$ENV{RazzleToolPath}\\uniqfile.cmd $1\\$ENV{script_name}_loctmp.tmp`;
  120. chomp $TempFile;
  121. logmsg( "Applicable SKUs: " . join(", ", @A2USKUs) );
  122. return 1;
  123. }
  124. sub CdDataUpdate {
  125. my (@files) = @_;
  126. $lang = $ENV{lang};
  127. return if ($lang=~/(usa)|(psu)/i);
  128. &init or return;
  129. # A2U is the list we get from a2u.txt, which contains the rules for convertion.
  130. # Look for each rule to find out the applicable files.
  131. # Locate the files in the tree and store their location in %list.
  132. foreach $hA2U (@A2U) {
  133. if (@files ne 0) {
  134. my $FOUND=0;
  135. for (@files) {
  136. if ($hA2U->{PbuildPath}=~/$_/i) {
  137. $FOUND=1;
  138. last;
  139. }
  140. }
  141. next if (!$FOUND);
  142. }
  143. if (cklang::CkLang(uc$lang, $hA2U->{Languages})) {
  144. $pbuildpath = "$ENV{_NTPostBld}$hA2U->{PbuildPath}";
  145. $hA2U->{Extension} =~s/^-$//;
  146. $hA2U->{FileDir} =~s/^-$//;
  147. &scan_layoutinf($hA2U->{Extension}, $hA2U->{FileDir});
  148. &locate;
  149. }
  150. }
  151. return map({s/\\\.//g;s/^\Q$ENV{_NTPostBld}\E\\*//;$_} keys %list);
  152. }
  153. sub scan_layoutinf {
  154. my($string, $dirnum) = @_;
  155. my($total, $layoutinf, $file)=(0);
  156. my $orgstring = $string;
  157. local *LAYOUT;
  158. logmsg( "Generating file lists..." );
  159. $string =~ s/^\./\\\./;
  160. foreach $SKU (@A2USKUs) {
  161. $layoutinf = "$pbuildpath\\$RelateSubdir{$SKU}\\layout.inf";
  162. if (open(LAYOUT, $layoutinf)) {
  163. while (<LAYOUT>) {
  164. s/;.*$//;
  165. s/^(\S+)\s*=\s*//;
  166. $file = lc $1;
  167. if ($file =~ /$string/i) {
  168. if ($dirnum) {
  169. push @{$SKU}, $file if (split /,/)[7] == $dirnum;
  170. } else {
  171. push @{$SKU}, $file;
  172. }
  173. }
  174. }
  175. close LAYOUT;
  176. } elsif ((-e "$pbuildpath\\$string") && (!-d "$pbuildpath\\$string")) {
  177. $total++;
  178. @{$SKU} = ($string);
  179. } else {
  180. errmsg("can't open $layoutinf.");
  181. }
  182. $total += @{$SKU};
  183. }
  184. # errmsg("file that matches '$orgstring' " . ($dirnum ? "and '$dirnum' " : "") . "not found.", 2) unless $total;
  185. }
  186. # locate
  187. # Calls search() with prioritized search place list.
  188. # i.e. &search(@WKS, WKS);
  189. # &search(@SRV, SRV, WKS);
  190. # &search(@ENT, ENT, SRV, WKS); ...
  191. sub locate {
  192. foreach my $index ((0..$#A2USKUs)) {
  193. &search(\@{$A2USKUs[$index]}, @A2USKUs[$index..$#A2USKUs]);
  194. @{$A2USKUs[$index]}=();
  195. }
  196. }
  197. # search
  198. # Searches and locates files to be converted.
  199. # Input
  200. # arrayref : reference to file list
  201. # searchlist : list of which type to look for
  202. # Output
  203. # %list (global variable)
  204. # keys are in format of "path/subdir/filename"
  205. sub search {
  206. my($arrayref, @searchlist) = @_;
  207. my $SKU = $searchlist[0];
  208. my ($file, $found);
  209. foreach $file (@$arrayref) {
  210. # Skip files on exclude list
  211. next if ($A2UEX=~/$file/i);
  212. $found = 0;
  213. foreach (@searchlist) {
  214. if (-e "$pbuildpath\\$RelateSubdir{$_}\\$file") {
  215. $list{"$pbuildpath\\$RelateSubdir{$_}\\$file"}++;
  216. $found = 1;
  217. last;
  218. }
  219. }
  220. logmsg("warning: $file for $SKU is not found.") if not $found;
  221. }
  222. }
  223. # Convert
  224. # Converts files to Unicode and copies back.
  225. sub Convert {
  226. my $filesptr = shift;
  227. my ($shortfile, $myfile, $UNICODE, $cmd, $convertctr);
  228. $convertctr=0;
  229. logmsg("Converting $ENV{_NTPostBld} files using codepage and place them into tmp dir $tmp.");
  230. NF: for $shortfile (@$filesptr) {
  231. $myfile = $ENV{_NTPostBld} . "\\" . $shortfile;
  232. $UNICODE = "";
  233. $cmd ="unitext -m -$Codes{uc$lang}->{ACP} -z $myfile $TempFile";
  234. logmsg("$cmd\n");
  235. open UNITEXT, "$cmd |" or do {errmsg("Cannot execute '$cmd'.");next;};
  236. while (<UNITEXT>) {
  237. next if /^Converting /;
  238. if (/^Conversion completed.$/) {
  239. logmsg("$shortfile\t: converted");
  240. $UNICODE = "Y";
  241. $convertctr++;
  242. } elsif (/is probably unicode! Stopping conversion.$/) {
  243. # logmsg("$shortfile\t: already Unicode");
  244. $UNICODE = "N";
  245. next NF;
  246. } else {
  247. logmsg("$shortfile\t: $_");
  248. }
  249. }
  250. close UNITEXT;
  251. logmsg("Copying the Unicode files back to $shortfile");
  252. $cmd = "move /Y $TempFile $myfile";
  253. open MOVECMD, "$cmd |" or errmsg("Cannot execute '$cmd'.");
  254. while (<MOVECMD>) {
  255. logmsg("$_") if /\S/;
  256. }
  257. close MOVECMD;
  258. }
  259. logmsg("Converted $convertctr file(s)");
  260. }
  261. sub ValidateParams {
  262. #<Add your code for validating the parameters here>
  263. }
  264. # <Add your usage here>
  265. sub Usage {
  266. print <<USAGE;
  267. Purpose of program
  268. Usage: $0 [-l lang] [-o ruleitem] [-f]
  269. -l Language
  270. -o ruleitem; such as tsclient
  271. -f fullly run; without reference cddata.txt.full
  272. -? Displays usage
  273. Example:
  274. $0 -l jpn
  275. USAGE
  276. }
  277. sub GetParams {
  278. # Step 1: Call pm getparams with specified arguments
  279. &GetParams::getparams(@_);
  280. # Step 2: Set the language into the enviroment
  281. $ENV{lang}=$lang;
  282. # Step 3: Call the usage if specified by /?
  283. if ($HELP) {
  284. &Usage();
  285. exit 1;
  286. }
  287. }
  288. # Cmd entry point for script.
  289. if (eval("\$0 =~ /" . __PACKAGE__ . "\\.pm\$/i")) {
  290. # Step 1: Parse the command line
  291. # <run perl.exe GetParams.pm /? to get the complete usage for GetParams.pm>
  292. &GetParams ('-o', 'l:o:f', '-p', 'lang ruleitem full', @ARGV);
  293. # Include local environment extension s
  294. &LocalEnvEx::localenvex('initialize');
  295. # Set lang from the environment
  296. $lang=$ENV{lang};
  297. # Validate the option given as parameter.
  298. &ValidateParams;
  299. # Step 4: Call the main function
  300. &A2U::Main();
  301. # End local environment extensions.
  302. &LocalEnvEx::localenvex('end');
  303. }
  304. # -------------------------------------------------------------------------------------------
  305. # Script: A2U.pm
  306. # Purpose: ASCII to UniCode
  307. # SD Location: %sdxroot%\tools\postbuildscripts
  308. #
  309. # (1) Code section description:
  310. # CmdMain - Developer code section. This is where your work gets done.
  311. # <Implement your subs here> - Developer subs code section. This is where you write subs.
  312. #
  313. # (2) Reserved Variables -
  314. # $ENV{HELP} - Flag that specifies usage.
  315. # $ENV{lang} - The specified language. Defaults to USA.
  316. # $ENV{logfile} - The path and filename of the logs file.
  317. # $ENV{logfile_bak} - The path and filename of the logfile.
  318. # $ENV{errfile} - The path and filename of the error file.
  319. # $ENV{tmpfile} - The path and filename of the temp file.
  320. # $ENV{errors} - The scripts errorlevel.
  321. # $ENV{script_name} - The script name.
  322. # $ENV{_NTPostBld} - Abstracts the language from the files path that
  323. # postbuild operates on.
  324. # $ENV{_NTPostBld_Bak} - Reserved support var.
  325. # $ENV{_temp_bak} - Reserved support var.
  326. # $ENV{_logs_bak} - Reserved support var.
  327. #
  328. # (3) Reserved Subs -
  329. # Usage - Use this sub to discribe the scripts usage.
  330. # ValidateParams - Use this sub to verify the parameters passed to the script.
  331. #
  332. # (4) Call other executables or command scripts by using:
  333. # system "foo.exe";
  334. # Note that the executable/script you're calling with system must return a
  335. # non-zero value on errors to make the error checking mechanism work.
  336. #
  337. # Example
  338. # if (system("perl.exe foo.pl -l $lang")){
  339. # errmsg("perl.exe foo.pl -l $lang failed.");
  340. # # If you need to terminate function's execution on this error
  341. # goto End;
  342. # }
  343. #
  344. # (5) Log non-error information by using:
  345. # logmsg "<log message>";
  346. # and log error information by using:
  347. # errmsg "<error message>";
  348. #
  349. # (6) Have your changes reviewed by a member of the US build team (ntbusa) and
  350. # by a member of the international build team (ntbintl).
  351. #
  352. # -------------------------------------------------------------------------------------------
  353. =head1 NAME
  354. B<mypackage> - What this package for
  355. =head1 SYNOPSIS
  356. <An code example how to use>
  357. =head1 DESCRIPTION
  358. <Use above example to describe this package>
  359. =head1 INSTANCES
  360. =head2 <myinstances>
  361. <Description of myinstances>
  362. =head1 METHODS
  363. =head2 <mymathods>
  364. <Description of mymathods>
  365. =head1 SEE ALSO
  366. <Some related package or None>
  367. =head1 AUTHOR
  368. <Your Name <your e-mail address>>
  369. =cut
  370. 1;