1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
#!/usr/bin/perl -- -*-cperl-*-
## Set and update selected translation strings from the Postgres source
## This only needs to be run by developers of check_postgres, and only rarely
## Usage: $0 --pgsrc=path to top of Postgres source tree
##
## Greg Sabino Mullane <greg@turnstep.com>
## BSD licensed
use 5.008;
use strict;
use warnings;
use utf8;
use Getopt::Long qw/GetOptions/;
use Data::Dumper qw/Dumper/;
use vars qw/ %opt %po /;
my $USAGE = "$0 --pgsrc=path";
die $USAGE unless
GetOptions(
\%opt,
'pgsrc=s',
'verbose|v+',
)
and $opt{pgsrc}
and ! @ARGV;
our $VERBOSE = $opt{verbose} || 0;
my $basedir = $opt{pgsrc};
-d $basedir or die qq{Could not find directory "$basedir"\n};
## There is no "en.po", so we force an entry here
%po = ('en' => {});
process_po_files($basedir, 'backend/po', \%po);
process_po_files($basedir, 'bin/pg_controldata/po', \%po);
my $file = 'check_postgres.pl';
open my $fh, '+<', $file or die qq{Could not open "$file": $!\n};
my ($start,$lang,$quote,$comment,%msg,@lines) = (0,'');
while (<$fh>) {
push @lines, $_;
}
## List of translatable messages
my %trans;
for my $line (@lines) {
## Do nothing until we are at the start of the translations
if (!$start) {
if ($line =~ /^our \%msg/) {
$start = 1;
}
next;
}
## Start of a language section
if ($line =~ /^'(\w+)' => \{/) {
$lang = $1;
$msg{$lang} = {};
next;
}
## A message
if ($line =~ /^(\s*)'([\w\-]+)'\s*=> (qq?)\{(.+?)}[,.](.*)/) {
my ($space,$msg,$quote,$value,$comment) = (length $1 ? 1 : 0, $2, $3, $4, $5);
$msg{$lang}{$msg} = [$space,$value,$quote,$comment];
if ($lang eq 'en' and $msg =~ /\-po\d*$/) {
$trans{$msg} = $value;
}
next;
}
## End of the language section
last if $line =~ /^\);/o;
}
## Plug in any translatable strings we find
for my $ll (sort keys %po) {
next if $ll eq 'en';
for my $mm (sort keys %{$po{$ll}}) {
my $nn = $po{$ll}{$mm};
for my $tr (sort keys %trans) {
my $val = $trans{$tr};
if ($mm =~ /^$val/) {
$nn =~ s/(.+?)\s*\%.*/$1/; # remove everything from % on
print "$tr/$ll: $val -> $nn\n";
length $nn and $msg{$ll}{$tr} = [1,$nn,'q',''];
}
}
}
}
seek $fh, 0, 0;
$start = 0;
## Add in all lines up until the translation section:
for my $line (@lines) {
print {$fh} $line;
last if $line =~ /^our \%msg/;
}
my %all_langs = map { $_ => 1} (keys %msg, keys %po);
## Add in the translated sections, with new info as needed
for my $m (sort {
## English goes first, as the base class
return -1 if $a eq 'en'; return 1 if $b eq 'en';
## Then the fully translated languages
return -1 if $a eq 'es'; return 1 if $b eq 'es';
return -1 if $a eq 'fr'; return 1 if $b eq 'fr';
## Everything else is alphabetical
return $a cmp $b
} keys %all_langs) {
print {$fh} qq!'$m' => {\n!;
my $size = 14; # length of "checkpoint-po" + 1
for my $msg (keys %{$msg{$m}}) {
$size = length($msg) if length($msg) > $size;
}
for my $mm (sort keys %{$msg{$m}}) {
printf {$fh} "%s%-*s=> %s{%s},%s\n",
$msg{$m}{$mm}->[0] ? " " : '',
2+$size,
qq{'$mm'},
$msg{$m}{$mm}->[2],
$msg{$m}{$mm}->[1],
$msg{$m}{$mm}->[3];
}
print {$fh} "},\n";
}
## Add everything after the translations
$start = 0;
for my $line (@lines) {
if (!$start) {
if ($line =~ /^our \%msg/) {
$start = 1;
}
next;
}
if ($start == 1) {
next if $line !~ /^\);/o;
$start = 2;
}
print {$fh} $line;
}
truncate $fh, tell $fh;
close $fh or warn qq{Could not close "$file": $!\n};
exit;
sub process_po_files {
my ($dir, $path, $panda) = @_;
my $podir = ($dir =~ /^src/) ? "$dir/$path" : "$basedir/src/$path";
opendir my $dh, $podir or die qq{Could not find directory "$podir"\n};
my @files = grep { /po$/ } readdir $dh;
closedir $dh or warn qq{Could not closedir $podir\n};
for my $file (sort @files) {
(my $lang = $file) =~ s/\.po//;
my $pofile = "$podir/$file";
print "Processing $pofile\n";
open my $fh, '<', $pofile or die qq{Could not open "$pofile": $!\n};
1 while <$fh> !~ /^#,/o;
my $id = '';
my $isid = 1;
while (<$fh>) {
if (/^msgid "(.*)"/) {
$id = $1;
$isid = 1;
}
elsif (/^msgstr "(.*)"/) {
$panda->{$lang}{$id} = $1;
$isid = 0;
}
elsif (/^"(.*)"/) {
$isid ? ($id .= $1) : ($panda->{$lang}{$id} .= $1);
}
}
close $fh or warn qq{Could not close "$pofile" $!\n};
}
return;
} ## end of process_po_files
exit;
|