|
1 #!/usr/bin/perl -w |
|
2 # This Source Code Form is subject to the terms of the Mozilla Public |
|
3 # License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
5 |
|
6 $failure = 0; |
|
7 |
|
8 sub unJAR |
|
9 { |
|
10 my ($file, $dir) = @_; |
|
11 |
|
12 -d $dir && system("rm -rf $dir"); |
|
13 system("unzip -q -d $dir $file") && die("Could not unZIP $file"); |
|
14 } |
|
15 |
|
16 sub readDTD |
|
17 { |
|
18 my ($file) = @_; |
|
19 |
|
20 open DTD, "<$file" || die ("Couldn't open file $file"); |
|
21 |
|
22 local $/ = undef; |
|
23 my $contents = <DTD>; |
|
24 close DTD; |
|
25 |
|
26 $contents =~ s/<!--.*?-->//gs; # strip SGML comments |
|
27 |
|
28 return $contents =~ /<!ENTITY\s+([\w\.]+)\s+(?:\"[^\"]*\"|\'[^\']*\')\s*>/g; |
|
29 } |
|
30 |
|
31 sub compareDTD |
|
32 { |
|
33 my ($path) = @_; |
|
34 |
|
35 my @entities1 = readDTD("$gSourceDir1/$path"); |
|
36 my %entities2 = map { $_ => 1 } readDTD("$gSourceDir2/$path"); |
|
37 |
|
38 my @extra1; |
|
39 |
|
40 foreach my $entity (@entities1) { |
|
41 if (exists $entities2{$entity}) { |
|
42 delete $entities2{$entity}; |
|
43 } else { |
|
44 push @extra1, $entity; |
|
45 } |
|
46 } |
|
47 |
|
48 if (@extra1 or keys %entities2) { |
|
49 $failure = 1; |
|
50 print "Entities in $path don't match:\n"; |
|
51 if (@extra1) { |
|
52 print " In $gSource1: (add these keys to your localization)\n"; |
|
53 map { print " $_\n"; } @extra1; |
|
54 } |
|
55 |
|
56 if (keys %entities2) { |
|
57 print " In $gSource2: (remove these keys from your localization)\n"; |
|
58 map {print " $_\n"; } keys %entities2; |
|
59 } |
|
60 print "\n"; |
|
61 } |
|
62 } |
|
63 |
|
64 sub readProperties |
|
65 { |
|
66 my ($file) = @_; |
|
67 |
|
68 open PROPS, "<$file" || die ("Couldn't open file $file"); |
|
69 |
|
70 local $/ = undef; |
|
71 my $contents = <PROPS>; |
|
72 close PROPS; |
|
73 |
|
74 $contents =~ s/\\$$//gm; |
|
75 |
|
76 return $contents =~ /^\s*([^#!\s\r\n][^=:\r\n]*?)\s*[=:]/gm; |
|
77 } |
|
78 |
|
79 sub compareProperties |
|
80 { |
|
81 my ($path) = @_; |
|
82 |
|
83 my @entities1 = readProperties("$gSourceDir1/$path"); |
|
84 my %entities2 = map { $_ => 1 } readProperties("$gSourceDir2/$path"); |
|
85 |
|
86 my @extra1; |
|
87 |
|
88 foreach my $entity (@entities1) { |
|
89 if (exists $entities2{$entity}) { |
|
90 delete $entities2{$entity}; |
|
91 } else { |
|
92 # hack to ignore non-fatal region.properties differences |
|
93 if ($path !~ /chrome\/browser-region\/region\.properties$/ or |
|
94 ($entity !~ /browser\.search\.order\.[1-9]/ and |
|
95 $entity !~ /browser\.contentHandlers\.types\.[0-5]/ and |
|
96 $entity !~ /gecko\.handlerService\.schemes\./ and |
|
97 $entity !~ /gecko\.handlerService\.defaultHandlersVersion/)) { |
|
98 push @extra1, $entity; |
|
99 } |
|
100 } |
|
101 } |
|
102 # hack to ignore non-fatal region.properties differences |
|
103 if ($path =~ /chrome\/browser-region\/region\.properties$/) { |
|
104 foreach $entity (keys(%entities2)) { |
|
105 if ($entity =~ /browser\.search\.order\.[1-9]/ || |
|
106 $entity =~ /browser\.contentHandlers\.types\.[0-5]/ || |
|
107 $entity =~ /gecko\.handlerService\.schemes\./ || |
|
108 $entity =~ /gecko\.handlerService\.defaultHandlersVersion/) { |
|
109 delete $entities2{$entity}; |
|
110 } |
|
111 } |
|
112 } |
|
113 |
|
114 if (@extra1 or keys %entities2) { |
|
115 $failure = 1; |
|
116 print "Properties in $path don't match:\n"; |
|
117 if (@extra1) { |
|
118 print " In $gSource1: (add these to your localization)\n"; |
|
119 map { print " $_\n"; } @extra1; |
|
120 } |
|
121 |
|
122 if (keys %entities2) { |
|
123 print " In $gSource2: (remove these from your localization)\n"; |
|
124 map {print " $_\n"; } keys %entities2; |
|
125 } |
|
126 print "\n"; |
|
127 } |
|
128 } |
|
129 |
|
130 sub readDefines |
|
131 { |
|
132 my ($file) = @_; |
|
133 |
|
134 open DEFS, "<$file" || die ("Couldn't open file $file"); |
|
135 |
|
136 local $/ = undef; |
|
137 my $contents = <DEFS>; |
|
138 close DEFS; |
|
139 |
|
140 return $contents =~ /#define\s+(\w+)/gm; |
|
141 } |
|
142 |
|
143 sub compareDefines |
|
144 { |
|
145 my ($path) = @_; |
|
146 |
|
147 my @entities1 = readDefines("$gSourceDir1/$path"); |
|
148 my %entities2 = map { $_ => 1 } readDefines("$gSourceDir2/$path"); |
|
149 |
|
150 my @extra1; |
|
151 |
|
152 foreach my $entity (@entities1) { |
|
153 if (exists $entities2{$entity}) { |
|
154 delete $entities2{$entity}; |
|
155 } else { |
|
156 push @extra1, $entity; |
|
157 } |
|
158 } |
|
159 |
|
160 if (@extra1 or keys %entities2) { |
|
161 $failure = 1; |
|
162 print "Defines in $path don't match:\n"; |
|
163 if (@extra1) { |
|
164 print " In $gSource1: (add these to your localization)\n"; |
|
165 map { print " $_\n"; } @extra1; |
|
166 } |
|
167 |
|
168 if (keys %entities2) { |
|
169 print " In $gSource2: (remove these from your localization)\n"; |
|
170 map {print " $_\n"; } keys %entities2; |
|
171 } |
|
172 print "\n"; |
|
173 } |
|
174 } |
|
175 |
|
176 sub compareDir |
|
177 { |
|
178 my ($path) = @_; |
|
179 |
|
180 my (@entries1, %entries2); |
|
181 |
|
182 opendir(DIR1, "$gSourceDir1/$path") || |
|
183 die ("Couldn't list $gSourceDir1/$path"); |
|
184 @entries1 = grep(!(/^(\.|CVS)/ || /~$/), readdir(DIR1)); |
|
185 closedir(DIR1); |
|
186 |
|
187 opendir(DIR2, "$gSourceDir2/$path") || |
|
188 die ("Couldn't list $gSourceDir2/$path"); |
|
189 %entries2 = map { $_ => 1 } grep(!(/^(\.|CVS)/ || /~$/), readdir(DIR2)); |
|
190 closedir(DIR2); |
|
191 |
|
192 foreach my $file (@entries1) { |
|
193 if (exists($entries2{$file})) { |
|
194 delete $entries2{$file}; |
|
195 |
|
196 if (-d "$gSourceDir1/$path/$file") { |
|
197 compareDir("$path/$file"); |
|
198 } else { |
|
199 if ($file =~ /\.dtd$/) { |
|
200 compareDTD("$path/$file"); |
|
201 } elsif ($file =~ /\.inc$/) { |
|
202 compareDefines("$path/$file"); |
|
203 } elsif ($file =~ /\.properties$/) { |
|
204 compareProperties("$path/$file"); |
|
205 } else { |
|
206 print "no comparison for $path/$file\n"; |
|
207 } |
|
208 } |
|
209 } else { |
|
210 push @gSource1Extra, "$path/$file"; |
|
211 } |
|
212 } |
|
213 |
|
214 foreach my $file (keys %entries2) { |
|
215 push @gSource2Extra, "$path/$file"; |
|
216 } |
|
217 } |
|
218 |
|
219 local ($gSource1, $gSource2) = @ARGV; |
|
220 ($gSource1 && $gSource2) || die("Specify two directories or ZIP files"); |
|
221 |
|
222 my ($gSource1IsZIP, $gSource2IsZIP); |
|
223 local ($gSourceDir1, $gSourceDir2); |
|
224 local (@gSource1Extra, @gSource2Extra); |
|
225 |
|
226 if (-d $gSource1) { |
|
227 $gSource1IsZIP = 0; |
|
228 $gSourceDir1 = $gSource1; |
|
229 } else { |
|
230 $gSource1IsZIP = 1; |
|
231 $gSourceDir1 = "temp1"; |
|
232 unJAR($gSource1, $gSourceDir1); |
|
233 } |
|
234 |
|
235 if (-d $gSource2) { |
|
236 $gSource2IsZIP = 0; |
|
237 $gSourceDir2 = $gSource2; |
|
238 } else { |
|
239 $gSource2IsZIP = 1; |
|
240 $gSourceDir2 = "temp2"; |
|
241 unJAR($gSource2, $gSourceDir2); |
|
242 } |
|
243 |
|
244 compareDir("."); |
|
245 |
|
246 if (@gSource1Extra) { |
|
247 print "Files in $gSource1 not in $gSource2:\n"; |
|
248 map { print " $_\n"; } @gSource1Extra; |
|
249 print "\n"; |
|
250 } |
|
251 |
|
252 if (@gSource2Extra) { |
|
253 print "Files in $gSource2 not in $gSource1:\n"; |
|
254 map { print " $_\n"; } @gSource2Extra; |
|
255 print "\n"; |
|
256 } |
|
257 |
|
258 $gSource1IsZIP && system("rm -rf $gSourceDir1"); |
|
259 $gSource2IsZIP && system("rm -rf $gSourceDir2"); |
|
260 |
|
261 exit $failure; |