source: osm/applications/editors/josm/i18n/i18n.pl@ 19319

Last change on this file since 19319 was 19319, checked in by stoecker, 15 years ago

i18n update

  • Property svn:executable set to *
File size: 7.6 KB
Line 
1#! /usr/bin/perl -w
2
3use utf8;
4use encoding "utf8";
5use Term::ReadKey;
6use Encode;
7
8my $waswarn = 0;
9
10main();
11
12sub getdate
13{
14 my @t=gmtime();
15 return sprintf("%04d-%02d-%02d %02d:%02d+0000",
16 1900+$t[5],$t[4]+1,$t[3],$t[2],$t[1]);
17}
18
19sub loadfiles($@)
20{
21 my $desc;
22 my $all;
23 my ($lang,@files) = @_;
24 foreach my $file (@files)
25 {
26 die "Could not open file $file." if(!open FILE,"<:utf8",$file);
27 my $linenum = 0;
28
29 if($file =~ /\/(.._..)\.po$/ || $file =~ /\/(..)\.po$/)
30 {
31 my $l = $1;
32 ++$lang->{$l};
33 my %postate = (last => "", type => "");
34 my $linenum = 0;
35 print "Reading file $file\n";
36 while(<FILE>)
37 {
38 ++$linenum;
39 my $fn = "$file:$linenum";
40 chomp;
41 if($_ =~ /^#/ || !$_)
42 {
43 checkpo(\%postate, \%all, $l, "line $linenum in $file", $keys, 1);
44 $postate{fuzzy} = 1 if ($_ =~ /fuzzy/);
45 }
46 elsif($_ =~ /^"(.*)"$/) {$postate{last} .= $1;}
47 elsif($_ =~ /^(msg.+) "(.*)"$/)
48 {
49 my ($n, $d) = ($1, $2);
50 my $new = ($n eq "msgid" && $postate{type} ne "msgctxt") || ($n eq "msgctxt");
51 checkpo(\%postate, \%all, $l, "line $linenum in $file", $keys, $new);
52 $postate{last} = $d;
53 $postate{type} = $n;
54 $postate{src} = $fn if $new;
55 }
56 else
57 {
58 die "Strange line $linenum in $file: $_.";
59 }
60 }
61 checkpo(\%postate, \%all, $l, "line $linenum in $file", $keys, 1);
62 }
63 else
64 {
65 die "File format not supported for file $file.";
66 }
67 close(FILE);
68 }
69 return %all;
70}
71
72my $alwayspo = 0;
73my $alwaysup = 0;
74my $noask = 0;
75my $conflicts;
76sub copystring($$$$$$$)
77{
78 my ($data, $en, $l, $str, $txt, $context, $ispo) = @_;
79
80 $en = "___${context}___$en" if $context;
81
82 if(exists($data->{$en}{$l}) && $data->{$en}{$l} ne $str)
83 {
84 return if !$str;
85 if($l =~ /^_/)
86 {
87 $data->{$en}{$l} .= ";$str" if !($data->{$en}{$l} =~ /$str/);
88 }
89 elsif(!$data->{$en}{$l})
90 {
91 $data->{$en}{$l} = $str;
92 }
93 else
94 {
95
96 my $f = $data->{$en}{_file} || "";
97 $f = ($f ? "$f;".$data->{$en}{"_src.$l"} : $data->{$en}{"_src.$l"}) if $data->{$en}{"_src.$l"};
98 my $isotherpo = ($f =~ /\.po\:/);
99 my $pomode = ($ispo && !$isotherpo) || (!$ispo && $isotherpo);
100
101 my $mis = "String mismatch for '$en' **$str** ($txt) != **$data->{$en}{$l}** ($f)\n";
102 my $replace = 0;
103
104 if(($conflicts{$l}{$str} || "") eq $data->{$en}{$l}) {}
105 elsif($pomode && $alwaysup) { $replace=$isotherpo; }
106 elsif($pomode && $alwayspo) { $replace=$ispo; }
107 elsif($noask) { print $mis; ++$waswarn; }
108 else
109 {
110 ReadMode 4; # Turn off controls keys
111 my $arg = "(l)eft, (r)ight";
112 $arg .= ", (p)o, (u)pstream[ts/mat], all p(o), all up(s)tream" if $pomode;
113 $arg .= ", e(x)it: ";
114 print "$mis$arg";
115 while((my $c = getc()))
116 {
117 if($c eq "l") { $replace=1; }
118 elsif($c eq "r") {}
119 elsif($c eq "p" && $pomode) { $replace=$ispo; }
120 elsif($c eq "u" && $pomode) { $replace=$isotherpo; }
121 elsif($c eq "o" && $pomode) { $alwayspo = 1; $replace=$ispo; }
122 elsif($c eq "s" && $pomode) { $alwaysup = 1; $replace=$isotherpo; }
123 elsif($c eq "x") { $noask = 1; ++$waswarn; }
124 else { print "\n$arg"; next; }
125 last;
126 }
127 print("\n");
128 ReadMode 0; # Turn on controls keys
129 }
130 if(!$noask)
131 {
132 if($replace)
133 {
134 $data->{$en}{$l} = $str;
135 $conflicts{$l}{$data->{$en}{$l}} = $str;
136 }
137 else
138 {
139 $conflicts{$l}{$str} = $data->{$en}{$l};
140 }
141 }
142 }
143 }
144 else
145 {
146 $data->{$en}{$l} = $str;
147 }
148}
149
150sub checkpo($$$$$$)
151{
152 my ($postate, $data, $l, $txt, $keys, $new) = @_;
153
154 if($postate->{type} eq "msgid") {$postate->{msgid} = $postate->{last};}
155 elsif($postate->{type} eq "msgid_plural") {$postate->{msgid_1} = $postate->{last};}
156 elsif($postate->{type} =~ /^msgstr(\[0\])?$/) {$postate->{msgstr} = $postate->{last};}
157 elsif($postate->{type} =~ /^msgstr\[(.+)\]$/) {$postate->{"msgstr_$1"} = $postate->{last};}
158 elsif($postate->{type} eq "msgctxt") {$postate->{context} = $postate->{last};}
159 elsif($postate->{type}) { die "Strange type $postate->{type} found\n" }
160
161 if($new)
162 {
163 if((!$postate->{fuzzy}) && $postate->{msgstr} && $postate->{msgid})
164 {
165 copystring($data, $postate->{msgid}, $l, $postate->{msgstr},$txt,$postate->{context}, 1);
166 for($i = 1; exists($postate->{"msgstr_$i"}); ++$i)
167 { copystring($data, $postate->{msgid}, "$l.$i", $postate->{"msgstr_$i"},$txt,$postate->{context}, 1); }
168 if($postate->{msgid_1})
169 { copystring($data, $postate->{msgid}, "en.1", $postate->{msgid_1},$txt,$postate->{context}, 1); }
170 copystring($data, $postate->{msgid}, "_src.$l", $postate->{src},$txt,$postate->{context}, 1);
171 }
172 elsif($postate->{msgstr} && !$postate->{msgid})
173 {
174 my %k = ($postate->{msgstr} =~ /(.+?): +(.+?)\\n/g);
175 # take the first one!
176 for $a (sort keys %k)
177 {
178 $keys->{$l}{$a} = $k{$a} if !$keys->{$l}{$a};
179 }
180 }
181 foreach my $k (keys %{$postate})
182 {
183 delete $postate->{$k};
184 }
185 $postate->{type} = $postate->{last} = "";
186 }
187}
188
189sub createlang($@)
190{
191 my ($data, @files) = @_;
192 foreach my $file (@files)
193 {
194 my $la;
195 if($file =~ /[-_](.._..)\.lang$/ || $file =~ /^(?:.*\/)?(.._..)\.lang$/ ||
196 $file =~ /[-_](...?)\.lang$/ || $file =~ /^(?:.*\/)?(..)\.lang$/)
197 {
198 print "Creating file $file\n";
199 $la = $1;
200 }
201 else
202 {
203 die "Language for file $file unknown.";
204 }
205 die "Could not open outfile $file\n" if !open FILE,">:raw",$file;
206
207 foreach my $en (sort keys %{$data})
208 {
209 next if $data->{$en}{"en.1"};
210 my $val;
211 if($la eq "en")
212 {
213 $val = $en;
214 $val =~ s/^___(.*)___/_:$1\n/;
215 }
216 else
217 {
218 my $ennoctx = $en;
219 $ennoctx =~ s/^___(.*)___//;
220 $val = (exists($data->{$en}{$la})) ? $data->{$en}{$la} : "";
221 $val = "" if($ennoctx eq $val);
222 }
223 $val = encode("utf8", $val);
224 print FILE pack("n",length($val)).$val;
225 }
226 print FILE pack "n",0xFFFF;
227 foreach my $en (sort keys %{$data})
228 {
229 next if !$data->{$en}{"en.1"};
230 my $num;
231 for($num = 1; exists($data->{$en}{"$la.$num"}); ++$num)
232 { }
233 my $val;
234 if($la eq "en")
235 {
236 $val = $en;
237 $val =~ s/^___(.*)___/_:$1\n/;
238 }
239 else
240 {
241 $val = (exists($data->{$en}{$la})) ? $data->{$en}{$la} : "";
242 --$num if(!$val);
243 if($num == 2)
244 {
245 my $ennoctx = $en;
246 $ennoctx =~ s/^___(.*)___//;
247 $num = 0 if $val eq $ennoctx && $data->{$en}{"$la.1"} eq $data->{$en}{"en.1"};
248 }
249 }
250
251 print FILE pack "C",$num;
252 if($num)
253 {
254 $val = encode("utf8", $val);
255 print FILE pack("n",length($val)).$val;
256 for($num = 1; exists($data->{$en}{"$la.$num"}); ++$num)
257 {
258 $val = encode("utf8", $data->{$en}{"$la.$num"});
259 print FILE pack("n",length($val)).$val;
260 }
261 }
262 }
263 close FILE;
264 }
265}
266
267sub main
268{
269 my %lang;
270 my @po;
271 my $basename = shift @ARGV;
272 foreach my $arg (@ARGV)
273 {
274 foreach my $f (glob $arg)
275 {
276 if($f =~ /\*/) { printf "Skipping $f\n"; }
277 elsif($f =~ /\.po$/) { push(@po, $f); }
278 else { die "unknown file extension."; }
279 }
280 }
281 my %data = loadfiles(\%lang,@po);
282 my @clang;
283 foreach my $la (sort keys %lang)
284 {
285 push(@clang, "${basename}$la.lang");
286 }
287 push(@clang, "${basename}en.lang");
288 die "There have been warning. No output.\n" if $waswarn;
289
290 createlang(\%data, @clang);
291}
Note: See TracBrowser for help on using the repository browser.