#!/usr/bin/perl -w # # .po to faqomatic's Language_.pm converter. # # Usage: # po2pm [-h] [{inputfile|-} [outfile]] # # Copyright (c) Andrew W. Nosenko , 2001 # # This program is free software; you can redistribute it and/or modify # it under the terms of either: # # a) the GNU General Public License as published by the Free # Software Foundation; either version 2, or (at your option) any # later version, or # b) the "Artistic License" which comes with Perl Kit. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either # the GNU General Public License or the Artistic License for more details. # use strict; use IO; use File::Basename; use Getopt::Long; my $NAME = 'po2pm'; my $PROG; sub Help() { printf(".po to faqomatic's Language_.pm converter.\n"); printf("Copyright (c) Andrew W. Nosenko , 2001\n"); printf("Usage:\n"); printf(" %s [-h] [{inputfile|-} [outfile]]\n", $PROG); printf("Where:\n"); printf(" inputfile .po file for building Language_.pm from which.\n"); printf(" If omited or have magic name \`-' (minus sign)\n"); printf(" then STDIN will be used\n"); printf(" outfile Name of taget .pm file. If omited then STDOUT\n"); printf(" will be used.\n"); printf("Options:\n"); printf(" --help | -h this Help\n"); } sub UseHelp() { printf(STDERR "%s: try \`%s --help' for help\n", $PROG, $PROG); } sub perlify( $ ) { my $s = $_[0]; if (defined($s)) { $s =~ s/\\\\/\\/g; } return $s; } sub po_to_pm( $$$$ ) { my ($inhandle, $infilename, $outhandle, $outfilename) = @_; my $state = 'initial'; # 'initial', 'msgid', 'msgstr' my $line; my $lineno = 0; my $fuzzy = 0; my ($msgid, $msgstr); while(defined($line = $inhandle->getline())) { chomp($line); ++$lineno; if ($line =~ m/^\s*$/ || $line =~ m/^#/) { if ($state ne 'initial' && $state ne 'msgstr') { die("$infilename:$lineno: syntax error: current state \`$state', expected state \`initial' or \`msgstr'"); } if (defined($msgid) && defined($msgstr)) { $outhandle->printf(" \"%s\"\n", $msgid) or die("error output into \`$outfilename': $!"); if ($fuzzy) { $outhandle->printf("# fuzzy # => \"%s\",\n", $msgstr) or die("error output into \`$outfilename': $!"); $outhandle->printf(" => \"\",\n") or die("error output into \`$outfilename': $!"); } else { $outhandle->printf(" => \"%s\",\n", $msgstr) or die("error output into \`$outfilename': $!"); } undef($msgid); undef($msgstr); } $state = 'initial'; if ($line =~ m/^#,/ && $line =~ m/, fuzzy\b/) { $fuzzy = 1; } else { $fuzzy = 0; } $outhandle->printf("%s\n", $line) or die("error output into \`$outfilename': $!"); next; } if ($line =~ m/^msgid "/) { if ($state ne 'initial') { die("$infilename:$lineno: unexpected msgid"); } $line =~ m/^msgid "(.*)"$/ or die("$infilename:$lineno: syntax error"); $msgid = perlify($1); $state = 'msgid'; next; } if ($line =~ m/^msgstr "/) { if ($state ne 'msgid') { die("$infilename:$lineno: unexpected msgstr"); } $line =~ m/^msgstr "(.*)"$/ or die("$infilename:$lineno: syntax error"); $msgstr = perlify($1); $state = 'msgstr'; next; } if ($line =~ m/^"/) { if ($state ne 'msgid' && $state ne 'msgstr') { die("$infilename:$lineno: unexpected string"); } $line =~ m/^"(.*)"$/ or die("$infilename:$lineno: syntax error"); if ($state eq 'msgid') { $msgid .= perlify($1); } elsif ($state eq 'msgstr') { $msgstr .= perlify($1); } next; } die("assert! state=$state, infilename=$infilename, lineno=$lineno, line=\`$line'"); } if ($inhandle->error()) { die("error reading from \`$infilename': $!"); } if ($state ne 'initial' && $state ne 'msgstr') { die("$infilename:$lineno: syntax error at EOF: current state \`$state', expected state \`initial' or \`msgstr'"); } if (defined($msgid) && defined($msgstr)) { $outhandle->printf(" \"%s\"\n", $msgid) or die("error output into \`$outfilename': $!"); if ($fuzzy) { $outhandle->printf("# fuzzy # => \"%s\",\n", $msgstr) or die("error output into \`$outfilename': $!"); $outhandle->printf(" => \"\",\n") or die("error output into \`$outfilename': $!"); } else { $outhandle->printf(" => \"%s\",\n", $msgstr) or die("error output into \`$outfilename': $!"); } undef($msgid); undef($msgstr); } return 1; } sub output_pm_header( $$$ ) { my ($infilename, $outhandle, $outfilename) = @_; my ($inbasename, $outbasename); $inbasename = basename($infilename); $outbasename = basename($outfilename); $outhandle->printf('#-------------------------------------------------------------------- # %s # Generated automatically from %s by %s #-------------------------------------------------------------------- sub translations { my $tx = shift; my %%data = ( ', $outbasename, $inbasename, $NAME) or die("error output into \`$outfilename' : $!"); return 1; } sub output_pm_footer( $$ ) { my ($outhandle, $outfilename) = @_; $outhandle->print(' ); # end of %data hash my $msgid; foreach $msgid (keys(%data)) { $tx->{$msgid} = $data{$msgid}; } return 1; } ') or die("error output into \`$outfilename' : $!"); return 1; } sub main() { my $success; my $opt_help; my ($infilename, $inhandle, $in_close_on_exit); my ($outfilename, $outhandle, $out_close_on_exit); $PROG = basename($0); Getopt::Long::Configure('bundling', 'no_ignore_case', 'no_auto_abbrev'); $success = GetOptions('help|h' => \$opt_help); if (!$success) { UseHelp(); exit(1); } if ($opt_help) { Help(); exit(0); } if (@ARGV > 2) { printf(STDERR "%s: too many command line arguments\n", $PROG); UseHelp(); exit(1); } # # Open input/output handles # $infilename = $ARGV[0]; if ($infilename && $infilename ne '-') { $inhandle = IO::File->new($infilename, 'r') or die("error opening \`$infilename' for reading: $!\n"); $in_close_on_exit = 1; } else { $infilename = '(stdin)'; $inhandle = IO::Handle->new_from_fd(fileno(STDIN), 'r') or die("error reopening STDIN for reading: $!\n"); $in_close_on_exit = 0; } $outfilename = $ARGV[1]; if ($outfilename) { $outhandle = IO::File->new($outfilename, 'w') or die("error opening \`$outfilename' for writing: $!\n"); $out_close_on_exit = 1; } else { $outfilename = '(stdout)'; $outhandle = IO::Handle->new_from_fd(fileno(STDOUT), 'w') or die("error reopening STDOUT for writing: $!\n"); $out_close_on_exit = 0; } # # Main work # $success = output_pm_header($infilename, $outhandle, $outfilename) && po_to_pm($inhandle, $infilename, $outhandle, $outfilename) && output_pm_footer($outhandle, $outfilename); # # Finish # if ($in_close_on_exit) { $inhandle->close() or die("error closing input file \`$infilename': $!\n"); } if ($out_close_on_exit) { $outhandle->close() or die("error closing output file \`$outfilename': $!\n"); } return $success ? 0 : 1; } my $rc = main(); exit($rc);