source: osm/applications/editors/josm/plugins/photoadjust/i18n/i18nlib.pm@ 33512

Last change on this file since 33512 was 31960, checked in by holgermappt, 9 years ago

Added scripts that read the JOSM *.lang language files.

File size: 6.4 KB
Line 
1### i18nlib.pm - Perl library based on i18n/i18n.pl.
2
3use utf8;
4binmode STDERR, ":encoding(utf8)";
5use Term::ReadKey;
6use Encode;
7
8my $waswarn = 0;
9my $maxcount = 0;
10
11sub loadfiles($@)
12{
13 my $desc;
14 my $all;
15 my ($lang,@files) = @_;
16 foreach my $file (@files)
17 {
18 die "Could not open file $file." if(!open FILE,"<:utf8",$file);
19 my $linenum = 0;
20
21 my $cnt = -1; # don't count translators info
22 if($file =~ /\/(.._..(@.+)?)\.po$/ || $file =~ /\/(...?(@.+)?)\.po$/)
23 {
24 my $l = $1;
25 ++$lang->{$l};
26 my %postate = (last => "", type => "");
27 my $linenum = 0;
28 print "Reading file $file\n";
29 while(<FILE>)
30 {
31 ++$linenum;
32 my $fn = "$file:$linenum";
33 chomp;
34 if($_ =~ /^#/ || !$_)
35 {
36 checkpo(\%postate, \%all, $l, "line $linenum in $file", $keys, 1);
37 $postate{fuzzy} = 1 if ($_ =~ /fuzzy/);
38 }
39 elsif($_ =~ /^"(.*)"$/) {$postate{last} .= $1;}
40 elsif($_ =~ /^(msg.+) "(.*)"$/)
41 {
42 my ($n, $d) = ($1, $2);
43 ++$cnt if $n eq "msgid";
44 my $new = !${postate}{fuzzy} && (($n eq "msgid" && $postate{type} ne "msgctxt") || ($n eq "msgctxt"));
45 checkpo(\%postate, \%all, $l, "line $linenum in $file", $keys, $new);
46 $postate{last} = $d;
47 $postate{type} = $n;
48 $postate{src} = $fn if $new;
49 }
50 else
51 {
52 die "Strange line $linenum in $file: $_.";
53 }
54 }
55 checkpo(\%postate, \%all, $l, "line $linenum in $file", $keys, 1);
56 }
57 else
58 {
59 die "File format not supported for file $file.";
60 }
61 $maxcount = $cnt if $cnt > $maxcount;
62 close(FILE);
63 }
64 return %all;
65}
66
67my $alwayspo = 0;
68my $alwaysup = 0;
69my $noask = 0;
70my $conflicts;
71sub copystring($$$$$$$)
72{
73 my ($data, $en, $l, $str, $txt, $context, $ispo) = @_;
74
75 $en = "___${context}___$en" if $context;
76
77 if(exists($data->{$en}{$l}) && $data->{$en}{$l} ne $str)
78 {
79 return if !$str;
80 if($l =~ /^_/)
81 {
82 $data->{$en}{$l} .= ";$str" if !($data->{$en}{$l} =~ /$str/);
83 }
84 elsif(!$data->{$en}{$l})
85 {
86 $data->{$en}{$l} = $str;
87 }
88 else
89 {
90
91 my $f = $data->{$en}{_file} || "";
92 $f = ($f ? "$f;".$data->{$en}{"_src.$l"} : $data->{$en}{"_src.$l"}) if $data->{$en}{"_src.$l"};
93 my $isotherpo = ($f =~ /\.po\:/);
94 my $pomode = ($ispo && !$isotherpo) || (!$ispo && $isotherpo);
95
96 my $mis = "String mismatch for '$en' **$str** ($txt) != **$data->{$en}{$l}** ($f)\n";
97 my $replace = 0;
98
99 if(($conflicts{$l}{$str} || "") eq $data->{$en}{$l}) {}
100 elsif($pomode && $alwaysup) { $replace=$isotherpo; }
101 elsif($pomode && $alwayspo) { $replace=$ispo; }
102 elsif($noask) { print $mis; ++$waswarn; }
103 else
104 {
105 ReadMode 4; # Turn off controls keys
106 my $arg = "(l)eft, (r)ight";
107 $arg .= ", (p)o, (u)pstream[ts/mat], all p(o), all up(s)tream" if $pomode;
108 $arg .= ", e(x)it: ";
109 print "$mis$arg";
110 while((my $c = getc()))
111 {
112 if($c eq "l") { $replace=1; }
113 elsif($c eq "r") {}
114 elsif($c eq "p" && $pomode) { $replace=$ispo; }
115 elsif($c eq "u" && $pomode) { $replace=$isotherpo; }
116 elsif($c eq "o" && $pomode) { $alwayspo = 1; $replace=$ispo; }
117 elsif($c eq "s" && $pomode) { $alwaysup = 1; $replace=$isotherpo; }
118 elsif($c eq "x") { $noask = 1; ++$waswarn; }
119 else { print "\n$arg"; next; }
120 last;
121 }
122 print("\n");
123 ReadMode 0; # Turn on controls keys
124 }
125 if(!$noask)
126 {
127 if($replace)
128 {
129 $data->{$en}{$l} = $str;
130 $conflicts{$l}{$data->{$en}{$l}} = $str;
131 }
132 else
133 {
134 $conflicts{$l}{$str} = $data->{$en}{$l};
135 }
136 }
137 }
138 }
139 else
140 {
141 $data->{$en}{$l} = $str;
142 }
143}
144
145sub checkpo($$$$$$)
146{
147 my ($postate, $data, $l, $txt, $keys, $new) = @_;
148
149 if($postate->{type} eq "msgid") {$postate->{msgid} = $postate->{last};}
150 elsif($postate->{type} eq "msgid_plural") {$postate->{msgid_1} = $postate->{last};}
151 elsif($postate->{type} =~ /^msgstr(\[0\])?$/) {$postate->{msgstr} = $postate->{last};}
152 elsif($postate->{type} =~ /^msgstr\[(.+)\]$/) {$postate->{"msgstr_$1"} = $postate->{last};}
153 elsif($postate->{type} eq "msgctxt") {$postate->{context} = $postate->{last};}
154 elsif($postate->{type}) { die "Strange type $postate->{type} found\n" }
155
156 if($new)
157 {
158 if((!$postate->{fuzzy}) && $postate->{msgstr} && $postate->{msgid})
159 {
160 copystring($data, $postate->{msgid}, $l, $postate->{msgstr},$txt,$postate->{context}, 1);
161 for($i = 1; exists($postate->{"msgstr_$i"}); ++$i)
162 { copystring($data, $postate->{msgid}, "$l.$i", $postate->{"msgstr_$i"},$txt,$postate->{context}, 1); }
163 if($postate->{msgid_1})
164 { copystring($data, $postate->{msgid}, "en.1", $postate->{msgid_1},$txt,$postate->{context}, 1); }
165 copystring($data, $postate->{msgid}, "_src.$l", $postate->{src},$txt,$postate->{context}, 1);
166 }
167 elsif($postate->{msgstr} && !$postate->{msgid})
168 {
169 my %k = ($postate->{msgstr} =~ /(.+?): +(.+?)\\n/g);
170 # take the first one!
171 for $a (sort keys %k)
172 {
173 $keys->{$l}{$a} = $k{$a} if !$keys->{$l}{$a};
174 }
175 }
176 foreach my $k (keys %{$postate})
177 {
178 delete $postate->{$k};
179 }
180 $postate->{type} = $postate->{last} = "";
181 }
182}
183
184### Load a JOSM language file. The format is two byte string length, then the
185### string. Length 0x0000 means the string was not in the PO file, i.e. there
186### is no translation (there are no empty strings). Length 0xfffe (65534)
187### means the string is the same as the original string. Length 0xffff ends
188### the string list.
189###
190### Args:
191### filename (str): Path to language file.
192###
193### Returns:
194### array: List of decoded strings.
195sub loadLangFile {
196 my ($filename) = @_;
197 my @strings;
198 open(my $langFd, $filename) or die "Cannot open file $filename: $!";
199 binmode($langFd);
200 my $buffer;
201 my $length;
202 while (1) {
203 read($langFd, $buffer, 2);
204 $length = unpack("n", $buffer);
205 die "Unable to read string length" unless ($buffer);
206 if ($length == 0) {
207 push(@strings, "");
208 }
209 elsif ($length == 0xfffe) {
210 push(@strings, "(see original string)");
211 }
212 elsif ($length == 0xffff) {
213 last;
214 }
215 else {
216 read($langFd, $buffer, $length);
217 push(@strings, $buffer);
218 }
219 }
220 close($langFd);
221 return @strings;
222}
223
2241;
Note: See TracBrowser for help on using the repository browser.