source: subversion/applications/editors/josm/i18n/i18n.pl @ 19334

Last change on this file since 19334 was 19334, checked in by Dirk Stoecker, 10 years ago

i18n update

  • Property svn:executable set to *
File size: 7.7 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 = !${postate}{fuzzy} && (($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.