http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.03.tar.gz
[xscreensaver] / intltool-update.in
diff --git a/intltool-update.in b/intltool-update.in
new file mode 100644 (file)
index 0000000..43edc02
--- /dev/null
@@ -0,0 +1,602 @@
+#!@INTLTOOL_PERL@ -w
+
+#
+#  The Intltool Message Updater
+#
+#  Copyright (C) 2000-2002 Free Software Foundation.
+#
+#  Intltool is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License 
+#  version 2 published by the Free Software Foundation.
+#
+#  Intltool 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 the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#  As a special exception to the GNU General Public License, if you
+#  distribute this file as part of a program that contains a
+#  configuration script generated by Autoconf, you may include it under
+#  the same distribution terms that you use for the rest of that program.
+#
+#  Authors: Kenneth Christiansen <kenneth@gnu.org>
+#           Maciej Stachowiak
+#           Darin Adler <darin@bentspoon.com>
+
+## Release information
+my $PROGRAM = "intltool-update";
+my $VERSION = "0.18";
+my $PACKAGE = "intltool";
+
+## Loaded modules
+use strict;
+use Getopt::Long;
+use Cwd;
+use File::Copy;
+use File::Find;
+
+## Scalars used by the option stuff
+my $HELP_ARG      = 0;
+my $VERSION_ARG    = 0;
+my $DIST_ARG      = 0;
+my $POT_ARG       = 0;
+my $HEADERS_ARG    = 0;
+my $MAINTAIN_ARG   = 0;
+my $REPORT_ARG     = 0;
+my $VERBOSE       = 0;
+my $GETTEXT_PACKAGE = "";
+
+my @languages;
+my %po_files_by_lang = ();
+
+# Regular expressions to categorize file types.
+# FIXME: Please check if the following is correct
+
+my $xml_extension =
+"xml(\.in)*|".         # .in is not required
+"ui|".
+"glade2?(\.in)*|".     # .in is not required
+"scm(\.in)*|".         # .in is not required
+"oaf(\.in)+|".
+"etspec|".
+"sheet(\.in)+|".
+"pong(\.in)+";
+
+my $ini_extension =
+"desktop(\.in)+|".
+"caves(\.in)+|". 
+"directory(\.in)+|".
+"soundlist(\.in)+|".
+"keys(\.in)+|".
+"server(\.in)+";
+
+## Always print as the first thing
+$| = 1;
+
+## Handle options
+GetOptions 
+(
+ "help"               => \$HELP_ARG,
+ "version"            => \$VERSION_ARG,
+ "dist|d"             => \$DIST_ARG,
+ "pot|p"              => \$POT_ARG,
+ "headers|s"          => \$HEADERS_ARG,
+ "maintain|m"         => \$MAINTAIN_ARG,
+ "report|r"           => \$REPORT_ARG,
+ "verbose|x"          => \$VERBOSE,
+ "gettext-package|g=s" => \$GETTEXT_PACKAGE,
+ ) or &print_error_invalid_option;
+
+&print_help if $HELP_ARG;
+&print_version if $VERSION_ARG;
+
+my $arg_count = ($DIST_ARG > 0)
+    + ($POT_ARG > 0)
+    + ($HEADERS_ARG > 0)
+    + ($MAINTAIN_ARG > 0)
+    + ($REPORT_ARG > 0);
+&print_help if $arg_count > 1;
+
+# --version and --help don't require a module name
+my $MODULE = $GETTEXT_PACKAGE || &find_package_name;
+
+if ($DIST_ARG) {
+    if ($ARGV[0] =~ /^[a-z]/){
+        &update_po_file ($ARGV[0]);
+        &print_status ($ARGV[0]);
+    } else {
+        &print_help;
+    }
+} elsif ($POT_ARG) {
+    &generate_headers;
+    &generate_po_template;
+} elsif ($HEADERS_ARG) {
+    &generate_headers;
+} elsif ($MAINTAIN_ARG) {
+    &find_leftout_files;
+} elsif ($REPORT_ARG) {
+    &print_report;
+} else {
+    if ($ARGV[0] =~ /^[a-z]/) {
+        &main ($ARGV[0]);
+    } else {
+        &print_help;
+    }
+}
+
+exit;
+
+#########
+
+sub print_version
+{
+    ## Print version information
+    print "${PROGRAM} (${PACKAGE}) $VERSION\n";
+    print "Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler.\n\n";
+    print "Copyright (C) 2000-2002 Free Software Foundation, Inc.\n";
+    print "This is free software; see the source for copying conditions.  There is NO\n";
+    print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
+    exit;
+}
+
+sub print_help
+{
+    ## Print usage information
+    print "Usage: ${PROGRAM} [OPTIONS] ...LANGCODE\n";
+    print "Updates PO template files and merge them with the translations.\n\n";
+    print "  -p, --pot              generate the PO template only\n";
+    print "  -s, --headers          generate the header files in POTFILES.in\n";
+    print "  -m, --maintain         search for left out files from POTFILES.in\n";
+    print "  -r, --report           display a status report for the module.\n";
+    print "  -x, --verbose          display lots of feedback\n";
+    print "      --help             display this help and exit\n";
+    print "      --version          output version information and exit\n";
+    print "\nExamples of use:\n";
+    print "${PROGRAM} --pot    just creates a new PO template from the source\n";
+    print "${PROGRAM} da       created new PO template and updated the da.po file\n\n";
+    print "Report bugs to bugzilla.gnome.org, module 'intltool'.\n";
+    exit;
+}
+
+sub main
+{
+    my ($lang) = @_;
+
+    ## Report error if the language file supplied
+    ## to the command line is non-existent
+    &print_error_not_existing("$lang.po") if ! -s "$lang.po";
+
+    print "Working, please wait..." unless $VERBOSE;
+    &generate_headers;
+    &generate_po_template;
+    &update_po_file ($lang);
+    &print_status ($lang);
+}
+
+sub determine_type ($) 
+{
+   my $type = $_;
+   my $gettext_type;
+
+   # FIXME: Use $xml_extentions, and maybe do all this even nicer
+   my $xml_regex = 
+       "(?:xml(\.in)*|ui|oaf(?:\.in)+|server(?:\.in)+|sheet(?:\.in)+|".
+       "pong(?:\.in)+|etspec)";
+   my $ini_regex =
+       "(?:desktop(?:\.in)+|caves(?:\.in)+|directory(?:\.in)+|".
+       "soundlist(?:\.in)+)";
+
+   if ($type =~ /\[type: gettext\/([^\]].*)]/) {
+        $gettext_type=$1;
+   }
+   elsif ($type =~ /$xml_regex$/) {
+        $gettext_type="xml";
+   }
+   elsif ($type =~ /glade2?(\.in)*$/) {
+        $gettext_type="glade";
+   }
+   elsif ($type =~ /$ini_regex$/) { 
+        $gettext_type="ini";
+   }
+   elsif ($type =~ /scm(\.in)*$/) {
+        $gettext_type="scheme";
+   }
+   elsif ($type =~ /keys(\.in)+$/) {
+        $gettext_type="keys";
+   }
+   else { $gettext_type=""; }
+
+   return "gettext\/$gettext_type";
+}
+
+sub find_leftout_files
+{
+    my (@buf_i18n_plain,
+       @buf_i18n_xml,
+       @buf_i18n_ini,
+       @buf_potfiles,
+       @buf_potfiles_ignore,
+       @buf_allfiles,
+       @buf_allfiles_sorted,
+       @buf_potfiles_sorted
+    );
+
+    ## Search and find all translatable files
+    find sub { 
+       push @buf_i18n_plain, "$File::Find::name" if /\.(c|y|cc|cpp|c\+\+|h|gob)$/ 
+       }, "..";
+    find sub { 
+       push @buf_i18n_xml, "$File::Find::name" if /\.($xml_extension)$/ 
+       }, "..";
+    find sub {
+       push @buf_i18n_ini, "$File::Find::name" if /\.($ini_extension)$/ 
+       }, "..";
+
+    open POTFILES, "POTFILES.in" || die "$PROGRAM:  there's no POTFILES.in!\n";
+
+    @buf_potfiles = grep /^[^#]/, <POTFILES>;
+                           
+    print "Searching for missing translatable files...\n" if $VERBOSE;
+
+    ## Check if we should ignore some found files, when
+    ## comparing with POTFILES.in
+    foreach my $ignore ("POTFILES.skip", "POTFILES.ignore") {
+        if (-s $ignore) {
+            open FILE, $ignore;
+            while (<FILE>) {
+                if (/^[^#]/){
+                    push @buf_potfiles_ignore, $_;
+                }
+            }
+           print "Found $ignore: Ignoring files...\n" if $VERBOSE;
+            @buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles);
+        }
+    }
+
+    foreach my $file (@buf_i18n_plain)
+      {
+        my $in_comment = 0;
+       my $in_macro = 0;
+
+        open FILE, "<$file";
+        while (<FILE>)
+         {
+           # Handle continued multi-line comment.
+           if ($in_comment)
+             {
+               next unless s-.*\*/--;
+               $in_comment = 0;
+             }
+
+           # Handle continued macro.
+           if ($in_macro)
+             {
+               $in_macro = 0 unless /\\$/;
+               next;
+             }
+
+           # Handle start of macro (or any preprocessor directive).
+           if (/^\s*\#/)
+             {
+               $in_macro = 1 if /^([^\\]|\\.)*\\$/;
+               next;
+             }
+
+           # Handle comments and quoted text.
+           while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy
+             {
+               my $match = $1;
+               if ($match eq "/*")
+                 {
+                   if (!s-/\*.*?\*/--)
+                     {
+                       s-/\*.*--;
+                       $in_comment = 1;
+                     }
+                 }
+               elsif ($match eq "//")
+                 {
+                   s-//.*--;
+                 }
+               else # ' or "
+                 {
+                   if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-)
+                     {
+                       warn "mismatched quotes at line $. in $file\n";
+                       s-$match.*--;
+                     }
+                 }
+             }
+       
+
+           if (/_\(QUOTEDTEXT/)
+             {
+               ## Remove the first 3 chars and add newline
+               push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+               last;
+             }
+         }
+       close FILE;
+      }
+
+    foreach my $file (@buf_i18n_xml) {
+        open FILE, "<$file";
+        while (<FILE>) {
+            if (/\s_(.*)=\"/){
+                push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+                last;
+            }
+        }
+    }
+
+    foreach my $file (@buf_i18n_ini){
+        open FILE, "<$file";
+        while (<FILE>) {
+            if (/_(.*)=/){
+                push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+                last;
+            }
+        }
+    }
+
+    @buf_allfiles_sorted = sort (@buf_allfiles);
+    @buf_potfiles_sorted = sort (@buf_potfiles);
+
+    my %in2;
+    foreach (@buf_potfiles_sorted) {
+        $in2{$_} = 1;
+    }
+
+    my @result;
+
+    foreach (@buf_allfiles_sorted){
+        if (!exists($in2{$_})){
+            push @result, $_
+        }
+    }
+
+    ## Save file with information about the files missing
+    ## if any, and give information about this procedure.
+    if (@result) {
+       print "\n" if $VERBOSE;
+        open OUT, ">missing";
+        print OUT @result;
+        print "The following files contain translations and are currently not in use. Please\n";
+       print "consider adding these to the POTFILES.in file, located in the po/ directory.\n\n";
+       print @result, "\n";
+       print "If some of these files are left out on purpose then please add them to\n";
+       print "POTFILES.skip instead of POTFILES.in. A file 'missing' containing this list\n";
+        print "of left out files has been written in the current directory.\n";
+    }
+
+    ## If there is nothing to complain about, notify the user
+    else {
+        print "\nAll files containing translations are present in POTFILES.in.\n";
+    }
+}
+
+sub print_error_invalid_option
+{
+    ## Handle invalid arguments
+    print "Try `${PROGRAM} --help' for more information.\n";
+    exit 1;
+}
+
+sub generate_headers
+{
+    my $EXTRACT = `which intltool-extract 2>/dev/null`;
+    chomp $EXTRACT;
+
+    $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"};
+
+    ## Generate the .h header files, so we can allow glade and
+    ## xml translation support
+    if (! -s $EXTRACT)
+    {
+       print "\n *** The intltool-extract script wasn't found!"
+            ."\n *** Without it, intltool-update can not generate files.\n";
+       exit;
+    }
+    else
+    {
+        open FILE, "<POTFILES.in";
+        while (<FILE>) {
+           chomp;
+
+           ## Find xml files in POTFILES.in and generate the
+           ## files with help from the extract script
+
+          my $gettext_type= &determine_type ($1);
+
+           if (/\.($xml_extension|$ini_extension)$/ || /^\[/){
+              $_ =~ s/^\[[^\[].*]\s*//;
+               my $filename = "../$_";
+
+               if ($VERBOSE){
+                   system($EXTRACT, "--update", "--type=$gettext_type", $filename);
+               } else {
+                  system($EXTRACT, "--update", "--type=$gettext_type", "--quiet", $filename);
+               }
+           }
+       }
+       close FILE;
+   }
+}
+
+sub generate_po_template
+{
+    ## Generate the potfiles from the POTFILES.in file
+
+    print "Building the $MODULE.pot...\n" if $VERBOSE;
+
+    move ("POTFILES.in", "POTFILES.in.old");
+
+    open INFILE, "<POTFILES.in.old";
+    open OUTFILE, ">POTFILES.in";
+    while (<INFILE>) {
+        s/\.($xml_extension|$ini_extension)$/$&.h/;
+        s/^\[.*]\s*(.*)/$1.h/;
+        print OUTFILE $_;
+    }
+    close OUTFILE;
+    close INFILE;
+
+    system ("xgettext", "--default-domain\=$MODULE", 
+                       "--directory\=\.\.",
+                       "--add-comments", 
+                       "--keyword\=\_", 
+                       "--keyword\=N\_", 
+                       "--keyword\=U\_",
+                       "--files-from\=\.\/POTFILES\.in");
+
+    if (!-e "$MODULE.po") {
+        print "WARNING: It seems that none of the files in POTFILES.in ".
+              "contain marked strings\n";
+        exit (1);
+    }
+
+    system ("rm", "-f", "$MODULE.pot");
+    move ("$MODULE.po", "$MODULE.pot") || die "$PROGRAM: couldn't move $MODULE.po to $MODULE.pot.\n";
+
+    print "Wrote $MODULE.pot\n" if $VERBOSE;
+
+    move ("POTFILES.in.old", "POTFILES.in");
+
+    print "Removing generated header (.h) files..." if $VERBOSE;
+
+    open FILE, "<POTFILES.in";
+
+    while (<FILE>)
+    {
+        chomp;
+        unlink "../$_.h" if /\.($xml_extension|$ini_extension)$/;
+    }
+
+    close FILE;
+    print "done\n" if $VERBOSE;
+}
+
+sub update_po_file
+{
+    my ($lang) = @_;
+
+    print "Merging $lang.po with $MODULE.pot..." if $VERBOSE;
+
+    copy ("$lang.po", "$lang.po.old") || die "copy failed: $!";
+
+    # Perform merge, remove backup file and the "messages" trash file 
+    # generated by gettext
+    system ("msgmerge", "$lang.po.old", "$MODULE.pot", "-o", "$lang.po");
+    unlink "$lang.po.old";
+    unlink "messages";
+}
+
+sub print_error_not_existing
+{
+    my ($file) = @_;
+
+    ## Report error if supplied language file is non-existing
+    print "$PROGRAM: $file does not exist!\n";
+    print "Try '$PROGRAM --help' for more information.\n";
+    exit;
+}
+
+sub gather_po_files
+{
+    my @po_files = glob ("./*.po");
+
+    @languages = map (&po_file2lang, @po_files);
+
+    foreach my $lang (@languages) {
+       $po_files_by_lang{$lang} = shift (@po_files);
+    }
+}
+
+sub po_file2lang ($)
+{
+    my $tmp = $_;
+    $tmp =~ s/^.*\/(.*)\.po$/$1/;
+    return $tmp;
+}
+
+sub print_status
+{
+    my ($lang) = @_;
+
+    system ("msgfmt", "--statistics", "$lang.po");
+    print "\n";
+}
+
+sub print_report
+{
+    &generate_headers;
+    &generate_po_template;
+    &gather_po_files;
+
+    foreach my $lang (@languages) {
+       print "$lang: ";
+       &update_po_file ($lang);
+    }
+
+    print "\n\n * Current translation support in $MODULE \n\n";
+
+    foreach my $lang (@languages){
+        print "$lang: ";
+       system ("msgfmt", "--statistics", "$lang.po");
+    }
+}
+
+sub find_package_name
+{
+    my $base_dirname = getcwd();
+    $base_dirname =~ s@.*/@@;
+
+    my ($conf_in, $src_dir);
+
+    if ($base_dirname =~ /^po(-.+)?$/) {
+        if (-f "../configure.in") {
+            $conf_in = "../configure.in";
+        } else {
+           my $makefile_source;
+           local (*IN);
+           open IN, "<Makefile" || die "can't open Makefile: $!";
+
+           while (<IN>) {
+               if (/^top_srcdir[ \t]*=/) {
+                   $src_dir = $_;
+                   # print "${src_dir}\n";
+
+                   $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
+                   # print "${src_dir}\n";
+                   chomp $src_dir;
+                   $conf_in = "$src_dir" . "/configure.in" . "\n";
+                   last;
+               }
+           }
+           $conf_in || die "Cannot find top_srcdir in Makefile."
+        }
+
+        my $conf_source; {
+           local (*IN);
+           local $/; # slurp mode
+           open (IN, "<$conf_in") || die "can't open $conf_in: $!";
+           $conf_source = <IN>;
+        }
+
+       my $name = "";
+       $name = $1 if $conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+)/m;
+       $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=(\S+)/m;
+       if ($name =~ /^[\$](\S+)/) {
+            return $1 if $conf_source =~ /^\s*$1=(\S*)/m;
+        }
+       return $name if $name;
+    }
+
+    print "$PROGRAM: Unable to determine package name.\n" .
+         "Make sure to run this script inside the po directory.\n";
+    exit;
+}