90
107
"report|r" => \$REPORT_ARG,
91
108
"verbose|x" => \$VERBOSE,
92
109
"gettext-package|g=s" => \$GETTEXT_PACKAGE,
93
) or &print_error_invalid_option;
97
# Use the supplied arguments
98
# This section will check for the different options.
100
sub split_on_argument
109
## Give error if script is run without an argument
111
print "${PROGRAM}: missing file arguments\n";
112
print "Try `${PROGRAM} --help' for more information.\n";
116
# --version and --help doesn't require us to be in /po, so
117
# first do this here.
118
$MODULE = $GETTEXT_PACKAGE || &find_package_name;
126
&generate_po_template;
128
elsif ($HEADERS_ARG) {
132
elsif ($MAINTAIN_ARG) {
135
elsif ($REPORT_ARG) {
138
elsif ($LANG && $LANG !~ /^-/) {
150
## Print version information
151
print "${PROGRAM} (${PACKAGE}) $VERSION\n";
152
print "Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler.\n\n";
153
print "Copyright (C) 2000-2002 Free Software Foundation, Inc.\n";
154
print "This is free software; see the source for copying conditions. There is NO\n";
155
print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
161
## Print usage information
162
print "Usage: ${PROGRAM} [OPTIONS] ...LANGCODE\n";
163
print "Updates PO template files and merge them with the translations.\n\n";
164
print " -p, --pot generate the PO template only\n";
165
print " -s, --headers generate the header files in POTFILES.in\n";
166
print " -m, --maintain search for left out files from POTFILES.in\n";
167
print " -r, --report display a status report for the module.\n";
168
print " -x, --verbose display lots of feedback\n";
169
print " --help display this help and exit\n";
170
print " --version output version information and exit\n";
171
print "\nExamples of use:\n";
172
print "${PROGRAM} --pot just creates a new PO template from the source\n";
173
print "${PROGRAM} da created new PO template and updated the da.po file\n\n";
174
print "Report bugs to bugzilla.gnome.org, module 'intltool'.\n";
110
"output-file|o=s" => \$OUTPUT_FILE,
111
) or &Console_WriteError_InvalidOption;
113
&Console_Write_IntltoolHelp if $HELP_ARG;
114
&Console_Write_IntltoolVersion if $VERSION_ARG;
116
my $arg_count = ($DIST_ARG > 0)
119
+ ($MAINTAIN_ARG > 0)
122
&Console_Write_IntltoolHelp if $arg_count > 1;
124
# --version and --help don't require a module name
125
my $MODULE = $GETTEXT_PACKAGE || &FindPackageName;
136
elsif ($MAINTAIN_ARG)
144
&Console_Write_CoverageReport;
146
elsif ((defined $ARGV[0]) && $ARGV[0] =~ /^[a-z]/)
180
150
## Report error if the language file supplied
181
151
## to the command line is non-existent
182
&print_error_not_existing if !(-s "$LANG.po");
184
print "Working, please wait..." unless $VERBOSE;
186
&generate_po_template;
191
sub determine_type ($)
152
&Console_WriteError_NotExisting("$lang.po") if ! -s "$lang.po";
156
print "Working, please wait..." if $VERBOSE;
160
&POFile_Update ($lang, $OUTPUT_FILE);
161
&Console_Write_TranslationStatus ($lang, $OUTPUT_FILE);
165
&Console_Write_IntltoolHelp;
172
sub Console_Write_IntltoolVersion
175
${PROGRAM} (${PACKAGE}) $VERSION
176
Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler.
178
Copyright (C) 2000-2003 Free Software Foundation, Inc.
179
This is free software; see the source for copying conditions. There is NO
180
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
185
sub Console_Write_IntltoolHelp
188
Usage: ${PROGRAM} [OPTION]... LANGCODE
189
Updates PO template files and merge them with the translations.
191
Mode of operation (only one is allowed):
192
-p, --pot generate the PO template only
193
-s, --headers generate the header files in POTFILES.in
194
-m, --maintain search for left out files from POTFILES.in
195
-r, --report display a status report for the module
196
-d, --dist merge LANGCODE.po with existing PO template
199
-g, --gettext-package=NAME override PO template name, useful with --pot
200
-o, --output-file=FILE write merged translation to FILE
201
-x, --verbose display lots of feedback
202
--help display this help and exit
203
--version output version information and exit
206
${PROGRAM} --pot just create a new PO template
207
${PROGRAM} xy create new PO template and merge xy.po with it
209
Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
210
or send email to <xml-i18n-tools\@gnome.org>.
215
sub POFile_DetermineType ($)
194
218
my $gettext_type;
196
# FIXME: Use $xml_extentions, and maybe do all this even nicer
198
"(?:xml(\.in)*|ui|oaf(?:\.in)+|server(?:\.in)+|sheet(?:\.in)+|".
199
"pong(?:\.in)+|etspec)";
201
"(?:desktop(?:\.in)+|caves(?:\.in)+|directory(?:\.in)+|".
202
"soundlist(?:\.in)+)";
204
if ($type =~ /\[type: gettext\/([^\]].*)]/) {
207
elsif ($type =~ /$xml_regex$/) {
210
elsif ($type =~ /glade(\.in)*$/) {
211
$gettext_type="glade";
213
elsif ($type =~ /$ini_regex$/) {
216
elsif ($type =~ /scm(\.in)*$/) {
217
$gettext_type="scheme";
219
elsif ($type =~ /keys(\.in)+$/) {
220
$gettext_type="keys";
222
else { $gettext_type=""; }
220
my $xml_regex = "(?:" . $xml_support . ")";
221
my $ini_regex = "(?:" . $ini_support . ")";
222
my $buildin_regex = "(?:" . $buildin_gettext_support . ")";
224
if ($type =~ /\[type: gettext\/([^\]].*)]/)
228
elsif ($type =~ /schemas(\.in)+$/)
230
$gettext_type="schemas";
232
elsif ($type =~ /glade2?(\.in)*$/)
234
$gettext_type="glade";
236
elsif ($type =~ /scm(\.in)*$/)
238
$gettext_type="scheme";
240
elsif ($type =~ /keys(\.in)+$/)
242
$gettext_type="keys";
247
elsif ($type =~ /$xml_regex$/)
251
elsif ($type =~ /$ini_regex$/)
255
elsif ($type =~ /$buildin_regex$/)
257
$gettext_type="buildin";
261
$gettext_type="unknown";
224
264
return "gettext\/$gettext_type";
227
sub find_leftout_files
267
sub TextFile_DetermineEncoding ($)
269
my $gettext_code="ASCII"; # All files are ASCII by default
270
my $filetype=`file $_ | cut -d ' ' -f 2`;
274
if ($filetype =~ /^(ISO|UTF)/)
276
chomp ($gettext_code = $filetype);
278
elsif ($filetype =~ /^XML/)
280
$gettext_code="UTF-8"; # We asume that .glade and other .xml files are UTF-8
284
return $gettext_code;
287
sub isNotValidMissing
291
return if $file =~ /^\{arch\}\/.*$/;
292
return if $file =~ /^$varhash{"PACKAGE"}-$varhash{"VERSION"}\/.*$/;
229
297
my (@buf_i18n_plain,
299
@buf_i18n_xml_unmarked,
233
302
@buf_potfiles_ignore,
239
308
## Search and find all translatable files
241
push @buf_i18n_plain, "$File::Find::name" if /\.(c|y|cc|cpp|c\+\+|h|gob)$/
244
push @buf_i18n_xml, "$File::Find::name" if /\.($xml_extension)$/
247
push @buf_i18n_ini, "$File::Find::name" if /\.($ini_extension)$/
250
open POTFILES, "POTFILES.in" || die "$PROGRAM: there's no POTFILES.in!\n";
252
@buf_potfiles = grep /^[^#]/, <POTFILES>;
310
push @buf_i18n_plain, "$File::Find::name" if /\.($buildin_gettext_support)$/;
311
push @buf_i18n_xml, "$File::Find::name" if /\.($xml_support)$/;
312
push @buf_i18n_ini, "$File::Find::name" if /\.($ini_support)$/;
313
push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/;
317
open POTFILES, $POTFILES_in or die "$PROGRAM: there's no POTFILES.in!\n";
318
@buf_potfiles = grep !/^(#|\s*$)/, <POTFILES>;
321
foreach (@buf_potfiles) {
254
325
print "Searching for missing translatable files...\n" if $VERBOSE;
256
327
## Check if we should ignore some found files, when
257
328
## comparing with POTFILES.in
258
foreach my $ignore ("POTFILES.skip", "POTFILES.ignore") {
263
push @buf_potfiles_ignore, $_;
266
print "Found $ignore: Ignoring files...\n" if $VERBOSE;
267
@buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles);
271
foreach my $file (@buf_i18n_plain) {
275
## Remove the first 3 chars and add newline
276
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
282
foreach my $file (@buf_i18n_xml) {
286
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
292
foreach my $file (@buf_i18n_ini){
296
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
329
foreach my $ignore ("POTFILES.skip", "POTFILES.ignore")
331
(-s $ignore) or next;
333
if ("$ignore" eq "POTFILES.ignore")
335
print "The usage of POTFILES.ignore is deprecated. Please consider moving the\n".
336
"content of this file to POTFILES.skip.\n";
339
print "Found $ignore: Ignoring files...\n" if $VERBOSE;
340
open FILE, "<$ignore" or die "ERROR: Failed to open $ignore!\n";
344
push @buf_potfiles_ignore, $_ unless /^(#|\s*$)/;
348
@buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles);
351
foreach my $file (@buf_i18n_plain)
359
# Handle continued multi-line comment.
362
next unless s-.*\*/--;
366
# Handle continued macro.
369
$in_macro = 0 unless /\\$/;
373
# Handle start of macro (or any preprocessor directive).
376
$in_macro = 1 if /^([^\\]|\\.)*\\$/;
380
# Handle comments and quoted text.
381
while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy
392
elsif ($match eq "//")
398
if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-)
400
warn "mismatched quotes at line $. in $file\n";
406
if (/\.GetString ?\(QUOTEDTEXT/)
408
if (defined isNotValidMissing (unpack("x3 A*", $file))) {
409
## Remove the first 3 chars and add newline
410
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
417
if (defined isNotValidMissing (unpack("x3 A*", $file))) {
418
## Remove the first 3 chars and add newline
419
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
427
foreach my $file (@buf_i18n_xml)
433
# FIXME: share the pattern matching code with intltool-extract
434
if (/\s_(.*)=\"/ || /<_[^>]+>/ || /translatable=\"yes\"/)
436
if (defined isNotValidMissing (unpack("x3 A*", $file))) {
437
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
445
foreach my $file (@buf_i18n_ini)
452
if (defined isNotValidMissing (unpack("x3 A*", $file))) {
453
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
461
foreach my $file (@buf_i18n_xml_unmarked)
463
if (defined isNotValidMissing (unpack("x3 A*", $file))) {
464
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
302
469
@buf_allfiles_sorted = sort (@buf_allfiles);
303
470
@buf_potfiles_sorted = sort (@buf_potfiles);
306
foreach (@buf_potfiles_sorted) {
473
foreach (@buf_potfiles_sorted)
312
foreach (@buf_allfiles_sorted){
313
if (!exists($in2{$_})){
480
foreach (@buf_allfiles_sorted)
482
if (!exists($in2{$_}))
488
my @buf_potfiles_notexist;
490
foreach (@buf_potfiles_sorted)
492
chomp (my $dummy = $_);
493
if ("$dummy" ne "" and ! -f "../$dummy")
495
push @buf_potfiles_notexist, $_;
318
499
## Save file with information about the files missing
319
500
## if any, and give information about this procedure.
321
print "\n" if $VERBOSE;
322
open OUT, ">missing";
324
print "The following files contain translations and are currently not in use. Please\n";
325
print "consider adding these to the POTFILES.in file, located in the po/ directory.\n\n";
327
print "If some of these files are left out on purpose then please add them to\n";
328
print "POTFILES.skip instead of POTFILES.in. A file 'missing' containing this list\n";
329
print "of left out files has been written in the current directory.\n";
501
if (@result + @buf_potfiles_notexist > 0)
505
print "\n" if $VERBOSE;
507
open OUT, ">missing";
510
warn "\e[1mThe following files contain translations and are currently not in use. Please\e[0m\n".
511
"\e[1mconsider adding these to the POTFILES.in file, located in the po/ directory.\e[0m\n\n";
512
print STDERR @result, "\n";
513
warn "If some of these files are left out on purpose then please add them to\n".
514
"POTFILES.skip instead of POTFILES.in. A file \e[1m'missing'\e[0m containing this list\n".
515
"of left out files has been written in the current directory.\n";
517
if (@buf_potfiles_notexist)
520
open OUT, ">notexist";
521
print OUT @buf_potfiles_notexist;
523
warn "\n" if ($VERBOSE or @result);
524
warn "\e[1mThe following files do not exist anymore:\e[0m\n\n";
525
warn @buf_potfiles_notexist, "\n";
526
warn "Please remove them from POTFILES.in or POTFILES.skip. A file \e[1m'notexist'\e[0m\n".
527
"containing this list of absent files has been written in the current directory.\n";
332
531
## If there is nothing to complain about, notify the user
334
print "\nAll files containing translations are present in POTFILES.in.\n";
533
print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE;
338
sub print_error_invalid_option
537
sub Console_WriteError_InvalidOption
340
539
## Handle invalid arguments
341
print "${PROGRAM}: invalid option -- $LANG\n";
342
print "Try `${PROGRAM} --help' for more information.\n";
540
print STDERR "Try `${PROGRAM} --help' for more information.\n";
348
my $EXTRACT = `which intltool-extract 2>/dev/null`;
546
my $EXTRACT = "@INTLTOOL_EXTRACT@";
351
549
$EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"};
353
551
## Generate the .h header files, so we can allow glade and
354
552
## xml translation support
357
print "\n *** The intltool-extract script wasn't found!"
358
."\n *** Without this intltool-update can not generate files.\n";
555
print STDERR "\n *** The intltool-extract script wasn't found!"
556
."\n *** Without it, intltool-update can not generate files.\n";
363
open FILE, "<POTFILES.in";
367
## Find xml files in POTFILES.in and generate the
368
## files with help from the extract script
370
my $gettext_type= &determine_type ($1);
372
if (/\.($xml_extension|$ini_extension)$/ || /^\[/){
373
$_ =~ s/^\[[^\[].*]\s*//;
374
my $filename = "../$_";
377
system($EXTRACT, "--update", "--type=$gettext_type", $filename);
379
system($EXTRACT, "--update", "--type=$gettext_type", "--quiet", $filename);
561
open (FILE, $POTFILES_in) or die "$PROGRAM: POTFILES.in not found.\n";
566
next if /^\[\s*encoding/;
568
## Find xml files in POTFILES.in and generate the
569
## files with help from the extract script
571
my $gettext_type= &POFile_DetermineType ($1);
573
if (/\.($xml_support|$ini_support)$/ || /^\[/)
577
my $filename = "../$_";
581
system ($EXTRACT, "--update", "--srcdir=$SRCDIR",
582
"--type=$gettext_type", $filename);
586
system ($EXTRACT, "--update", "--type=$gettext_type",
587
"--srcdir=$SRCDIR", "--quiet", $filename);
387
sub generate_po_template
596
# Generate .pot file from POTFILES.in
598
sub GeneratePOTemplate
389
## Generate the potfiles from the POTFILES.in file
391
print "Building the $MODULE.pot...\n" if $VERBOSE;
393
move ("POTFILES.in", "POTFILES.in.old");
395
open INFILE, "<POTFILES.in.old";
396
open OUTFILE, ">POTFILES.in";
398
s/\.($xml_extension|$ini_extension)$/$&.h/;
399
s/^\[.*]\s*(.*)/$1.h/;
600
my $XGETTEXT = $ENV{"XGETTEXT"} || "/opt/gnome-devel/bin/xgettext";
601
my $XGETTEXT_ARGS = $ENV{"XGETTEXT_ARGS"} || '';
606
print STDERR " *** xgettext is not found on this system!\n".
607
" *** Without it, intltool-update can not extract strings.\n";
611
print "Building $MODULE.pot...\n" if $VERBOSE;
613
open INFILE, $POTFILES_in;
614
unlink "POTFILES.in.temp";
615
open OUTFILE, ">POTFILES.in.temp" or die("Cannot open POTFILES.in.temp for writing");
617
my $gettext_support_nonascii = 0;
619
# checks for GNU gettext >= 0.12
620
my $dummy = `$XGETTEXT --version --from-code=UTF-8 >/dev/null 2>/dev/null`;
623
$gettext_support_nonascii = 1;
627
# urge everybody to upgrade gettext
628
print STDERR "WARNING: This version of gettext does not support extracting non-ASCII\n".
629
" strings. That means you should install a version of gettext\n".
630
" that supports non-ASCII strings (such as GNU gettext >= 0.12),\n".
631
" or have to let non-ASCII strings untranslated. (If there is any)\n";
634
my $encoding = "ASCII";
635
my $forced_gettext_code;
637
my $encoding_problem_is_reported = 0;
641
next if (/^#/ or /^\s*$/);
647
if (/^\[\s*encoding:\s*(.*)\s*\]/)
649
$forced_gettext_code=$1;
651
elsif (/\.($xml_support|$ini_support)$/ || /^\[/)
654
print OUTFILE "$_.h\n";
655
push @temp_headers, "../$_.h";
656
$gettext_code = &TextFile_DetermineEncoding ("../$_.h") if ($gettext_support_nonascii and not defined $forced_gettext_code);
660
if ($SRCDIR eq ".") {
661
print OUTFILE "$_\n";
663
print OUTFILE "$SRCDIR/../$_\n";
665
$gettext_code = &TextFile_DetermineEncoding ("../$_") if ($gettext_support_nonascii and not defined $forced_gettext_code);
668
next if (! $gettext_support_nonascii);
670
if (defined $forced_gettext_code)
672
$encoding=$forced_gettext_code;
674
elsif (defined $gettext_code and "$encoding" ne "$gettext_code")
676
if ($encoding eq "ASCII")
678
$encoding=$gettext_code;
680
elsif ($gettext_code ne "ASCII")
682
# Only report once because the message is quite long
683
if (! $encoding_problem_is_reported)
685
print STDERR "WARNING: You should use the same file encoding for all your project files,\n".
686
" but $PROGRAM thinks that most of the source files are in\n".
687
" $encoding encoding, while \"$_\" is (likely) in\n".
688
" $gettext_code encoding. If you are sure that all translatable strings\n".
689
" are in same encoding (say UTF-8), please \e[1m*prepend*\e[0m the following\n".
690
" line to POTFILES.in:\n\n".
691
" [encoding: UTF-8]\n\n".
692
" and make sure that configure.in/ac checks for $PACKAGE >= 0.27 .\n".
693
"(such warning message will only be reported once.)\n";
694
$encoding_problem_is_reported = 1;
405
system ("xgettext", "--default-domain\=$MODULE",
411
"--files-from\=\.\/POTFILES\.in");
413
# FIXME: Convert to use system () and perl functions like move ()
415
my $gettext_test ="test \! -f $MODULE\.po \|\| \( rm -f \.\/$MODULE\.pot "
416
."&& mv $MODULE\.po \.\/$MODULE\.pot \)";
418
system ($gettext_test);
420
print "Wrote $MODULE.pot\n" if $VERBOSE;
422
move ("POTFILES.in.old", "POTFILES.in");
703
unlink "$MODULE.pot";
704
my @xgettext_argument=("$XGETTEXT",
707
"--output\=$MODULE\.pot",
708
"--files-from\=\.\/POTFILES\.in\.temp");
709
my $XGETTEXT_KEYWORDS = &FindPOTKeywords;
710
push @xgettext_argument, $XGETTEXT_KEYWORDS;
711
push @xgettext_argument, "--from-code\=$encoding" if ($gettext_support_nonascii);
712
push @xgettext_argument, $XGETTEXT_ARGS if $XGETTEXT_ARGS;
713
my $xgettext_command = join ' ', @xgettext_argument;
715
# intercept xgettext error message
716
print "Running $xgettext_command\n" if $VERBOSE;
717
my $xgettext_error_msg = `$xgettext_command 2>\&1`;
718
my $command_failed = $?;
720
unlink "POTFILES.in.temp";
424
722
print "Removing generated header (.h) files..." if $VERBOSE;
426
open FILE, "<POTFILES.in";
431
unlink "../$_.h" if /\.($xml_extension|$ini_extension)$/;
435
print "done\n" if $VERBOSE;
440
# FIXME: This is ugly, and is it used???
447
print "Merging $LANG.po with $MODULE.pot..." if $VERBOSE;
449
copy ("$LANG.po", "$LANG.po.old") || die "copy failed: $!";
451
# Perform merge, remove backup file and the "messages" trash file
452
# generated by gettext
453
system ("msgmerge", "$LANG.po.old", "$MODULE.pot", "-o", "$LANG.po");
454
unlink "$LANG.po.old";
458
sub print_error_not_existing
723
unlink foreach (@temp_headers);
724
print "done.\n" if $VERBOSE;
726
if (! $command_failed)
728
if (! -e "$MODULE.pot")
730
print "None of the files in POTFILES.in contain strings marked for translation.\n" if $VERBOSE;
734
print "Wrote $MODULE.pot\n" if $VERBOSE;
739
if ($xgettext_error_msg =~ /--from-code/)
741
# replace non-ASCII error message with a more useful one.
742
print STDERR "ERROR: xgettext failed to generate PO template file because there is non-ASCII\n".
743
" string marked for translation. Please make sure that all strings marked\n".
744
" for translation are in uniform encoding (say UTF-8), then \e[1m*prepend*\e[0m the\n".
745
" following line to POTFILES.in and rerun $PROGRAM:\n\n".
746
" [encoding: UTF-8]\n\n";
750
print STDERR "$xgettext_error_msg";
751
if (-e "$MODULE.pot")
754
print STDERR "ERROR: xgettext failed but still managed to generate PO template file.\n".
755
" Please consult error message above if there is any.\n";
759
print STDERR "ERROR: xgettext failed to generate PO template file. Please consult\n".
760
" error message above if there is any.\n";
769
-f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n";
771
my $MSGMERGE = $ENV{"MSGMERGE"} || "/opt/gnome-devel/bin/msgmerge";
772
my ($lang, $outfile) = @_;
774
print "Merging $lang.po with $MODULE.pot..." if $VERBOSE;
776
my $infile = "$lang.po";
777
$outfile = "$lang.po" if ($outfile eq "");
779
# I think msgmerge won't overwrite old file if merge is not successful
780
system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot");
783
sub Console_WriteError_NotExisting
460
787
## Report error if supplied language file is non-existing
461
print "$PROGRAM: sorry, $LANG.po does not exist!\n";
462
print "Try `$PROGRAM --help' for more information.\n";
788
print STDERR "$PROGRAM: $file does not exist!\n";
789
print STDERR "Try '$PROGRAM --help' for more information.\n";
468
795
my @po_files = glob ("./*.po");
470
@languages = map (&po_file2lang, @po_files);
797
@languages = map (&POFile_GetLanguage, @po_files);
472
foreach my $lang (@languages) {
799
foreach my $lang (@languages)
473
801
$po_files_by_lang{$lang} = shift (@po_files);
480
$tmp =~ s/^.*\/(.*)\.po$/$1/;
486
system ("msgfmt", "--statistics", "$LANG.po");
493
&generate_po_template;
496
foreach my $lang (@languages) {
805
sub POFile_GetLanguage ($)
807
s/^(.*\/)?(.+)\.po$/$2/;
811
sub Console_Write_TranslationStatus
813
my ($lang, $output_file) = @_;
814
my $MSGFMT = $ENV{"MSGFMT"} || "/opt/gnome-devel/bin/msgfmt";
816
$output_file = "$lang.po" if ($output_file eq "");
818
system ("$MSGFMT", "-o", "/dev/null", "--statistics", $output_file);
821
sub Console_Write_CoverageReport
823
my $MSGFMT = $ENV{"MSGFMT"} || "/opt/gnome-devel/bin/msgfmt";
827
foreach my $lang (@languages)
498
&update_po_file ($lang);
830
&POFile_Update ($lang, "");
501
833
print "\n\n * Current translation support in $MODULE \n\n";
503
foreach my $lang (@languages){
505
system ("msgfmt", "--statistics", "$lang.po");
509
sub find_package_name
835
foreach my $lang (@languages)
838
system ("$MSGFMT", "-o", "/dev/null", "--statistics", "$lang.po");
842
sub SubstituteVariable
846
# always need to rewind file whenever it has been accessed
849
# cache each variable. varhash is global to we can add
850
# variables elsewhere.
855
($varhash{$1} = $2) =~ s/^["'](.*)["']$/$1/;
859
if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/)
863
my $sub = $varhash{$2};
865
return SubstituteVariable ("$untouched$sub$rest");
868
# We're using Perl backticks ` and "echo -n" here in order to
869
# expand any shell escapes (such as backticks themselves) in every variable
870
return `echo -n "$str"`;
511
875
my $base_dirname = getcwd();
512
876
$base_dirname =~ s@.*/@@;
514
878
my ($conf_in, $src_dir);
516
if ($base_dirname eq "po") {
517
if (-f "../configure.in") {
518
$conf_in = "../configure.in";
880
if ($base_dirname =~ /^po(-.+)?$/)
520
884
my $makefile_source;
522
open IN, "<Makefile" || die "can't open Makefile: $!";
887
open (IN, "<Makevars") || die "can't open Makevars: $!";
525
if (/^top_srcdir[ \t]*=/) {
891
if (/^top_builddir[ \t]*=/)
527
# print "${src_dir}\n";
894
$src_dir =~ s/^top_builddir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
897
if (-f "$src_dir" . "/configure.ac") {
898
$conf_in = "$src_dir" . "/configure.ac" . "\n";
900
$conf_in = "$src_dir" . "/configure.in" . "\n";
907
$conf_in || die "Cannot find top_builddir in Makevars.";
909
elsif (-f "../configure.ac")
911
$conf_in = "../configure.ac";
913
elsif (-f "../configure.in")
915
$conf_in = "../configure.in";
922
open (IN, "<Makefile") || return;
926
if (/^top_srcdir[ \t]*=/)
529
929
$src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
530
# print "${src_dir}\n";
532
932
$conf_in = "$src_dir" . "/configure.in" . "\n";
536
$conf_in || die "Cannot find top_srcdir in Makefile."
541
local $/; # slurp mode
542
open (IN, "<$conf_in") || die "can't open $conf_in: $!";
547
$name = $1 if $conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+)/m;
548
$name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=(\S+)/m;
549
if ($name =~ /^[\$](\S+)/) {
550
return $1 if $conf_source =~ /^\s*$1=(\S*)/m;
552
return $name if $name;
555
print "$PROGRAM: Unable to determine package name.\n" .
556
"Make sure to run this script inside the po directory.\n";
939
$conf_in || die "Cannot find top_srcdir in Makefile.";
942
open (CONF, "<$conf_in");
946
print STDERR "$PROGRAM: Unable to proceed.\n" .
947
"Make sure to run this script inside the po directory.\n";
955
my $domain = &FindMakevarsDomain;
956
my $name = $domain || "untitled";
962
open (IN, "<&CONF") || return $name;
964
local $/; # slurp mode
969
# priority for getting package name:
971
# 2. first argument of AC_INIT (with >= 2 arguments)
972
# 3. first argument of AM_INIT_AUTOMAKE (with >= 2 argument)
974
# /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m
975
# the \s makes this not work, why?
976
if ($conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+),([^,\)]+)/m)
978
($name, $version) = ($1, $2);
979
$name =~ s/[\[\]\s]//g;
980
$version =~ s/[\[\]\s]//g;
981
$varhash{"AC_PACKAGE_NAME"} = $name;
982
$varhash{"PACKAGE"} = $name;
983
$varhash{"AC_PACKAGE_VERSION"} = $version;
984
$varhash{"VERSION"} = $version;
987
if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)/m)
989
($name, $version) = ($1, $2);
990
$name =~ s/[\[\]\s]//g;
991
$version =~ s/[\[\]\s]//g;
992
$varhash{"AC_PACKAGE_NAME"} = $name;
993
$varhash{"PACKAGE"} = $name;
994
$varhash{"AC_PACKAGE_VERSION"} = $version;
995
$varhash{"VERSION"} = $version;
998
# \s makes this not work, why?
999
$name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m;
1001
# prepend '$' to auto* internal variables, usually they are
1002
# used in configure.in/ac without the '$'
1003
$name =~ s/AC_/\$AC_/g;
1004
$name =~ s/\$\$/\$/g;
1006
$name = $domain if $domain;
1008
$name = SubstituteVariable ($name);
1009
$name =~ s/^["'](.*)["']$/$1/;
1011
return $name if $name;
1018
my $keywords = "--keyword\=\_ --keyword\=N\_ --keyword\=U\_ --keyword\=Q\_";
1019
my $varname = "XGETTEXT_OPTIONS";
1022
open (IN, "<Makevars") || (open(IN, "<Makefile.in.in") && ($varname = "XGETTEXT_KEYWORDS")) || return $keywords;
1024
local $/; # slurp mode
1025
$make_source = <IN>;
1029
$keywords = $1 if $make_source =~ /^$varname[ ]*=\[?([^\n\]]+)/m;
1034
sub FindMakevarsDomain
1038
my $makevars_source; {
1040
open (IN, "<Makevars") || return $domain;
1042
local $/; # slurp mode
1043
$makevars_source = <IN>;
1047
$domain = $1 if $makevars_source =~ /^DOMAIN[ ]*=\[?([^\n\]\$]+)/m;
1048
$domain =~ s/^\s+//;
1049
$domain =~ s/\s+$//;