The SILC Project

source navigation ]
identifier search ]
freetext search ]
file search ]

silc/silcer/xml-i18n-update.in

  1 #!@XML_I18N_TOOLS_PERL@ -w
  2 
  3 #  The GNOME Translation Update Tool
  4 #
  5 #  Copyright (C) 2000 Free Software Foundation.
  6 #
  7 #  This library is free software; you can redistribute it and/or
  8 #  modify it under the terms of the GNU General Public License as
  9 #  published by the Free Software Foundation; either version 2 of the
 10 #  License, or (at your option) any later version.
 11 #
 12 #  This script is distributed in the hope that it will be useful,
 13 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15 #  General Public License for more details.
 16 #
 17 #  You should have received a copy of the GNU General Public License
 18 #  along with this library; if not, write to the Free Software
 19 #  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20 #
 21 #  Author(s): Kenneth Christiansen
 22 
 23 ## Release information
 24 my $PROGRAM  = "xml-i18n-update";
 25 my $VERSION  = "0.9";
 26 my $_PACKAGE = "xml-i18n-tools";
 27 
 28 ## Loaded modules
 29 use strict;
 30 use Getopt::Long;
 31 use Cwd;
 32 use File::Copy;
 33 use File::Find;
 34 
 35 ## Scalars used by the option stuff
 36 my $LANG           = $ARGV[0];
 37 my $HELP_ARG       = "0";
 38 my $VERSION_ARG    = "0";
 39 my $DIST_ARG       = "0";
 40 my $POT_ARG        = "0";
 41 my $HEADERS_ARG    = "0";
 42 my $MAINTAIN_ARG   = "0";
 43 my $REPORT_ARG     = "0";
 44 my $VERBOSE        = "0";
 45 
 46 my @languages;
 47 my %po_files_by_lang = ();
 48 
 49 my $xml_extension = 
 50 "xml(\.in)*|".          # .in is not required
 51 "ui|".
 52 "glade(\.in)*|".        # .in is not required
 53 "desktop(\.in)+|".
 54 "directory(\.in)+|".
 55 "soundlist(\.in)+|".
 56 "keys(\.in)+|".
 57 "oaf(\.in)+|".
 58 "server(\.in)+|".
 59 "etspec|".
 60 "pong(\.in)+";
 61 
 62 my $PACKAGE = &find_package_name;
 63 
 64 ## Always print as the first thing
 65 $| = 1;
 66 
 67 ## Give error if script is run without an argument
 68 if (! $LANG){
 69     print "${PROGRAM}:  missing file arguments\n";
 70     print "Try `${PROGRAM} --help' for more information.\n";
 71     exit;
 72 }
 73 
 74 ## Handle options
 75 GetOptions (
 76             "help|h|?"          => \$HELP_ARG,
 77             "version|v"         => \$VERSION_ARG,
 78             "dist|d"            => \$DIST_ARG,
 79             "pot|p"             => \$POT_ARG,
 80             "headers|s"         => \$HEADERS_ARG,
 81             "maintain|m"        => \$MAINTAIN_ARG,
 82             "report|r"          => \$REPORT_ARG,
 83             "verbose|x"         => \$VERBOSE
 84             ) or &invalid_option;
 85 
 86 
 87 ## Use the supplied arguments
 88 ## Check for options.
 89 ## This section will check for the different options.
 90 
 91 sub split_on_argument {
 92 
 93     if ($VERSION_ARG) {
 94         &version;
 95 
 96     } elsif ($HELP_ARG) {
 97         &help;
 98 
 99     } elsif ($DIST_ARG) {
100         &merging;
101         &status;
102 
103     } elsif ($POT_ARG) {
104         &gen_headers;
105         &generate_pot;
106 
107     } elsif ($HEADERS_ARG) {
108         &gen_headers;
109         exit;
110 
111     } elsif ($MAINTAIN_ARG) {
112         &maintain;
113 
114     } elsif ($REPORT_ARG) {
115         &show_status;
116 
117     } elsif ($LANG) {
118         if ($LANG =~ /^-/){ ## not an option
119             &help;
120         } else {
121             &main;
122         }
123 
124     } else {
125         &help;
126     }
127 }
128 
129 &split_on_argument;
130 
131 sub main
132 {
133    if(-s "$LANG.po"){
134         print "Working, please wait..." unless $VERBOSE;
135         &gen_headers;
136         &generate_pot;
137         &merging;
138         &status;
139    }
140 
141    ## Report error if the language file supplied
142    ## to the command line is non-existent
143    else {
144         &not_existing;
145    }
146 }
147 
148 sub determine_type($) {
149    my $type = $_;
150 
151    my $gettext_type;
152 
153    if ($type =~ /\[type: (gettext\/[^\]].*)]/) {
154         $gettext_type=$1;
155    }
156    elsif ($type =~ /(?:xml(\.in)*|ui|oaf(?:\.in)+|pong(?:\.in)+|etspec)$/) {
157         $gettext_type="gettext\/xml";
158    }
159    elsif ($type =~ /glade(\.in)*$/) {
160         $gettext_type="gettext\/glade";
161    }
162    elsif ($type =~ /(?:desktop(?:\.in)+|directory(?:\.in)+|soundlist(?:\.in)+)$/) {
163         $gettext_type="gettext\/ini";
164    }
165    elsif ($type =~ /keys(\.in)+$/) {
166         $gettext_type="gettext\/keys";
167    }
168    else { $gettext_type=""; }
169 
170    return $gettext_type;
171 }
172 
173 sub version{
174 
175     ## Print version information
176     print "${PROGRAM} (${_PACKAGE}) $VERSION\n";
177     print "Written by Kenneth Christiansen <kenneth\@gnome.org>, 2000.\n\n";
178     print "Copyright (C) 2000 Free Software Foundation, Inc.\n";
179     print "This is free software; see the source for copying conditions.  There is NO\n";
180     print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
181     exit;
182 }
183 
184 sub help
185 {
186     ## Print usage information
187     print "Usage: ./${PROGRAM} [OPTIONS] ...LANGCODE\n";
188     print "Updates pot files and merge them with the translations.\n\n";
189     print "  -H, --help                   shows this help page\n";
190     print "  -P, --pot                    generate the pot file only\n";
191     print "  -S, --headers                generate the XML headerfiles in POTFILES.in\n";
192     print "  -M, --maintain               search for missing files in POTFILES.in\n";
193     print "  -R, --report                 creates a status report for the module.\n";
194     print "  -X, --verbose                show lots of feedback\n";
195     print "  -V, --version                shows the version\n";
196     print "\nExamples of use:\n";
197     print "${PROGRAM} --pot    just creates a new pot file from the source\n";
198     print "${PROGRAM} da       created new pot file and updated the da.po file\n\n";
199     print "Report bugs to <kenneth\@gnome.org>.\n";
200     exit;
201 }
202 
203 sub maintain
204 {
205     my (@buf_i18n_plain,
206         @buf_i18n_xml,
207         @buf_potfiles,
208         @buf_potfiles_ignore,
209         @buf_allfiles,
210         @buf_allfiles_sorted,
211         @buf_potfiles_sorted
212     );
213 
214     ## Search and find all translatable files
215     find sub { push @buf_i18n_plain, "$File::Find::name" if /\.(c|y|cc|c\+\+|h|gob)$/ }, "..";
216     find sub { push @buf_i18n_xml, "$File::Find::name" if /\.($xml_extension)$/ }, "..";
217 
218     open(POTFILES, "POTFILES.in") || die "$PROGRAM:  there's no POTFILES.in!!!\n";
219     @buf_potfiles = <POTFILES>;
220 
221     print "Searching for missing translatable files...\n";
222 
223     ## Check if we should ignore some found files, when
224     ## comparing with POTFILES.in
225     if (-s "POTFILES.skip"){
226         open FILE, "POTFILES.skip";
227         while (<FILE>) {
228             if (/^[^#]/){
229                 push @buf_potfiles_ignore, $_;
230             }
231         }
232         print "Found POTFILES.skip: Ignoring files...\n";
233         @buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles);
234     }
235 
236     foreach my $file (@buf_i18n_plain){
237         open FILE, "<$file";
238         while (<FILE>) {
239             if (/_\(\"/){
240                 ## Remove the first 3 chars and add newline
241                 push @buf_allfiles, unpack("x3 A*", $file) . "\n";
242                 last;
243             }
244         }
245     }
246 
247     foreach my $file (@buf_i18n_xml){
248         open FILE, "<$file";
249         while (<FILE>) {
250             if (/\s_(.*)=\"/){
251                 ## Remove the first 3 chars and add newline
252                 push @buf_allfiles, unpack("x3 A*", $file) . "\n";
253                 last;
254             }
255         }
256     }
257 
258     @buf_allfiles_sorted = sort (@buf_allfiles);
259     @buf_potfiles_sorted = sort (@buf_potfiles);
260 
261     my %in2;
262     foreach (@buf_potfiles_sorted) {
263         $in2{$_} = 1;
264     }
265 
266     my @result;
267 
268     foreach (@buf_allfiles_sorted){
269         if (!exists($in2{$_})){
270             push @result, $_
271         }
272     }
273 
274     ## Save file with information about the files missing
275     ## if any, and give information about this proceedier
276     if(@result){
277         open OUT, ">missing";
278         print OUT @result;
279         print "\nHere is the result:\n\n", @result, "\n";
280         print "The file \"missing\" has been placed in the current directory.\n";
281         print "Files supposed to be ignored should be placed in \"POTFILES.skip\"\n";
282     }
283 
284     ## If there is nothing to complain about, notice the user
285     else{
286         print "\nWell, it's all perfect! Congratulation!\n";
287     }
288 }
289 
290 sub invalid_option
291 {
292     ## Handle invalid arguments
293     print "${PROGRAM}: invalid option -- $LANG\n";
294     print "Try `${PROGRAM} --help' for more information.\n";
295     exit 1;
296 }
297 
298 sub gen_headers
299 {
300     my $XML_I18N_EXTRACT = `which xml-i18n-extract 2>/dev/null`;
301     chomp $XML_I18N_EXTRACT;
302 
303     $XML_I18N_EXTRACT = $ENV{"XML_I18N_EXTRACT"} if $ENV{"XML_I18N_EXTRACT"};
304 
305     ## Generate the .h header files, so we can allow glade and
306     ## xml translation support
307     if (! -s $XML_I18N_EXTRACT)
308     {
309         print "\n *** The xml-i18n-extract script wasn't found!"
310              ."\n *** Without this xml-i18n-update can not generate files.\n";
311         exit;
312     }
313     else
314     {
315         open FILE, "<POTFILES.in";
316         while (<FILE>) {
317            chomp;
318 
319            ## Find xml files in POTFILES.in and generate the
320            ## files with help from the xml-i18n-extract script
321 
322            my $gettext_type=&determine_type($1);
323 
324            if (/\.($xml_extension)$/ || /^\[/){
325                $_ =~ s/^\[[^\[].*]\s*//;
326                my $filename = "../$_";
327 
328                if ($VERBOSE){
329                    system($XML_I18N_EXTRACT, "--update", "--type=$gettext_type", $filename);
330                } else {
331                    system($XML_I18N_EXTRACT, "--update", "--type=$gettext_type", "--quiet", $filename);
332                }
333            }
334        }
335        close FILE;
336    }
337 }
338 
339 sub generate_pot
340 {
341     ## Generate the potfiles from the POTFILES.in file
342 
343     print "Building the $PACKAGE.pot...\n" if $VERBOSE;
344 
345     move("POTFILES.in", "POTFILES.in.old");
346 
347     open INFILE, "<POTFILES.in.old";
348     open OUTFILE, ">POTFILES.in";
349     while (<INFILE>) {
350         s/\.($xml_extension)$/$&.h/;
351         s/^\[.*]\s*(.*)/$1.h/;
352         print OUTFILE $_;
353     }
354     close OUTFILE;
355     close INFILE;
356 
357     my $gettext_test   ="test \! -f $PACKAGE\.po \|\| \( rm -f \.\/$PACKAGE\.pot "
358                        ."&& mv $PACKAGE\.po \.\/$PACKAGE\.pot \)";
359 
360     system("xgettext", "--default-domain\=$PACKAGE", "--directory\=\.\.",
361            "--add-comments", "--keyword\=\_", "--keyword\=N\_",
362            "--files-from\=\.\/POTFILES\.in");
363 
364     system($gettext_test);
365 
366     print "Wrote $PACKAGE.pot\n" if $VERBOSE;
367 
368     move("POTFILES.in.old", "POTFILES.in");
369 
370     print "Removing generated header (.h) files..." if $VERBOSE;
371 
372     open FILE, "<POTFILES.in";
373     while (<FILE>)
374     {
375         chomp;
376         unlink "../$_.h" if /\.($xml_extension)$/;
377     }
378     close FILE;
379     print "done\n" if $VERBOSE;
380 }
381 
382 sub merging
383 {
384     if ($ARGV[1]){
385         $LANG   = $ARGV[1];
386     } else {
387         $LANG   = $ARGV[0];
388     }
389 
390     if ($ARGV[0] ne "--dist" && $ARGV[0] ne "-D") {
391         print "Merging $LANG.po with $PACKAGE.pot..." if $VERBOSE;
392     }
393 
394     &perform_merge($LANG);
395     ## Remove the "messages" trash file generated by gettext
396     unlink "messages";
397 }
398 
399 sub perform_merge
400 {
401     my ($LANG) = @_;
402 
403     copy("$LANG.po", "$LANG.po.old") || die "copy failed: $!";
404 
405     ## Preform merge
406     system("msgmerge", "$LANG.po.old", "$PACKAGE.pot", "-o", "$LANG.po");
407 
408     ## Remove the backup file
409     unlink "$LANG.po.old";
410 }
411 
412 sub not_existing
413 {
414     ## Report error if supplied language file is non-existing
415     print "$PROGRAM:  sorry, $LANG.po does not exist!\n";
416     print "Try `$PROGRAM --help' for more information.\n";
417     exit;
418 }
419 
420 sub gather_po_files
421 {
422     my @po_files = glob("./*.po");
423 
424     @languages = map (&po_file2lang, @po_files);
425 
426     foreach my $lang (@languages) {
427         $po_files_by_lang{$lang} = shift (@po_files);
428     }
429 }
430 
431 sub po_file2lang
432 {
433     my $tmp = $_;
434     $tmp =~ s/^.*\/(.*)\.po$/$1/;
435     return $tmp;
436 }
437 
438 sub status
439 {
440     ## Print statistics
441     system("msgfmt", "--statistics", "$LANG.po");
442     print "\n";
443 }
444 
445 sub show_status
446 {
447     &gen_headers;
448     &generate_pot;
449     &gather_po_files;
450 
451     foreach my $lang (@languages){
452         print "$lang: ";
453         &perform_merge($lang);
454     }
455 
456     print "\n\n * Current translation support in $PACKAGE \n\n";
457 
458     foreach my $lang (@languages){
459         print "$lang: ";
460         ## Print statistics
461         system("msgfmt", "--statistics", "$lang.po");
462     }
463 }
464 
465 sub find_package_name
466 {
467     my $base_dirname = getcwd();
468     $base_dirname =~ s@.*/@@;
469 
470     my ($conf_in, $src_dir);
471 
472     if ($base_dirname eq "po") {
473         if (-f "../configure.in") {
474             $conf_in = "../configure.in";
475         } else {
476             my $makefile_source;
477             local (*IN);
478             open (IN, "<Makefile") || die "can't open Makefile: $!";
479 
480             while (<IN>) {
481                 if (/^top_srcdir[ \t]*=/) {
482                     $src_dir = $_;
483                     # print "${src_dir}\n";
484 
485                     $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
486                     # print "${src_dir}\n";
487                     chomp $src_dir;
488                     $conf_in = "$src_dir" . "/configure.in" . "\n";
489                     last;
490                 }
491             }
492             $conf_in || die "Cannot find top_srcdir in Makefile."
493         }
494 
495         my $conf_source; {
496            local (*IN);
497            local $/; # slurp mode
498            open (IN, "<$conf_in") || die "can't open $conf_in: $!";
499            $conf_source = <IN>;
500         }
501 
502         if ($conf_source =~ /AM_INIT_AUTOMAKE\(([^,]*),(.*)/) {
503             my $package_name = $1;
504             if ($package_name =~ /^[\$](.*)/){
505                 if ($conf_source =~ /$1=(.*)/) {
506                     $package_name = $1;
507                 }
508             }
509             return $package_name;
510         }
511     }
512 
513     print "$PROGRAM: Unable to determine package name.\n" .
514           "Make sure to run this script inside the po directory.\n";
515     exit;
516 }

This page was automatically generated by the LXR engine.
Free-text search provided by Glimpse