#! /usr/bin/perl # Prerequisites: # GNU make (envar GMAKE) # msgmerge (envar MSGMERGE) # msgfmt (envar MSGFMT) # Source tree updated and distprep'ed # Input files specified as arguments # Output directory specified by -o option # Produces various output on stderr use strict; use warnings; use Getopt::Std; use File::Basename; my %opts; getopts('o:v:', \%opts) or die; my $outdir = $opts{'o'} || '.'; my $version = $opts{'v'}; my $gmake = $ENV{'GMAKE'} || 'gmake'; my $msgmerge = $ENV{'MSGMERGE'} || 'msgmerge'; my $msgfmt = $ENV{'MSGFMT'} || 'msgfmt'; # order as in the GNU gettext manual my %plural_rules = ( 'ja' => 'nplurals=1; plural=0;', 'en' => 'nplurals=2; plural=n != 1;', 'fr' => 'nplurals=2; plural=n>1;', 'ro' => 'nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;', 'ru' => 'nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;', 'cs' => 'nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;', 'pl' => 'nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;', 'sl' => 'nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;', ); my %plural_forms = ( 'af' => 'en', 'cs' => 'cs', 'de' => 'en', 'el' => 'en', 'es' => 'en', 'fa' => 'ja', 'fr' => 'fr', 'he' => 'en', 'hr' => 'ru', 'hu' => 'en', 'id' => 'en', 'it' => 'en', 'ja' => 'ja', 'ka' => 'en', 'ko' => 'ja', 'nb' => 'en', 'nl' => 'en', 'pl' => 'pl', 'pt_BR' => 'fr', 'ro' => 'ro', 'ru' => 'ru', 'sk' => 'cs', 'sl' => 'sl', 'sv' => 'en', 'ta' => 'en', 'tr' => 'ja', 'uk' => 'ru', 'vi' => 'ja', 'zh_CN' => 'ja', 'zh_TW' => 'ja', ); my @all_languages; foreach (@ARGV) { my $dirname = dirname($_); my @languages; @languages = map { m!/([^/]+)\.po$! && $1 } glob("$dirname/po/*.po"); @all_languages = (@all_languages, @languages); } my %saw; undef %saw; @saw{@all_languages} = (); @all_languages = sort keys %saw; foreach (@ARGV) { my $dirname = dirname($_); open my $nlsmk, '<', $_ or die "could not open $_: $!\n"; my $catalogname; while (<$nlsmk>) { /^CATALOG_NAME\s*:?=\s*(\S+)\s*$/ and $catalogname = $1; } close $nlsmk; system("$gmake -C $dirname init-po") == 0 or die "$!\n"; system("cp -f $dirname/po/$catalogname.pot $outdir/$catalogname.pot") == 0 or die "$!\n"; my $avail_languages = join(' ', map { m!/([^/]+)\.po$! && $1 } glob("$dirname/po/*.po")); print STDERR "* $catalogname\n"; foreach my $lang (@all_languages) { print STDERR "$lang: "; system("rm -f $outdir/$catalogname-$lang.po.err"); if (-f "$dirname/po/$lang.po") { # This is what we use to calculate the displayed percentages. if (system("$msgmerge $dirname/po/$lang.po $dirname/po/$catalogname.pot -o $dirname/po/$lang.po.mrg") != 0) { system( "$msgmerge $dirname/po/$lang.po $dirname/po/$catalogname.pot -o $dirname/po/$lang.po.mrg 2>>$outdir/$catalogname-$lang.po.err 1>/dev/null" ); } if ( system("$msgfmt -o /dev/null -v -c $dirname/po/$lang.po >/dev/null 2>&1") != 0 or system("$msgfmt -o /dev/null -v -c $dirname/po/$lang.po 2>&1 | grep -q 'warning'") == 0) { system( "$msgfmt -o /dev/null -v -c $dirname/po/$lang.po 2>>$outdir/$catalogname-$lang.po.err 1>/dev/null"); } if (system("grep -q -IU ' ' $dirname/po/$lang.po") == 0) { system("echo '$dirname/po/$lang.po contains DOS line endings' >>$outdir/$catalogname-$lang.po.err"); } } # This is what we offer for download. if (system("$gmake -C $dirname po/$lang.po.new AVAIL_LANGUAGES='$avail_languages'") != 0) { system( "$gmake -C $dirname po/$lang.po.new AVAIL_LANGUAGES='$avail_languages' 2>>$outdir/$catalogname-$lang.po.err 1>/dev/null" ); } if (-f "$dirname/po/$lang.po.mrg" && !-f "$dirname/po/$lang.po.new") { system("cp $dirname/po/$lang.po.mrg $outdir/$catalogname-$lang.po"); system("cp $dirname/po/$lang.po.mrg $outdir/$catalogname-$lang.po.old"); } if (-f "$dirname/po/$lang.po.mrg" && -f "$dirname/po/$lang.po.new") { system("cp $dirname/po/$lang.po.new $outdir/$catalogname-$lang.po"); system("cp $dirname/po/$lang.po.mrg $outdir/$catalogname-$lang.po.old"); } if (!-f "$dirname/po/$lang.po.mrg" && -f "$dirname/po/$lang.po.new") { my $pe = $plural_rules{ $plural_forms{$lang} } or die "missing plural support for language \"$lang\"\n"; $pe =~ s/\&/\\\&/g; system( "cat $dirname/po/$lang.po.new | sed '/Plural-Forms:/s/nplurals=INTEGER; plural=EXPRESSION;/$pe/' >$outdir/$catalogname-$lang.po" ); } if ( system("$msgfmt -o /dev/null -v -c $outdir/$catalogname-$lang.po >/dev/null 2>&1") != 0 or system("$msgfmt -o /dev/null -v -c $outdir/$catalogname-$lang.po >/dev/null 2>&1 | grep -q 'warning'") == 0) { system( "$msgfmt -o /dev/null -v -c $outdir/$catalogname-$lang.po 2>>$outdir/$catalogname-$lang.po.err 1>/dev/null" ); } } # foreach $lang } # foreach @ARGV