1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/locales/compare-locales.pl Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,261 @@ 1.4 +#!/usr/bin/perl -w 1.5 +# This Source Code Form is subject to the terms of the Mozilla Public 1.6 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.8 + 1.9 +$failure = 0; 1.10 + 1.11 +sub unJAR 1.12 +{ 1.13 + my ($file, $dir) = @_; 1.14 + 1.15 + -d $dir && system("rm -rf $dir"); 1.16 + system("unzip -q -d $dir $file") && die("Could not unZIP $file"); 1.17 +} 1.18 + 1.19 +sub readDTD 1.20 +{ 1.21 + my ($file) = @_; 1.22 + 1.23 + open DTD, "<$file" || die ("Couldn't open file $file"); 1.24 + 1.25 + local $/ = undef; 1.26 + my $contents = <DTD>; 1.27 + close DTD; 1.28 + 1.29 + $contents =~ s/<!--.*?-->//gs; # strip SGML comments 1.30 + 1.31 + return $contents =~ /<!ENTITY\s+([\w\.]+)\s+(?:\"[^\"]*\"|\'[^\']*\')\s*>/g; 1.32 +} 1.33 + 1.34 +sub compareDTD 1.35 +{ 1.36 + my ($path) = @_; 1.37 + 1.38 + my @entities1 = readDTD("$gSourceDir1/$path"); 1.39 + my %entities2 = map { $_ => 1 } readDTD("$gSourceDir2/$path"); 1.40 + 1.41 + my @extra1; 1.42 + 1.43 + foreach my $entity (@entities1) { 1.44 + if (exists $entities2{$entity}) { 1.45 + delete $entities2{$entity}; 1.46 + } else { 1.47 + push @extra1, $entity; 1.48 + } 1.49 + } 1.50 + 1.51 + if (@extra1 or keys %entities2) { 1.52 + $failure = 1; 1.53 + print "Entities in $path don't match:\n"; 1.54 + if (@extra1) { 1.55 + print " In $gSource1: (add these keys to your localization)\n"; 1.56 + map { print " $_\n"; } @extra1; 1.57 + } 1.58 + 1.59 + if (keys %entities2) { 1.60 + print " In $gSource2: (remove these keys from your localization)\n"; 1.61 + map {print " $_\n"; } keys %entities2; 1.62 + } 1.63 + print "\n"; 1.64 + } 1.65 +} 1.66 + 1.67 +sub readProperties 1.68 +{ 1.69 + my ($file) = @_; 1.70 + 1.71 + open PROPS, "<$file" || die ("Couldn't open file $file"); 1.72 + 1.73 + local $/ = undef; 1.74 + my $contents = <PROPS>; 1.75 + close PROPS; 1.76 + 1.77 + $contents =~ s/\\$$//gm; 1.78 + 1.79 + return $contents =~ /^\s*([^#!\s\r\n][^=:\r\n]*?)\s*[=:]/gm; 1.80 +} 1.81 + 1.82 +sub compareProperties 1.83 +{ 1.84 + my ($path) = @_; 1.85 + 1.86 + my @entities1 = readProperties("$gSourceDir1/$path"); 1.87 + my %entities2 = map { $_ => 1 } readProperties("$gSourceDir2/$path"); 1.88 + 1.89 + my @extra1; 1.90 + 1.91 + foreach my $entity (@entities1) { 1.92 + if (exists $entities2{$entity}) { 1.93 + delete $entities2{$entity}; 1.94 + } else { 1.95 +# hack to ignore non-fatal region.properties differences 1.96 + if ($path !~ /chrome\/browser-region\/region\.properties$/ or 1.97 + ($entity !~ /browser\.search\.order\.[1-9]/ and 1.98 + $entity !~ /browser\.contentHandlers\.types\.[0-5]/ and 1.99 + $entity !~ /gecko\.handlerService\.schemes\./ and 1.100 + $entity !~ /gecko\.handlerService\.defaultHandlersVersion/)) { 1.101 + push @extra1, $entity; 1.102 + } 1.103 + } 1.104 + } 1.105 +# hack to ignore non-fatal region.properties differences 1.106 + if ($path =~ /chrome\/browser-region\/region\.properties$/) { 1.107 + foreach $entity (keys(%entities2)) { 1.108 + if ($entity =~ /browser\.search\.order\.[1-9]/ || 1.109 + $entity =~ /browser\.contentHandlers\.types\.[0-5]/ || 1.110 + $entity =~ /gecko\.handlerService\.schemes\./ || 1.111 + $entity =~ /gecko\.handlerService\.defaultHandlersVersion/) { 1.112 + delete $entities2{$entity}; 1.113 + } 1.114 + } 1.115 + } 1.116 + 1.117 + if (@extra1 or keys %entities2) { 1.118 + $failure = 1; 1.119 + print "Properties in $path don't match:\n"; 1.120 + if (@extra1) { 1.121 + print " In $gSource1: (add these to your localization)\n"; 1.122 + map { print " $_\n"; } @extra1; 1.123 + } 1.124 + 1.125 + if (keys %entities2) { 1.126 + print " In $gSource2: (remove these from your localization)\n"; 1.127 + map {print " $_\n"; } keys %entities2; 1.128 + } 1.129 + print "\n"; 1.130 + } 1.131 +} 1.132 + 1.133 +sub readDefines 1.134 +{ 1.135 + my ($file) = @_; 1.136 + 1.137 + open DEFS, "<$file" || die ("Couldn't open file $file"); 1.138 + 1.139 + local $/ = undef; 1.140 + my $contents = <DEFS>; 1.141 + close DEFS; 1.142 + 1.143 + return $contents =~ /#define\s+(\w+)/gm; 1.144 +} 1.145 + 1.146 +sub compareDefines 1.147 +{ 1.148 + my ($path) = @_; 1.149 + 1.150 + my @entities1 = readDefines("$gSourceDir1/$path"); 1.151 + my %entities2 = map { $_ => 1 } readDefines("$gSourceDir2/$path"); 1.152 + 1.153 + my @extra1; 1.154 + 1.155 + foreach my $entity (@entities1) { 1.156 + if (exists $entities2{$entity}) { 1.157 + delete $entities2{$entity}; 1.158 + } else { 1.159 + push @extra1, $entity; 1.160 + } 1.161 + } 1.162 + 1.163 + if (@extra1 or keys %entities2) { 1.164 + $failure = 1; 1.165 + print "Defines in $path don't match:\n"; 1.166 + if (@extra1) { 1.167 + print " In $gSource1: (add these to your localization)\n"; 1.168 + map { print " $_\n"; } @extra1; 1.169 + } 1.170 + 1.171 + if (keys %entities2) { 1.172 + print " In $gSource2: (remove these from your localization)\n"; 1.173 + map {print " $_\n"; } keys %entities2; 1.174 + } 1.175 + print "\n"; 1.176 + } 1.177 +} 1.178 + 1.179 +sub compareDir 1.180 +{ 1.181 + my ($path) = @_; 1.182 + 1.183 + my (@entries1, %entries2); 1.184 + 1.185 + opendir(DIR1, "$gSourceDir1/$path") || 1.186 + die ("Couldn't list $gSourceDir1/$path"); 1.187 + @entries1 = grep(!(/^(\.|CVS)/ || /~$/), readdir(DIR1)); 1.188 + closedir(DIR1); 1.189 + 1.190 + opendir(DIR2, "$gSourceDir2/$path") || 1.191 + die ("Couldn't list $gSourceDir2/$path"); 1.192 + %entries2 = map { $_ => 1 } grep(!(/^(\.|CVS)/ || /~$/), readdir(DIR2)); 1.193 + closedir(DIR2); 1.194 + 1.195 + foreach my $file (@entries1) { 1.196 + if (exists($entries2{$file})) { 1.197 + delete $entries2{$file}; 1.198 + 1.199 + if (-d "$gSourceDir1/$path/$file") { 1.200 + compareDir("$path/$file"); 1.201 + } else { 1.202 + if ($file =~ /\.dtd$/) { 1.203 + compareDTD("$path/$file"); 1.204 + } elsif ($file =~ /\.inc$/) { 1.205 + compareDefines("$path/$file"); 1.206 + } elsif ($file =~ /\.properties$/) { 1.207 + compareProperties("$path/$file"); 1.208 + } else { 1.209 + print "no comparison for $path/$file\n"; 1.210 + } 1.211 + } 1.212 + } else { 1.213 + push @gSource1Extra, "$path/$file"; 1.214 + } 1.215 + } 1.216 + 1.217 + foreach my $file (keys %entries2) { 1.218 + push @gSource2Extra, "$path/$file"; 1.219 + } 1.220 +} 1.221 + 1.222 +local ($gSource1, $gSource2) = @ARGV; 1.223 +($gSource1 && $gSource2) || die("Specify two directories or ZIP files"); 1.224 + 1.225 +my ($gSource1IsZIP, $gSource2IsZIP); 1.226 +local ($gSourceDir1, $gSourceDir2); 1.227 +local (@gSource1Extra, @gSource2Extra); 1.228 + 1.229 +if (-d $gSource1) { 1.230 + $gSource1IsZIP = 0; 1.231 + $gSourceDir1 = $gSource1; 1.232 +} else { 1.233 + $gSource1IsZIP = 1; 1.234 + $gSourceDir1 = "temp1"; 1.235 + unJAR($gSource1, $gSourceDir1); 1.236 +} 1.237 + 1.238 +if (-d $gSource2) { 1.239 + $gSource2IsZIP = 0; 1.240 + $gSourceDir2 = $gSource2; 1.241 +} else { 1.242 + $gSource2IsZIP = 1; 1.243 + $gSourceDir2 = "temp2"; 1.244 + unJAR($gSource2, $gSourceDir2); 1.245 +} 1.246 + 1.247 +compareDir("."); 1.248 + 1.249 +if (@gSource1Extra) { 1.250 + print "Files in $gSource1 not in $gSource2:\n"; 1.251 + map { print " $_\n"; } @gSource1Extra; 1.252 + print "\n"; 1.253 +} 1.254 + 1.255 +if (@gSource2Extra) { 1.256 + print "Files in $gSource2 not in $gSource1:\n"; 1.257 + map { print " $_\n"; } @gSource2Extra; 1.258 + print "\n"; 1.259 +} 1.260 + 1.261 +$gSource1IsZIP && system("rm -rf $gSourceDir1"); 1.262 +$gSource2IsZIP && system("rm -rf $gSourceDir2"); 1.263 + 1.264 +exit $failure;