Index: po4a =================================================================== RCS file: /cvsroot/po4a/po4a/po4a,v retrieving revision 1.52 diff -u -r1.52 po4a --- po4a 26 Feb 2006 20:19:44 -0000 1.52 +++ po4a 26 Feb 2006 22:09:32 -0000 @@ -289,6 +289,7 @@ use Pod::Usage qw(pod2usage); use File::Temp; +use File::Basename; use File::Copy; Locale::Po4a::Common::textdomain('po4a'); @@ -439,6 +440,36 @@ # Argument check $po4a_opts{"help"} && pod2usage (-verbose => 1, -exitval => 0); +sub run_cmd { + my $cmd = shift; + print $cmd."\n" if $po4a_opts{"debug"}; + + my $out = qx/$cmd 2>&1/; + print $out if ($po4a_opts{"verbose"}); + unless ($? == 0) { + my $err = ""; + if ($? == -1) { + $err = sprintf(gettext("failed to execute '%s': %s."), + $cmd, $!); + } elsif ($? & 127) { + if ($? & 128) { + $err = sprintf(gettext("'%s' died with signal %d, ". + "with coredump."), + $cmd, $? & 127); + } else { + $err = sprintf(gettext("'%s' died with signal %d, ". + "without coredump."), + $cmd, $? & 127); + } + } else { + $err = sprintf(gettext("'%s' exited with value %d."), + $cmd, $? >> 8); + } + + die wrap_msg(gettext("Error: %s"), $err); + } +} + my $config_file= shift(@ARGV) || pod2usage(); # Check file existence -e $config_file || die wrap_msg(gettext("File %s does not exist."), $config_file); @@ -570,8 +601,24 @@ die wrap_msg(gettext("po4a_paths not declared. Dunno where to find the pot and po files")) unless (length $pot_filename); +my %splitted_po; # po_files: '$lang','$master' => '$path' +my %splitted_pot; # pot_files: '$master' => '$path' + # make a big pot my $update_pot_file = 0; +if ($pot_filename =~ m/\$master/) { + print "Splitted mode, creating a temporary POT.\n" + if $po4a_opts{"verbose"}; + foreach my $master (keys %document) { + my $m = basename $master; + my $master_pot = $pot_filename; + $master_pot =~ s/\$master/$m/g; + $splitted_pot{$master} = $master_pot; + } + # The POT needs to be generated anyway. + $update_pot_file = 1; + $po4a_opts{"split"} = 1; +} else { if (-e $pot_filename) { my $modtime = (stat $pot_filename)[9]; # The POT needs to be re-generated if a master document is more recent @@ -600,6 +647,7 @@ if $po4a_opts{"verbose"}; $update_pot_file = 1; } +} my $potfile=Locale::Po4a::Po->new(); if ($update_pot_file) { @@ -625,11 +673,22 @@ 'file_in_charset' => $file_opts{"mastchar"}); $potfile = $doc->getpoout(); } + if ($po4a_opts{"split"}) { + (undef,$pot_filename)=File::Temp->tempfile("po4aXXXX", + DIR => "/tmp", + SUFFIX => ".pot", + OPEN => 0, + UNLINK => 0) + or die wrap_msg(gettext("Can't create a temporary pot file: %s"), + $!); + $potfile->write($pot_filename); + } else { if ($po4a_opts{"force"}) { $potfile->write($pot_filename); } else { $potfile->write_if_needed($pot_filename); } + } print wrap_msg(gettext(" (%d entries)"), $potfile->count_entries()) unless ($po4a_opts{"quiet"}); @@ -637,107 +696,72 @@ $potfile->read($pot_filename); } +if ($po4a_opts{"split"}) { + # Generate a .pot for each document + foreach my $master (keys %document) { + my $tmp_file; + # Create a temporary POT, and check if the old one needs to be + # updated (unless --force was specified). + unless ($po4a_opts{"force"}) { + (undef,$tmp_file)=File::Temp->tempfile("po4aXXXX", + DIR => "/tmp", + SUFFIX => ".pot", + OPEN => 0, + UNLINK => 0) + or die wrap_msg(gettext("Can't create a temporary pot file: %s"), + $!); + } + + my $cmd = "msggrep -N '$master' -o ". + ($po4a_opts{"force"}?$splitted_pot{$master}:$tmp_file). + " $pot_filename"; + run_cmd($cmd); + + unless ($po4a_opts{"force"}) { + Locale::Po4a::Po::move_po_if_needed($tmp_file, + $splitted_pot{$master}); + } + } + # Generate a complete .po + foreach my $lang (sort keys %po_filename) { + my $tmp_bigpo; + (undef,$tmp_bigpo)=File::Temp->tempfile("po4aXXXX", + DIR => "/tmp", + SUFFIX => "-$lang.po", + OPEN => 0, + UNLINK => 0) + or die wrap_msg(gettext("Can't create a temporary po file: %s"), + $!); + my $cmd_cat = ""; + foreach my $master (keys %document) { + my $m = basename $master; + my $master_po = $po_filename{$lang}; + $master_po =~ s/\$master/$m/g; + if (-e "$master_po") { + $cmd_cat .= " $master_po"; + } + $splitted_po{$lang}{$master} = $master_po; + } + if (length $cmd_cat) { + $cmd_cat = "msgcat -o $tmp_bigpo $cmd_cat"; + run_cmd($cmd_cat); + } + # We do not need to keep the original name with $master + $po_filename{$lang} = $tmp_bigpo; + } +} + # update all po files my $lang; foreach $lang (sort keys %po_filename) { if (-e $po_filename{$lang}) { print wrap_msg(gettext("Updating %s:")." ", $po_filename{$lang}) if ($po4a_opts{"verbose"}); - if ($po4a_opts{"split"}) { - my ($pot_filename,$po_filename,$bigpo_filename); - (undef,$pot_filename)=File::Temp->tempfile("po4aXXXX", - DIR => "/tmp", - SUFFIX => ".pot", - OPEN => 0, - UNLINK => 0) - or die wrap_msg(gettext("Can't create a temporary pot file: %s"), $!); - (undef,$po_filename)=File::Temp->tempfile("po4aXXXX", - DIR => "/tmp", - SUFFIX => ".po", - OPEN => 0, - UNLINK => 0) - or die wrap_msg(gettext("Can't create a temporary po file: %s"), $!); - my ($poorig,$pores)=(Locale::Po4a::Po->new(),Locale::Po4a::Po->new()); - $poorig->read($po_filename{$lang}); - - foreach my $master (sort keys %document) { - my $pot=Locale::Po4a::Po->new(); - my $po=Locale::Po4a::Po->new(); - print " $master:" unless ($po4a_opts{"quiet"}); - print "(pot)" unless ($po4a_opts{"quiet"}); - $pot=$potfile->filter("(reference='\Q$master:\E')"); - print "(po) " unless ($po4a_opts{"quiet"}); - $po=$poorig->filter("(reference='\Q$master:\E')"); - unlink($pot_filename) if -e $pot_filename; - unlink($po_filename) if -e $po_filename; - - $pot->write($pot_filename); - $po->write($po_filename); - - my $cmd; - $cmd = "msgmerge -U $po_filename $pot_filename --backup=none"; - my $out = qx/$cmd 2>&1/; - print $out if ($po4a_opts{"verbose"}); - unless ($? == 0) { - my $err = ""; - if ($? == -1) { - $err = sprintf(gettext("failed to execute '%s': %s."), - $cmd, $!); - } elsif ($? & 127) { - if ($? & 128) { - $err = sprintf(gettext("'%s' died with signal %d, ". - "with coredump."), - $cmd, $? & 127); - } else { - $err = sprintf(gettext("'%s' died with signal %d, ". - "without coredump."), - $cmd, $? & 127); - } - } else { - $err = sprintf(gettext("'%s' exited with value %d."), - $cmd, $? >> 8); - } - - die wrap_msg(gettext("Error while running msgmerge: %s"), - $err); - } - $pores->read($po_filename); - } - $pores->write($po_filename{$lang}.".new"); - unlink($pot_filename) if -e $pot_filename; - unlink($po_filename) if -e $po_filename; - - } else { - my $cmd = "msgmerge -U ".$po_filename{$lang}." $pot_filename". - ($po4a_opts{"no-backups"}?" --backup=none":""); - my $out = qx/$cmd 2>&1/; - print $out if ($po4a_opts{"verbose"}); - unless ($? == 0) { - my $err = ""; - if ($? == -1) { - $err = sprintf(gettext("failed to execute '%s': %s."), - $cmd, $!); - } elsif ($? & 127) { - if ($? & 128) { - $err = sprintf(gettext("'%s' died with signal %d, ". - "with coredump."), - $cmd, $? & 127); - } else { - $err = sprintf(gettext("'%s' died with signal %d, ". - "without coredump."), - $cmd, $? & 127); - } - } else { - $err = sprintf(gettext("'%s' exited with value %d."), - $cmd, $? >> 8); - } - - die wrap_msg(gettext("Error while running msgmerge: %s"), - $err); - } - system "msgfmt --statistics -v -o /dev/null ".$po_filename{$lang} - if $po4a_opts{"verbose"}; - } + my $cmd = "msgmerge -U ".$po_filename{$lang}." $pot_filename". + ($po4a_opts{"no-backups"}?" --backup=none":""); + run_cmd($cmd); + system "msgfmt --statistics -v -o /dev/null ".$po_filename{$lang} + if $po4a_opts{"verbose"}; } else { print wrap_msg(gettext("Creating %s:"), $po_filename{$lang}) if $po4a_opts{"verbose"}; @@ -746,14 +770,45 @@ } } +if ($po4a_opts{"split"}) { + # We don't need the tmp big POT anymore + unlink($pot_filename); + + # Split the complete PO in multiple POs + foreach $lang (sort keys %po_filename) { + foreach my $master (keys %document) { + my $tmp_file; + # Create a temporary PO, and check if the old one needs to be + # updated (unless --force was specified). + unless ($po4a_opts{"force"}) { + (undef,$tmp_file)=File::Temp->tempfile("po4aXXXX", + DIR => "/tmp", + SUFFIX => ".po", + OPEN => 0, + UNLINK => 0) + or die wrap_msg( + gettext("Can't create a temporary pot file: %s"), $!); + } + + my $cmd = "msggrep -N '$master' -o ". + ($po4a_opts{"force"}?$splitted_po{$lang}{$master}: + $tmp_file). + " $po_filename{$lang}"; + run_cmd($cmd); + + Locale::Po4a::Po::move_po_if_needed($tmp_file, + $splitted_po{$lang}{$master}) + unless ($po4a_opts{"force"}); + } + } +} + if ($po4a_opts{"rm-backups"}) { # Delete the .po~ backup files generated by msgmerge - unless ($po4a_opts{"split"}) { foreach $lang (sort keys %po_filename) { unlink $po_filename{$lang}."~"; } - } } if (not $po4a_opts{"no-translations"}) { @@ -825,6 +880,13 @@ } } +if ($po4a_opts{"split"}) { + # We don't need the tmp big POs anymore + foreach $lang (sort keys %po_filename) { + unlink $po_filename{$lang}; + } +} + if ($po4a_opts{"rm-translations"}) { # Delete the translated documents foreach $lang (sort keys %po_filename) { Index: lib/Locale/Po4a/Po.pm =================================================================== RCS file: /cvsroot/po4a/po4a/lib/Locale/Po4a/Po.pm,v retrieving revision 1.57 diff -u -r1.57 Po.pm --- lib/Locale/Po4a/Po.pm 25 Feb 2006 15:20:05 -0000 1.57 +++ lib/Locale/Po4a/Po.pm 26 Feb 2006 22:09:33 -0000 @@ -313,31 +313,44 @@ =cut +sub move_po_if_needed { + my ($new_po, $old_po) = (shift, shift); + my $diff; + + if (-e $old_po) { + $diff = qx(diff -q -I'^#:' -I'^"POT-Creation-Date:' -I'^"PO-Revision-Date:' $old_po $new_po); + if ( $diff eq "" ) { + unlink $new_po + or die wrap_msg(dgettext("po4a","Can't unlink %s."), + $new_po); + # touch the old PO + my ($atime, $mtime) = (time,time); + utime $atime, $mtime, $old_po; + } else { + move $new_po, $old_po + or die wrap_msg(dgettext("po4a","Can't move %s to %s."), + $new_po, $old_po); + } + } else { + move $new_po, $old_po + or die wrap_msg(dgettext("po4a","Can't move %s to %s."), + $new_po, $old_po); + } +} + sub write_if_needed { my $self=shift; my $filename=shift or croak (dgettext("po4a","Can't write to a file without filename")."\n"); if (-e $filename) { - my ($tmp_filename, $diff); + my ($tmp_filename); (undef,$tmp_filename)=File::Temp->tempfile($filename."XXXX", DIR => "/tmp", OPEN => 0, UNLINK => 0); $self->write($tmp_filename); - $diff = qx(diff -q -I'^#:' -I'^"POT-Creation-Date:' -I'^"PO-Revision-Date:' $filename $tmp_filename); - if ( $diff eq "" ) { - unlink $tmp_filename or - die wrap_msg(dgettext("po4a","Can't unlink %s."), - $tmp_filename); - # touch it - my ($atime, $mtime) = (time,time); - utime $atime, $mtime, $filename; - } else { - move $tmp_filename, $filename or - die wrap_msg(dgettext("po4a","Can't rename %s to %s."), - $tmp_filename, $filename); - } + move_po_if_needed($tmp_filename, $filename); } else { $self->write($filename); }