source: trunk/third/xml-i18n-tools/xml-i18n-update.in @ 15545

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