fix network state automatic management (wasn't working)

This commit is contained in:
Simon Morlat 2010-03-10 22:40:48 +01:00
parent 4c4204ef96
commit b88fb9a025
6 changed files with 38 additions and 1643 deletions

View file

@ -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

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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/&apos;/'/g; # '
s/&quot;/"/g; # "
s/&amp;/&/g;
return $_;
}
sub entity_decode
{
local ($_) = @_;
s/&apos;/'/g; # '
s/&quot;/"/g; # "
s/&amp;/&/g;
s/&lt;/</g;
s/&gt;/>/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";
}
}
}
}

View file

@ -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/&apos;/'/g; # '
s/&quot;/"/g; # "
s/&amp;/&/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 "&quot;" if $_ == 34;
return "&amp;" if $_ == 38;
return "&apos;" 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;
}

View file

@ -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;
}