forked from mirrors/linphone-iphone
fix network state automatic management (wasn't working)
This commit is contained in:
parent
4c4204ef96
commit
b88fb9a025
6 changed files with 38 additions and 1643 deletions
|
|
@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
/*#define UNSTANDART_GSM_11K 1*/
|
||||
|
||||
static const char *liblinphone_version=LIBLINPHONE_VERSION;
|
||||
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable);
|
||||
|
||||
#include "enum.h"
|
||||
|
||||
|
|
@ -1403,28 +1404,31 @@ static void linphone_core_disconnected(LinphoneCore *lc){
|
|||
linphone_core_terminate_call(lc,NULL);
|
||||
}
|
||||
|
||||
static void proxy_update(LinphoneCore *lc, time_t curtime){
|
||||
|
||||
static void monitor_network_state(LinphoneCore *lc, time_t curtime){
|
||||
static time_t last_check=0;
|
||||
static bool_t last_status=FALSE;
|
||||
if (lc->sip_conf.register_only_when_network_is_up){
|
||||
char result[LINPHONE_IPADDR_SIZE];
|
||||
/* only do the network up checking every five seconds */
|
||||
if (last_check==0 || (curtime-last_check)>=5){
|
||||
if (eXosip_guess_localip(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,result,LINPHONE_IPADDR_SIZE)==0){
|
||||
if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){
|
||||
last_status=TRUE;
|
||||
ms_message("Network is up, registering now (%s)",result);
|
||||
}else last_status=FALSE;
|
||||
}
|
||||
last_check=curtime;
|
||||
char result[LINPHONE_IPADDR_SIZE];
|
||||
bool_t new_status;
|
||||
|
||||
/* only do the network up checking every five seconds */
|
||||
if (last_check==0 || (curtime-last_check)>=5){
|
||||
if (eXosip_guess_localip(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,result,LINPHONE_IPADDR_SIZE)==0){
|
||||
if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){
|
||||
new_status=TRUE;
|
||||
}else new_status=FALSE;
|
||||
}
|
||||
last_check=curtime;
|
||||
if (new_status!=last_status) {
|
||||
set_network_reachable(lc,new_status);
|
||||
last_status=new_status;
|
||||
}
|
||||
linphone_core_set_network_reachable(lc,last_status);
|
||||
}else {
|
||||
ms_list_for_each(lc->sip_conf.proxies,(void (*)(void*))&linphone_proxy_config_update);
|
||||
}
|
||||
}
|
||||
|
||||
static void proxy_update(LinphoneCore *lc){
|
||||
ms_list_for_each(lc->sip_conf.proxies,(void (*)(void*))&linphone_proxy_config_update);
|
||||
}
|
||||
|
||||
static void assign_buddy_info(LinphoneCore *lc, BuddyInfo *info){
|
||||
LinphoneFriend *lf=linphone_core_get_friend_by_uri(lc,info->sip_uri);
|
||||
if (lf!=NULL){
|
||||
|
|
@ -1542,7 +1546,9 @@ void linphone_core_iterate(LinphoneCore *lc)
|
|||
}
|
||||
}
|
||||
|
||||
proxy_update(lc,curtime);
|
||||
if (lc->auto_net_state_mon) monitor_network_state(lc,curtime);
|
||||
|
||||
proxy_update(lc);
|
||||
|
||||
if (lc->call!=NULL){
|
||||
LinphoneCall *call=lc->call;
|
||||
|
|
@ -3490,12 +3496,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
gstate_new_state(lc, GSTATE_POWER_OFF, NULL);
|
||||
}
|
||||
|
||||
void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t isReachable) {
|
||||
//first disable automatic mode
|
||||
if (lc->auto_net_state_mon) {
|
||||
ms_message("Disabling automatic network state monitoring");
|
||||
lc->auto_net_state_mon=FALSE;
|
||||
}
|
||||
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable){
|
||||
ms_message("Network state is now [%s]",isReachable?"UP":"DOWN");
|
||||
// second get the list of available proxies
|
||||
const MSList *elem=linphone_core_get_proxy_config_list(lc);
|
||||
|
|
@ -3504,14 +3505,21 @@ void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t isReachable) {
|
|||
if (linphone_proxy_config_register_enabled(cfg) ) {
|
||||
if (!isReachable) {
|
||||
cfg->registered=0;
|
||||
}else{
|
||||
cfg->commit=TRUE;
|
||||
} else {
|
||||
linphone_proxy_config_update(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
lc->network_reachable=isReachable;
|
||||
}
|
||||
|
||||
void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t isReachable) {
|
||||
//first disable automatic mode
|
||||
if (lc->auto_net_state_mon) {
|
||||
ms_message("Disabling automatic network state monitoring");
|
||||
lc->auto_net_state_mon=FALSE;
|
||||
}
|
||||
set_network_reachable(lc,isReachable);
|
||||
}
|
||||
/**
|
||||
* Destroys a LinphoneCore
|
||||
|
|
|
|||
|
|
@ -661,6 +661,7 @@ typedef struct _LinphoneCore
|
|||
* In case of false, network state must be communicate to linphone core with method linphone_core_
|
||||
*/
|
||||
bool_t auto_net_state_mon;
|
||||
bool_t network_reachable;
|
||||
} LinphoneCore;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -913,11 +913,13 @@ SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfig *cfg){
|
|||
}
|
||||
|
||||
void linphone_proxy_config_update(LinphoneProxyConfig *cfg){
|
||||
LinphoneCore *lc=cfg->lc;
|
||||
if (cfg->commit){
|
||||
if (cfg->type && cfg->ssctx==NULL){
|
||||
linphone_proxy_config_activate_sip_setup(cfg);
|
||||
}
|
||||
linphone_proxy_config_register(cfg);
|
||||
if (lc->sip_conf.register_only_when_network_is_up || lc->network_reachable)
|
||||
linphone_proxy_config_register(cfg);
|
||||
cfg->commit=FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,325 +0,0 @@
|
|||
#!@INTLTOOL_PERL@ -w
|
||||
# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
|
||||
#
|
||||
# The Intltool Message Extractor
|
||||
#
|
||||
# Copyright (C) 2000-2001 Free Software Foundation.
|
||||
#
|
||||
# Intltool is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# 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>
|
||||
# Darin Adler <darin@bentspoon.com>
|
||||
#
|
||||
|
||||
## Release information
|
||||
my $PROGRAM = "intltool-extract";
|
||||
my $PACKAGE = "intltool";
|
||||
my $VERSION = "0.22";
|
||||
|
||||
## Loaded modules
|
||||
use strict;
|
||||
use File::Basename;
|
||||
use Getopt::Long;
|
||||
|
||||
## Scalars used by the option stuff
|
||||
my $TYPE_ARG = "0";
|
||||
my $LOCAL_ARG = "0";
|
||||
my $HELP_ARG = "0";
|
||||
my $VERSION_ARG = "0";
|
||||
my $UPDATE_ARG = "0";
|
||||
my $QUIET_ARG = "0";
|
||||
|
||||
my $FILE;
|
||||
my $OUTFILE;
|
||||
|
||||
my $gettext_type = "";
|
||||
my $input;
|
||||
my %messages = ();
|
||||
|
||||
## Use this instead of \w for XML files to handle more possible characters.
|
||||
my $w = "[-A-Za-z0-9._:]";
|
||||
|
||||
## Always print first
|
||||
$| = 1;
|
||||
|
||||
## Handle options
|
||||
GetOptions (
|
||||
"type=s" => \$TYPE_ARG,
|
||||
"local|l" => \$LOCAL_ARG,
|
||||
"help|h" => \$HELP_ARG,
|
||||
"version|v" => \$VERSION_ARG,
|
||||
"update" => \$UPDATE_ARG,
|
||||
"quiet|q" => \$QUIET_ARG,
|
||||
) or &error;
|
||||
|
||||
&split_on_argument;
|
||||
|
||||
|
||||
## Check for options.
|
||||
## This section will check for the different options.
|
||||
|
||||
sub split_on_argument {
|
||||
|
||||
if ($VERSION_ARG) {
|
||||
&version;
|
||||
|
||||
} elsif ($HELP_ARG) {
|
||||
&help;
|
||||
|
||||
} elsif ($LOCAL_ARG) {
|
||||
&place_local;
|
||||
&extract;
|
||||
|
||||
} elsif ($UPDATE_ARG) {
|
||||
&place_normal;
|
||||
&extract;
|
||||
|
||||
} elsif (@ARGV > 0) {
|
||||
&place_normal;
|
||||
&message;
|
||||
&extract;
|
||||
|
||||
} else {
|
||||
&help;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sub place_normal {
|
||||
$FILE = $ARGV[0];
|
||||
$OUTFILE = "$FILE.h";
|
||||
}
|
||||
|
||||
sub place_local {
|
||||
$OUTFILE = fileparse($FILE, ());
|
||||
if (!-e "tmp/") {
|
||||
system("mkdir tmp/");
|
||||
}
|
||||
$OUTFILE = "./tmp/$OUTFILE.h"
|
||||
}
|
||||
|
||||
sub determine_type {
|
||||
if ($TYPE_ARG =~ /^gettext\/(.*)/) {
|
||||
$gettext_type=$1
|
||||
}
|
||||
}
|
||||
|
||||
## Sub for printing release information
|
||||
sub version{
|
||||
print "${PROGRAM} (${PACKAGE}) $VERSION\n";
|
||||
print "Copyright (C) 2000 Free Software Foundation, Inc.\n";
|
||||
print "Written by Kenneth Christiansen, 2000.\n\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 for printing usage information
|
||||
sub help{
|
||||
print "Usage: ${PROGRAM} [FILENAME] [OPTIONS] ...\n";
|
||||
print "Generates a header file from an xml source file.\n\nGrabs all strings ";
|
||||
print "between <_translatable_node> and it's end tag,\nwhere tag are all allowed ";
|
||||
print "xml tags. Read the docs for more info.\n\n";
|
||||
print " -v, --version shows the version\n";
|
||||
print " -h, --help shows this help page\n";
|
||||
print " -q, --quiet quiet mode\n";
|
||||
print "\nReport bugs to <kenneth\@gnu.org>.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
## Sub for printing error messages
|
||||
sub error{
|
||||
print "Try `${PROGRAM} --help' for more information.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
sub message {
|
||||
print "Generating C format header file for translation.\n";
|
||||
}
|
||||
|
||||
sub extract {
|
||||
&determine_type;
|
||||
|
||||
&convert ($FILE);
|
||||
|
||||
open OUT, ">$OUTFILE";
|
||||
&msg_write;
|
||||
close OUT;
|
||||
|
||||
print "Wrote $OUTFILE\n" unless $QUIET_ARG;
|
||||
}
|
||||
|
||||
sub convert($) {
|
||||
|
||||
## Reading the file
|
||||
{
|
||||
local (*IN);
|
||||
local $/; #slurp mode
|
||||
open (IN, "<$FILE") || die "can't open $FILE: $!";
|
||||
$input = <IN>;
|
||||
}
|
||||
|
||||
&type_ini if $gettext_type eq "ini";
|
||||
&type_keys if $gettext_type eq "keys";
|
||||
&type_xml if $gettext_type eq "xml";
|
||||
&type_glade if $gettext_type eq "glade";
|
||||
&type_scheme if $gettext_type eq "scheme";
|
||||
&type_schemas if $gettext_type eq "schemas";
|
||||
}
|
||||
|
||||
sub entity_decode_minimal
|
||||
{
|
||||
local ($_) = @_;
|
||||
|
||||
s/'/'/g; # '
|
||||
s/"/"/g; # "
|
||||
s/&/&/g;
|
||||
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub entity_decode
|
||||
{
|
||||
local ($_) = @_;
|
||||
|
||||
s/'/'/g; # '
|
||||
s/"/"/g; # "
|
||||
s/&/&/g;
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub escape_char
|
||||
{
|
||||
return '\"' if $_ eq '"';
|
||||
return '\n' if $_ eq "\n";
|
||||
return '\\' if $_ eq '\\';
|
||||
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub escape
|
||||
{
|
||||
my ($string) = @_;
|
||||
return join "", map &escape_char, split //, $string;
|
||||
}
|
||||
|
||||
sub type_ini {
|
||||
### For generic translatable desktop files ###
|
||||
while ($input =~ /^_.*=(.*)$/mg) {
|
||||
$messages{$1} = [];
|
||||
}
|
||||
}
|
||||
|
||||
sub type_keys {
|
||||
### For generic translatable mime/keys files ###
|
||||
while ($input =~ /^\s*_\w+=(.*)$/mg) {
|
||||
$messages{$1} = [];
|
||||
}
|
||||
}
|
||||
|
||||
sub type_xml {
|
||||
### For generic translatable XML files ###
|
||||
|
||||
while ($input =~ /\s_$w+=\"([^"]+)\"/sg) { # "
|
||||
$messages{entity_decode_minimal($1)} = [];
|
||||
}
|
||||
|
||||
while ($input =~ /<_($w+)>(.+?)<\/_\1>/sg) {
|
||||
$_ = $2;
|
||||
s/\s+/ /g;
|
||||
s/^ //;
|
||||
s/ $//;
|
||||
$messages{entity_decode_minimal($_)} = [];
|
||||
}
|
||||
}
|
||||
|
||||
sub type_schemas {
|
||||
### For schemas XML files ###
|
||||
|
||||
# FIXME: We should handle escaped < (less than)
|
||||
while ($input =~ /<(short|long)>([^<]+)<\/\1>/sg) {
|
||||
$_ = $2;
|
||||
s/\s+/ /g;
|
||||
s/^ //;
|
||||
s/ $//;
|
||||
$messages{entity_decode_minimal($_)} = [];
|
||||
}
|
||||
}
|
||||
|
||||
sub type_glade {
|
||||
### For translatable Glade XML files ###
|
||||
|
||||
my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message";
|
||||
|
||||
while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) {
|
||||
# Glade sometimes uses tags that normally mark translatable things for
|
||||
# little bits of non-translatable content. We work around this by not
|
||||
# translating strings that only includes something like label4 or window1.
|
||||
$messages{entity_decode($2)} = [] unless $2 =~ /^(window|label)[0-9]+$/;
|
||||
}
|
||||
|
||||
while ($input =~ /<items>(..[^<]*)<\/items>/sg) {
|
||||
for my $item (split (/\n/, $1)) {
|
||||
$messages{entity_decode($item)} = [];
|
||||
}
|
||||
}
|
||||
|
||||
## handle new glade files
|
||||
while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"[^>]*>([^<]+)<\/\1>/sg) {
|
||||
$messages{entity_decode($2)} = [] unless $2 =~ /^(window|label)[0-9]+$/;
|
||||
}
|
||||
while ($input =~ /<atkaction\s+action_name="([^>]*)"\s+description="([^>]+)"\/>/sg) {
|
||||
$messages{entity_decode_minimal($2)} = [];
|
||||
}
|
||||
}
|
||||
|
||||
sub type_scheme {
|
||||
while ($input =~ /_\(?"((?:[^"\\]+|\\.)*)"\)?/sg) {
|
||||
$messages{$1} = [];
|
||||
}
|
||||
}
|
||||
|
||||
sub msg_write {
|
||||
for my $message (sort keys %messages) {
|
||||
print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/;
|
||||
|
||||
my @lines = split (/\n/, $message);
|
||||
for (my $n = 0; $n < @lines; $n++) {
|
||||
if ($n == 0) {
|
||||
print OUT "char *s = N_(\"";
|
||||
} else {
|
||||
print OUT " \"";
|
||||
}
|
||||
|
||||
print OUT escape($lines[$n]);
|
||||
|
||||
if ($n < @lines - 1) {
|
||||
print OUT "\\n\"\n";
|
||||
} else {
|
||||
print OUT "\");\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,657 +0,0 @@
|
|||
#!@INTLTOOL_PERL@ -w
|
||||
|
||||
#
|
||||
# The Intltool Message Merger
|
||||
#
|
||||
# Copyright (C) 2000, 2002 Free Software Foundation.
|
||||
# Copyright (C) 2000, 2001 Eazel, Inc
|
||||
#
|
||||
# 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: Maciej Stachowiak <mjs@noisehavoc.org>
|
||||
# Kenneth Christiansen <kenneth@gnu.org>
|
||||
# Darin Adler <darin@bentspoon.com>
|
||||
#
|
||||
# Proper XML UTF-8'ification written by Cyrille Chepelov <chepelov@calixo.net>
|
||||
#
|
||||
|
||||
## Release information
|
||||
my $PROGRAM = "intltool-merge";
|
||||
my $PACKAGE = "intltool";
|
||||
my $VERSION = "0.22";
|
||||
|
||||
## Loaded modules
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
## Scalars used by the option stuff
|
||||
my $HELP_ARG = 0;
|
||||
my $VERSION_ARG = 0;
|
||||
my $BA_STYLE_ARG = 0;
|
||||
my $XML_STYLE_ARG = 0;
|
||||
my $KEYS_STYLE_ARG = 0;
|
||||
my $DESKTOP_STYLE_ARG = 0;
|
||||
my $SCHEMAS_STYLE_ARG = 0;
|
||||
my $QUIET_ARG = 0;
|
||||
my $PASS_THROUGH_ARG = 0;
|
||||
my $UTF8_ARG = 0;
|
||||
my $cache_file;
|
||||
|
||||
## Handle options
|
||||
GetOptions
|
||||
(
|
||||
"help" => \$HELP_ARG,
|
||||
"version" => \$VERSION_ARG,
|
||||
"quiet|q" => \$QUIET_ARG,
|
||||
"oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility
|
||||
"ba-style|b" => \$BA_STYLE_ARG,
|
||||
"xml-style|x" => \$XML_STYLE_ARG,
|
||||
"keys-style|k" => \$KEYS_STYLE_ARG,
|
||||
"desktop-style|d" => \$DESKTOP_STYLE_ARG,
|
||||
"schemas-style|s" => \$SCHEMAS_STYLE_ARG,
|
||||
"pass-through|p" => \$PASS_THROUGH_ARG,
|
||||
"utf8|u" => \$UTF8_ARG,
|
||||
"cache|c=s" => \$cache_file
|
||||
) or &error;
|
||||
|
||||
my $PO_DIR;
|
||||
my $FILE;
|
||||
my $OUTFILE;
|
||||
|
||||
my %po_files_by_lang = ();
|
||||
my %translations = ();
|
||||
|
||||
# Use this instead of \w for XML files to handle more possible characters.
|
||||
my $w = "[-A-Za-z0-9._:]";
|
||||
|
||||
# XML quoted string contents
|
||||
my $q = "[^\\\"]*";
|
||||
|
||||
## Check for options.
|
||||
|
||||
if ($VERSION_ARG) {
|
||||
&print_version;
|
||||
} elsif ($HELP_ARG) {
|
||||
&print_help;
|
||||
} elsif ($BA_STYLE_ARG && @ARGV > 2) {
|
||||
&preparation;
|
||||
&print_message;
|
||||
&ba_merge_translations;
|
||||
&finalize;
|
||||
} elsif ($XML_STYLE_ARG && @ARGV > 2) {
|
||||
&utf8_sanity_check;
|
||||
&preparation;
|
||||
&print_message;
|
||||
&xml_merge_translations;
|
||||
&finalize;
|
||||
} elsif ($KEYS_STYLE_ARG && @ARGV > 2) {
|
||||
&utf8_sanity_check;
|
||||
&preparation;
|
||||
&print_message;
|
||||
&keys_merge_translations;
|
||||
&finalize;
|
||||
} elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) {
|
||||
&preparation;
|
||||
&print_message;
|
||||
&desktop_merge_translations;
|
||||
&finalize;
|
||||
} elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) {
|
||||
&preparation;
|
||||
&print_message;
|
||||
&schemas_merge_translations;
|
||||
&finalize;
|
||||
} else {
|
||||
&print_help;
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
## Sub for printing release information
|
||||
sub print_version
|
||||
{
|
||||
print "${PROGRAM} (${PACKAGE}) ${VERSION}\n";
|
||||
print "Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen.\n\n";
|
||||
print "Copyright (C) 2000-2002 Free Software Foundation, Inc.\n";
|
||||
print "Copyright (C) 2000-2001 Eazel, 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 for printing usage information
|
||||
sub print_help
|
||||
{
|
||||
print "Usage: ${PROGRAM} [OPTIONS] PO_DIRECTORY FILENAME OUTPUT_FILE\n";
|
||||
print "Generates an output file that includes translated versions of some attributes,\n";
|
||||
print "from an untranslated source and a po directory that includes translations.\n\n";
|
||||
print " -b, --ba-style includes translations in the bonobo-activation style\n";
|
||||
print " -d, --desktop-style includes translations in the desktop style\n";
|
||||
print " -k, --keys-style includes translations in the keys style\n";
|
||||
print " -s, --schemas-style includes translations in the schemas style\n";
|
||||
print " -x, --xml-style includes translations in the standard xml style\n";
|
||||
print " -u, --utf8 convert all strings to UTF-8 before merging\n";
|
||||
print " -p, --pass-through use strings as found in .po files, without\n";
|
||||
print " conversion (STRONGLY unrecommended with -x)\n";
|
||||
print " -q, --quiet suppress most messages\n";
|
||||
print " --help display this help and exit\n";
|
||||
print " --version output version information and exit\n";
|
||||
print "\nReport bugs to bugzilla.gnome.org, module intltool, or contact us through \n";
|
||||
print "<xml-i18n-tools-list\@gnome.org>.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
## Sub for printing error messages
|
||||
sub print_error
|
||||
{
|
||||
print "Try `${PROGRAM} --help' for more information.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
sub print_message
|
||||
{
|
||||
print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG;
|
||||
}
|
||||
|
||||
|
||||
sub preparation
|
||||
{
|
||||
$PO_DIR = $ARGV[0];
|
||||
$FILE = $ARGV[1];
|
||||
$OUTFILE = $ARGV[2];
|
||||
|
||||
&gather_po_files;
|
||||
&get_translation_database;
|
||||
}
|
||||
|
||||
# General-purpose code for looking up translations in .po files
|
||||
|
||||
sub po_file2lang
|
||||
{
|
||||
my ($tmp) = @_;
|
||||
$tmp =~ s/^.*\/(.*)\.po$/$1/;
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
sub gather_po_files
|
||||
{
|
||||
for my $po_file (glob "$PO_DIR/*.po") {
|
||||
$po_files_by_lang{po_file2lang($po_file)} = $po_file;
|
||||
}
|
||||
}
|
||||
|
||||
sub get_po_encoding
|
||||
{
|
||||
my ($in_po_file) = @_;
|
||||
my $encoding = "";
|
||||
|
||||
open IN_PO_FILE, $in_po_file or die;
|
||||
while (<IN_PO_FILE>) {
|
||||
## example: "Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) {
|
||||
$encoding = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN_PO_FILE;
|
||||
|
||||
if (!$encoding) {
|
||||
print "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n";
|
||||
$encoding = "ISO-8859-1";
|
||||
}
|
||||
return $encoding
|
||||
}
|
||||
|
||||
sub utf8_sanity_check
|
||||
{
|
||||
if (!$UTF8_ARG) {
|
||||
if (!$PASS_THROUGH_ARG) {
|
||||
$PASS_THROUGH_ARG="1";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_translation_database
|
||||
{
|
||||
if ($cache_file) {
|
||||
&get_cached_translation_database;
|
||||
} else {
|
||||
&create_translation_database;
|
||||
}
|
||||
}
|
||||
|
||||
sub get_newest_po_age
|
||||
{
|
||||
my $newest_age;
|
||||
|
||||
foreach my $file (values %po_files_by_lang) {
|
||||
my $file_age = -M $file;
|
||||
$newest_age = $file_age if !$newest_age || $file_age < $newest_age;
|
||||
}
|
||||
|
||||
return $newest_age;
|
||||
}
|
||||
|
||||
sub create_cache
|
||||
{
|
||||
print "Generating and caching the translation database\n" unless $QUIET_ARG;
|
||||
|
||||
&create_translation_database;
|
||||
|
||||
open CACHE, ">$cache_file" || die;
|
||||
print CACHE join "\x01", %translations;
|
||||
close CACHE;
|
||||
}
|
||||
|
||||
sub load_cache
|
||||
{
|
||||
print "Found cached translation database\n" unless $QUIET_ARG;
|
||||
|
||||
my $contents;
|
||||
open CACHE, "<$cache_file" || die;
|
||||
{
|
||||
local $/;
|
||||
$contents = <CACHE>;
|
||||
}
|
||||
close CACHE;
|
||||
%translations = split "\x01", $contents;
|
||||
}
|
||||
|
||||
sub get_cached_translation_database
|
||||
{
|
||||
my $cache_file_age = -M $cache_file;
|
||||
if (defined $cache_file_age) {
|
||||
if ($cache_file_age <= &get_newest_po_age) {
|
||||
&load_cache;
|
||||
return;
|
||||
}
|
||||
print "Found too-old cached translation database\n" unless $QUIET_ARG;
|
||||
}
|
||||
|
||||
&create_cache;
|
||||
}
|
||||
|
||||
sub create_translation_database
|
||||
{
|
||||
for my $lang (keys %po_files_by_lang) {
|
||||
my $po_file = $po_files_by_lang{$lang};
|
||||
|
||||
if ($UTF8_ARG) {
|
||||
my $encoding = get_po_encoding ($po_file);
|
||||
if (lc $encoding eq "utf-8") {
|
||||
open PO_FILE, "<$po_file";
|
||||
} else {
|
||||
my $iconv = $ENV{"INTLTOOL_ICONV"} || "iconv";
|
||||
open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|";
|
||||
}
|
||||
} else {
|
||||
open PO_FILE, "<$po_file";
|
||||
}
|
||||
|
||||
my $nextfuzzy = 0;
|
||||
my $inmsgid = 0;
|
||||
my $inmsgstr = 0;
|
||||
my $msgid = "";
|
||||
my $msgstr = "";
|
||||
while (<PO_FILE>) {
|
||||
$nextfuzzy = 1 if /^#, fuzzy/;
|
||||
if (/^msgid "((\\.|[^\\])*)"/ ) {
|
||||
$translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
|
||||
$msgid = "";
|
||||
$msgstr = "";
|
||||
|
||||
if ($nextfuzzy) {
|
||||
$inmsgid = 0;
|
||||
} else {
|
||||
$msgid = unescape_po_string($1);
|
||||
$inmsgid = 1;
|
||||
}
|
||||
$inmsgstr = 0;
|
||||
$nextfuzzy = 0;
|
||||
}
|
||||
if (/^msgstr "((\\.|[^\\])*)"/) {
|
||||
$msgstr = unescape_po_string($1);
|
||||
$inmsgstr = 1;
|
||||
$inmsgid = 0;
|
||||
}
|
||||
if (/^"((\\.|[^\\])*)"/) {
|
||||
$msgid .= unescape_po_string($1) if $inmsgid;
|
||||
$msgstr .= unescape_po_string($1) if $inmsgstr;
|
||||
}
|
||||
}
|
||||
$translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
|
||||
}
|
||||
}
|
||||
|
||||
sub finalize
|
||||
{
|
||||
}
|
||||
|
||||
sub unescape_one_sequence
|
||||
{
|
||||
my ($sequence) = @_;
|
||||
|
||||
return "\\" if $sequence eq "\\\\";
|
||||
return "\"" if $sequence eq "\\\"";
|
||||
|
||||
# gettext also handles \n, \t, \b, \r, \f, \v, \a, \xxx (octal),
|
||||
# \xXX (hex) and has a comment saying they want to handle \u and \U.
|
||||
|
||||
return $sequence;
|
||||
}
|
||||
|
||||
sub unescape_po_string
|
||||
{
|
||||
my ($string) = @_;
|
||||
|
||||
$string =~ s/(\\.)/unescape_one_sequence($1)/eg;
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
sub entity_decode
|
||||
{
|
||||
local ($_) = @_;
|
||||
|
||||
s/'/'/g; # '
|
||||
s/"/"/g; # "
|
||||
s/&/&/g;
|
||||
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub entity_encode
|
||||
{
|
||||
my ($pre_encoded) = @_;
|
||||
|
||||
my @list_of_chars = unpack ('C*', $pre_encoded);
|
||||
|
||||
if ($PASS_THROUGH_ARG) {
|
||||
return join ('', map (&entity_encode_int_even_high_bit, @list_of_chars));
|
||||
} else {
|
||||
return join ('', map (&entity_encode_int_minimalist, @list_of_chars));
|
||||
}
|
||||
}
|
||||
|
||||
sub entity_encode_int_minimalist
|
||||
{
|
||||
return """ if $_ == 34;
|
||||
return "&" if $_ == 38;
|
||||
return "'" if $_ == 39;
|
||||
return chr $_;
|
||||
}
|
||||
|
||||
sub entity_encode_int_even_high_bit
|
||||
{
|
||||
if ($_ > 127 || $_ == 34 || $_ == 38 || $_ == 39) {
|
||||
# the ($_ > 127) should probably be removed
|
||||
return "&#" . $_ . ";";
|
||||
} else {
|
||||
return chr $_;
|
||||
}
|
||||
}
|
||||
|
||||
sub entity_encoded_translation
|
||||
{
|
||||
my ($lang, $string) = @_;
|
||||
|
||||
my $translation = $translations{$lang, $string};
|
||||
return $string if !$translation;
|
||||
return entity_encode ($translation);
|
||||
}
|
||||
|
||||
## XML (bonobo-activation specific) merge code
|
||||
|
||||
sub ba_merge_translations
|
||||
{
|
||||
my $source;
|
||||
|
||||
{
|
||||
local $/; # slurp mode
|
||||
open INPUT, "<$FILE" or die "can't open $FILE: $!";
|
||||
$source = <INPUT>;
|
||||
close INPUT;
|
||||
}
|
||||
|
||||
open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!";
|
||||
|
||||
while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) {
|
||||
print OUTPUT $1;
|
||||
|
||||
my $node = $2 . "\n";
|
||||
|
||||
my @strings = ();
|
||||
$_ = $node;
|
||||
while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) {
|
||||
push @strings, entity_decode($3);
|
||||
}
|
||||
print OUTPUT;
|
||||
|
||||
my %langs;
|
||||
for my $string (@strings) {
|
||||
for my $lang (keys %po_files_by_lang) {
|
||||
$langs{$lang} = 1 if $translations{$lang, $string};
|
||||
}
|
||||
}
|
||||
|
||||
for my $lang (sort keys %langs) {
|
||||
$_ = $node;
|
||||
s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s;
|
||||
s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg;
|
||||
print OUTPUT;
|
||||
}
|
||||
}
|
||||
|
||||
print OUTPUT $source;
|
||||
|
||||
close OUTPUT;
|
||||
}
|
||||
|
||||
|
||||
## XML (non-bonobo-activation) merge code
|
||||
|
||||
sub xml_merge_translations
|
||||
{
|
||||
my $source;
|
||||
|
||||
{
|
||||
local $/; # slurp mode
|
||||
open INPUT, "<$FILE" or die "can't open $FILE: $!";
|
||||
$source = <INPUT>;
|
||||
close INPUT;
|
||||
}
|
||||
|
||||
open OUTPUT, ">$OUTFILE" or die;
|
||||
|
||||
# FIXME: support attribute translations
|
||||
|
||||
# Empty nodes never need translation, so unmark all of them.
|
||||
# For example, <_foo/> is just replaced by <foo/>.
|
||||
$source =~ s|<\s*_($w+)\s*/>|<$1/>|g;
|
||||
|
||||
# Support for <_foo>blah</_foo> style translations.
|
||||
while ($source =~ s|^(.*?)([ \t]*)<\s*_($w+)\s*>(.*?)<\s*/_\3\s*>([ \t]*\n)?||s) {
|
||||
print OUTPUT $1;
|
||||
|
||||
my $spaces = $2;
|
||||
my $tag = $3;
|
||||
my $string = $4;
|
||||
|
||||
print OUTPUT "$spaces<$tag>$string</$tag>\n";
|
||||
|
||||
$string =~ s/\s+/ /g;
|
||||
$string =~ s/^ //;
|
||||
$string =~ s/ $//;
|
||||
$string = entity_decode($string);
|
||||
|
||||
for my $lang (sort keys %po_files_by_lang) {
|
||||
my $translation = $translations{$lang, $string};
|
||||
next if !$translation;
|
||||
$translation = entity_encode($translation);
|
||||
print OUTPUT "$spaces<$tag xml:lang=\"$lang\">$translation</$tag>\n";
|
||||
}
|
||||
}
|
||||
|
||||
print OUTPUT $source;
|
||||
|
||||
close OUTPUT;
|
||||
}
|
||||
|
||||
sub keys_merge_translations
|
||||
{
|
||||
open INPUT, "<${FILE}" or die;
|
||||
open OUTPUT, ">${OUTFILE}" or die;
|
||||
|
||||
while (<INPUT>) {
|
||||
if (s/^(\s*)_(\w+=(.*))/$1$2/) {
|
||||
my $string = $3;
|
||||
|
||||
print OUTPUT;
|
||||
|
||||
my $non_translated_line = $_;
|
||||
|
||||
for my $lang (sort keys %po_files_by_lang) {
|
||||
my $translation = $translations{$lang, $string};
|
||||
next if !$translation;
|
||||
|
||||
$_ = $non_translated_line;
|
||||
s/(\w+)=.*/[$lang]$1=$translation/;
|
||||
print OUTPUT;
|
||||
}
|
||||
} else {
|
||||
print OUTPUT;
|
||||
}
|
||||
}
|
||||
|
||||
close OUTPUT;
|
||||
close INPUT;
|
||||
}
|
||||
|
||||
sub desktop_merge_translations
|
||||
{
|
||||
open INPUT, "<${FILE}" or die;
|
||||
open OUTPUT, ">${OUTFILE}" or die;
|
||||
|
||||
while (<INPUT>) {
|
||||
if (s/^(\s*)_(\w+=(.*))/$1$2/) {
|
||||
my $string = $3;
|
||||
|
||||
print OUTPUT;
|
||||
|
||||
my $non_translated_line = $_;
|
||||
|
||||
for my $lang (sort keys %po_files_by_lang) {
|
||||
my $translation = $translations{$lang, $string};
|
||||
next if !$translation;
|
||||
|
||||
$_ = $non_translated_line;
|
||||
s/(\w+)=.*/${1}[$lang]=$translation/;
|
||||
print OUTPUT;
|
||||
}
|
||||
} else {
|
||||
print OUTPUT;
|
||||
}
|
||||
}
|
||||
|
||||
close OUTPUT;
|
||||
close INPUT;
|
||||
}
|
||||
|
||||
sub schemas_merge_translations
|
||||
{
|
||||
my $source;
|
||||
|
||||
{
|
||||
local $/; # slurp mode
|
||||
open INPUT, "<$FILE" or die "can't open $FILE: $!";
|
||||
$source = <INPUT>;
|
||||
close INPUT;
|
||||
}
|
||||
|
||||
open OUTPUT, ">$OUTFILE" or die;
|
||||
|
||||
# FIXME: support attribute translations
|
||||
|
||||
# Empty nodes never need translation, so unmark all of them.
|
||||
# For example, <_foo/> is just replaced by <foo/>.
|
||||
$source =~ s|<\s*_($w+)\s*/>|<$1/>|g;
|
||||
|
||||
# Support for <_foo>blah</_foo> style translations.
|
||||
|
||||
my $regex_start = "^(.*?)([ \t]*)<locale name=\"C\">";
|
||||
my $regex_short = "([ \t\n]*)<short>(.*?)</short>";
|
||||
my $regex_long = "([ \t\n]*)<long>(.*?)</long>";
|
||||
my $regex_end = "([ \t\n]*)</locale>";
|
||||
|
||||
while ($source =~ s|$regex_start$regex_short$regex_long$regex_end||s) {
|
||||
print OUTPUT $1;
|
||||
|
||||
my $locale_start_spaces = $2;
|
||||
my $locale_end_spaces = $7;
|
||||
my $short_spaces = $3;
|
||||
my $short_string = $4;
|
||||
my $long_spaces = $5;
|
||||
my $long_string = $6;
|
||||
|
||||
# English first
|
||||
|
||||
print OUTPUT "$locale_start_spaces<locale name=\"C\">";
|
||||
print OUTPUT "$short_spaces<short>$short_string</short>";
|
||||
print OUTPUT "$long_spaces<long>$long_string</long>";
|
||||
print OUTPUT "$locale_end_spaces</locale>";
|
||||
|
||||
$short_string =~ s/\s+/ /g;
|
||||
$short_string =~ s/^ //;
|
||||
$short_string =~ s/ $//;
|
||||
$short_string = entity_decode($short_string);
|
||||
|
||||
$long_string =~ s/\s+/ /g;
|
||||
$long_string =~ s/^ //;
|
||||
$long_string =~ s/ $//;
|
||||
$long_string = entity_decode($long_string);
|
||||
|
||||
for my $lang (sort keys %po_files_by_lang) {
|
||||
my $short_translation = $translations{$lang, $short_string};
|
||||
my $long_translation = $translations{$lang, $long_string};
|
||||
|
||||
next if (!$short_translation && !$long_translation);
|
||||
|
||||
print OUTPUT "\n$locale_start_spaces<locale name=\"$lang\">";
|
||||
|
||||
if ($short_translation)
|
||||
{
|
||||
$short_translation = entity_encode($short_translation);
|
||||
print OUTPUT "$short_spaces<short>$short_translation</short>";
|
||||
}
|
||||
|
||||
if ($long_translation)
|
||||
{
|
||||
$long_translation = entity_encode($long_translation);
|
||||
print OUTPUT "$long_spaces<long>$long_translation</long>";
|
||||
}
|
||||
|
||||
print OUTPUT "$locale_end_spaces</locale>";
|
||||
}
|
||||
}
|
||||
|
||||
print OUTPUT $source;
|
||||
|
||||
close OUTPUT;
|
||||
}
|
||||
|
|
@ -1,634 +0,0 @@
|
|||
#!@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.22";
|
||||
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)+|".
|
||||
"schemas(\.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|schemas(?:\.in)+)";
|
||||
my $ini_regex =
|
||||
"(?:desktop(?:\.in)+|caves(?:\.in)+|directory(?:\.in)+|".
|
||||
"soundlist(?:\.in)+)";
|
||||
|
||||
if ($type =~ /\[type: gettext\/([^\]].*)]/) {
|
||||
$gettext_type=$1;
|
||||
}
|
||||
elsif ($type =~ /schemas(\.in)+$/) {
|
||||
$gettext_type="schemas";
|
||||
}
|
||||
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_xml_unmarked,
|
||||
@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)$/
|
||||
}, "..";
|
||||
find sub {
|
||||
push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/
|
||||
}, "..";
|
||||
|
||||
|
||||
open POTFILES, "POTFILES.in" or 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_(.*)=\"/ || /translatable=\"yes\"/){
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $file (@buf_i18n_xml_unmarked){
|
||||
push @buf_allfiles, unpack("x3 A*", $file) . "\n";
|
||||
}
|
||||
|
||||
|
||||
@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");
|
||||
|
||||
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;
|
||||
|
||||
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") or die "$PROGRAM: couldn't move $MODULE.po to $MODULE.pot.\n";
|
||||
|
||||
print "Wrote $MODULE.pot\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";
|
||||
} elsif (-f "../configure.ac") {
|
||||
$conf_in = "../configure.ac";
|
||||
} 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 %varhash = ();
|
||||
my $conf_source; {
|
||||
local (*IN);
|
||||
open (IN, "<$conf_in") || die "can't open $conf_in: $!";
|
||||
while (<IN>) {
|
||||
if (/^(\w+)=(\S+)/) { $varhash{$1} = $2 };
|
||||
}
|
||||
seek (IN, 0, 0);
|
||||
local $/; # slurp mode
|
||||
$conf_source = <IN>;
|
||||
}
|
||||
|
||||
my $name = "";
|
||||
$name = $1 if $conf_source =~ /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m;
|
||||
if ($conf_source =~ /^AC_INIT\([\s\[]*([^,\)\s\]]+)\]?\s*,/m) {
|
||||
$name = $1;
|
||||
$varhash{"AC_PACKAGE_NAME"} = $1;
|
||||
}
|
||||
$name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\s\]]+)/m;
|
||||
|
||||
$name = "\$AC_PACKAGE_NAME" if "$name" eq "AC_PACKAGE_NAME";
|
||||
|
||||
my $oldname = "";
|
||||
while (($name =~ /[\$](\S+)/) && ("$oldname" ne "$name")) {
|
||||
$oldname = $name;
|
||||
if (exists $varhash{$1}) {
|
||||
$name =~ s/[\$](\S+)/$varhash{$1}/;
|
||||
}
|
||||
}
|
||||
return $name if $name;
|
||||
}
|
||||
|
||||
print "$PROGRAM: Unable to determine package name.\n" .
|
||||
"Make sure to run this script inside the po directory.\n";
|
||||
exit;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue