]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/genrb/genrbjar.pl
ICU-6.2.8.tar.gz
[apple/icu.git] / icuSources / tools / genrb / genrbjar.pl
1 #!/usr/bin/perl
2 # ********************************************************************
3 # * COPYRIGHT:
4 # * Copyright (c) 2002-2004, International Business Machines Corporation and
5 # * others. All Rights Reserved.
6 # ********************************************************************
7
8 # Script to generate the ICULocaleData.jar file. This file is
9 # part of icu4j. It is checked into CVS. It is generated from
10 # locale data in the icu4c project. See usage() notes (below)
11 # for more information.
12
13 # This script requires perl. For Win32, I recommend www.activestate.com.
14
15 # Alan Liu
16
17 use strict;
18 use warnings;
19 use File::Path;
20 use File::Copy;
21
22 my $isMSWin32 = ($^O eq 'MSWin32');
23 usage() unless (@ARGV >= ($isMSWin32 ? 3:2));
24 my $ICU_ROOT = shift;
25 my $ICU4J_ROOT = shift;
26 my $prefix = ''; # e.g. "LD_LIBRARY_PATH=..."
27 my $flavor = ''; # e.g. "Debug/"
28 if ($isMSWin32) {
29 $flavor = shift() . '/';
30 } else {
31 my $isDarwin = ($^O eq 'darwin');
32 my $ldVar = ($isDarwin ? 'DYLD_LIBRARY_PATH' : 'LD_LIBRARY_PATH');
33 $prefix = ($isMSWin32 ? '' : "$ldVar=$ICU_ROOT/source/common:$ICU_ROOT/source/i18n:$ICU_ROOT/source/tools/toolutil:$ICU_ROOT/source/data/out:$ICU_ROOT/source/data: ");
34 }
35 checkPlatform();
36
37 # Step 1. Run genrb.
38 print "\n[Step 1: Run genrb]\n";
39 my $genrb = "$ICU_ROOT/source/tools/genrb/${flavor}genrb";
40 my $dataDir = "$ICU_ROOT/source/data/locales";
41 my $javaRootDir = "$dataDir/java";
42 my $pkg = "com/ibm/icu/impl/data";
43 my $javaDir = "$javaRootDir/$pkg";
44 chdir($dataDir);
45 mkpath($javaDir);
46 my $op = "$prefix$genrb -s. -d$javaDir -j -p com.ibm.icu.impl.data -b LocaleElements ";
47 print "{Command: $op*.txt}\n";
48 print "Directory: $dataDir\n";
49 my @list;
50 if (@ARGV) {
51 @list = @ARGV;
52 foreach (@list) { $_ .= ".txt" unless (/\.txt$/i); }
53 } else {
54 @list = glob("*.txt");
55 }
56 my $count = 0;
57 my $errCount = 0;
58 foreach (sort @list) {
59 cmd("$op $_", " $_ ");
60 ++$count;
61 }
62
63 print "\nProcessed $count locale file(s)\n";
64
65 # Step 2. Create LocaleElements_index.java.
66 print "\n[Step 2: Create LocaleElements_index.java]\n";
67 chdir("$ICU_ROOT/source/data/out/build");
68 cmd("$op res_index.txt");
69 chdir($javaDir);
70 my $f = "LocaleElements_index.java";
71 unlink $f if (-e $f);
72 rename "LocaleElements_res_index.java", $f;
73 patchIndex("LocaleElements_index.java");
74
75 # Step 3. Find %%ALIAS tags.
76 # Assume that it looks like this:
77 # public LocaleElements_no_NO_NY () {
78 # contents = new Object[][] {
79 # {
80 # "%%ALIAS",
81 # "nn_NO",
82 # },
83 # };
84 # }
85 print "\n[Step 3: Scan for %%ALIAS tags]\n";
86 print "Directory: $javaDir\n";
87 chdir($javaDir);
88 @list = glob("LocaleElements*.java");
89 my %aliases;
90 foreach my $file (sort @list) {
91 my $aliasOf = '';
92 open(IN, $file) or die;
93 while (<IN>) {
94 if (/^\s*\"\%\%ALIAS\"/) {
95 # This is an alias of the locale on the next line
96 $aliasOf = <IN>;
97 die "Can't parse $aliasOf" unless
98 ($aliasOf =~ s/^\s*\"(.+?)\",\s*$/$1/);
99 last;
100 }
101 }
102 close(IN);
103
104 if ($aliasOf) {
105 my $me = $file;
106 $me =~ s/^LocaleElements_(.+)\.java$/$1/i;
107 $aliases{$me} = $aliasOf;
108 print " $me is an alias of $aliasOf\n";
109 }
110 }
111
112 # Step 4. Fix %%ALIAS tags.
113 print "\n[Step 4: Fix %%ALIAS tags]\n";
114 my %patched; # Record any locales that we patch
115 foreach my $loc (sort keys %aliases) {
116 # $loc is an alias of $aliases{$loc}
117 # Make $loc point to package private static _contents of $aliases{$loc}
118 my $aliasee = $aliases{$loc};
119 if (!exists($patched{$aliasee})) {
120 # Patch the alias
121 #patchAliasee($aliasee);
122 $patched{$aliasee} = 1;
123 }
124 patchAlias($loc, $aliasee);
125 }
126
127 # Step 5. Patch transliteration resources.
128 # ICU resources have TransliterateLATIN but ICU4J resources expect Transliterate_LATIN
129 print "\n[Step 5: Patch transliteration resources]\n";
130 foreach my $file (sort @list) {
131 my $hasTrans = 0;
132 open(IN, $file) or die;
133 while (<IN>) {
134 # Ignore files that are already patched
135 if (/^\s*\"Transliterate[^_].*\"/) {
136 $hasTrans = 1;
137 last;
138 }
139 }
140 close(IN);
141
142 patchTrans($file) if ($hasTrans);
143 }
144
145 # Step 6. Compile .java files
146 print "\n[Step 6: Compile .java files]\n";
147 my $cmd = "javac -classpath $ICU4J_ROOT/classes:$javaRootDir:%CLASSPATH% $pkg/*.java";
148 chdir($javaRootDir);
149 print "Directory: $javaRootDir\n";
150 cmd($cmd);
151
152 # Step 7. Update .jar file. Do a "jar u" to update the existing file.
153 print "\n[Step 7: Update .jar file]\n";
154 my $jarFile = "$ICU4J_ROOT/src/$pkg/ICULocaleData.jar";
155 my $filesToBePackaged= "$pkg/*.class $pkg/*.col $pkg/*.brk $pkg/*.utf8";
156 $cmd = "jar uf $jarFile $filesToBePackaged";
157 # Do jar command
158 print "Directory: $javaRootDir\n";
159 chdir($javaRootDir);
160 if(-e "$jarFile"){
161 if (! -e "$jarFile.orig") {
162 copy("$jarFile","$jarFile.orig");
163 }
164 }else{
165 $jarFile ="$ICU_ROOT/source/data/locales/java/ICULocaleData.jar";
166 $cmd = "jar cvf $jarFile $filesToBePackaged";
167 }
168 cmd($cmd);
169 print " $jarFile updated\n";
170
171 # Done!
172 print "\n[All done]\n";
173 checkPlatform();
174 exit(0);
175
176 #-----------------------------------------------------------------------
177 # Execute a command
178 # Param: Command
179 # Param: Display line, or '' to display command
180 sub cmd {
181 my $cmd = shift;
182 my $prompt = shift;
183 if ($prompt) {
184 print $prompt;
185 } else {
186 print "{Command: $cmd}..";
187 }
188 my_system($cmd);
189 my $exit_value = $? >> 8;
190 #my $signal_num = $? & 127;
191 #my $dumped_core = $? & 128;
192 if ($exit_value == 0) {
193 print "ok\n" unless ($prompt);
194 } else {
195 ++$errCount;
196 print "ERROR ($exit_value)\n";
197 exit(1);
198 }
199 }
200
201 # A system()-like sub that does NOT ignore SIGINT
202 sub my_system {
203 my $pid = fork;
204 if (! defined $pid) {
205 return -1;
206 } elsif ($pid) {
207 return waitpid($pid, 0);
208 } else {
209 exec(@_) or exit $!;
210 }
211 }
212
213 #-----------------------------------------------------------------------
214 # Patch the file that an %%ALIAS tag points to
215 sub patchAliasee {
216 my $loc = shift;
217 my $file = "LocaleElements_$loc.java";
218 my $omitNextBrace = 0;
219 open(IN, $file) or die;
220 open(OUT, ">$file.new") or die;
221 while (<IN>) {
222 #if (/^\s*data\s*=\s*new\s+Object/) {
223 # print OUT " super.contents = data;\n";
224 # print OUT " };\n";
225 # print OUT ' static final Object[][] data =', "\n";
226 # s/^\s*contents\s*=\s*/ /;
227 # print OUT;
228 # } elsif (/^\s*\}\s*;/) {
229 # # Omit the "}" after this
230 # print OUT;
231 # $omitNextBrace = 1;
232 # } elsif ($omitNextBrace && /^\s*\}\s*$/) {
233 # # Omit it
234 # $omitNextBrace = 0;
235 # } else {
236 print OUT;
237 # }
238 }
239 close(IN);
240 close(OUT);
241 unlink($file);
242 rename("$file.new", $file);
243 print " $file patched (aliasee)\n";
244 }
245
246 #-----------------------------------------------------------------------
247 # Patch the file that contains the %%ALIAS tag
248 sub patchAlias {
249 my $loc = shift;
250 my $aliasee = shift;
251 my $file = "LocaleElements_$loc.java";
252 open(IN, $file) or die;
253 open(OUT, ">$file.new") or die;
254 my $var = "static final Object";
255 while (<IN>) {
256 if(/$var/){
257 # Output our new data
258 print OUT " static final Object[][] data = LocaleElements_$aliasee.data;\n";
259 #consume the next 3 lines
260 <IN>;
261 <IN>;
262 <IN>;
263 <IN>;
264 <IN>;
265 } else {
266 print OUT;
267 }
268 }
269 close(IN);
270 close(OUT);
271 unlink($file);
272 rename("$file.new", $file);
273 print " $file patched (alias)\n";
274 }
275
276 #-----------------------------------------------------------------------
277 # Patch a file with a transliteration resource.
278 sub patchTrans {
279 my $file = shift;
280 open(IN, $file) or die;
281 open(OUT, ">$file.new") or die;
282 while (<IN>) {
283 # This should look like "TransliterateFOO" but if underscores
284 # have crept in, ignore them.
285 s/^(\s*\"Transliterate)_*(.+?\")/$1_$2/;
286 print OUT;
287 }
288 close(IN);
289 close(OUT);
290 unlink($file);
291 rename("$file.new", $file);
292 print " $file patched (trans)\n";
293 }
294
295 #-----------------------------------------------------------------------
296 # Patch the index file, renaming res_index to index
297 sub patchIndex {
298 my $file = shift;
299 open(IN, $file) or die;
300 open(OUT, ">$file.new") or die;
301 while (<IN>) {
302 s/res_(index)/$1/;
303 print OUT;
304 }
305 close(IN);
306 close(OUT);
307 unlink($file);
308 rename("$file.new", $file);
309 print " $file patched (index)\n";
310 }
311
312 #-----------------------------------------------------------------------
313 sub checkPlatform {
314 my $is_big_endian = unpack("h*", pack("s", 1)) =~ /01/;
315 if (!$is_big_endian) {
316 print "*******\n";
317 print "WARNING: You are running on a LITTLE ENDIAN machine.\n";
318 print "WARNING: You cannot use the resulting ICULocaleData.jar\n";
319 print "WARNING: *.col files will have incorrect byte order.\n";
320 print "*******\n";
321 }
322 }
323
324 #-----------------------------------------------------------------------
325 sub usage {
326 print << "END";
327 Usage: genrbjar.pl <icu_root_dir> <icu4j_root_dir> [<locale>+]
328 genrbjar.pl <icu_root_dir> <icu4j_root_dir> ('Debug' | 'Release') [<locale>+]
329
330 'Debug' or 'Release' is required on MSWin32, and absent on UNIX.
331
332 genrbjar creates the ICULocaleData.jar file in the icu4j project. It
333 uses locale data files in the icu4c directory and processes them with
334 genrb to generate Java source. It makes necessary edits to the Java
335 source, then compiles the Java to .class files, then creates a .jar
336 file. The ICULocaleData.jar file is created in its correct location
337 within the icu4j directory structure.
338
339 Optionally, one or more locales may be specified on the command line.
340 If this is done, only those locales will be processed. If no locales
341 are listed, all locales are processed.
342
343 Before running this tool, a JDK must be installed and the javac and
344 jar binaries for that JDK must be on the system path.
345 Examples:
346 i) on Linux: ./genrbjar.pl ~/icu ~/icu4j
347 ii) on Win32: perl genrbjar.pl C:\\icu C:\\icu4j Debug
348
349 NOTE: You CANNOT use the ICULocaleData.jar created on little endian
350 machines (e.g. Win32) because the *.col files will have the wrong byte
351 order. However, you can use the *.class files and look at the *.java
352 files.
353 END
354 exit(0);
355 }
356
357 __END__
358 :endofperl