aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEugene Sandulenko2010-06-15 10:44:51 +0000
committerEugene Sandulenko2010-06-15 10:44:51 +0000
commit859212df2523e8b15076d968018dbf98618fd60f (patch)
treee3f7ff62c58c9ac8a762791c0a1801b75fe1f14a /tools
parentdb6673c408865b201808e01ab5db796f2e794058 (diff)
downloadscummvm-rg350-859212df2523e8b15076d968018dbf98618fd60f.tar.gz
scummvm-rg350-859212df2523e8b15076d968018dbf98618fd60f.tar.bz2
scummvm-rg350-859212df2523e8b15076d968018dbf98618fd60f.zip
Implement translation support for ScummVM GUI.
Based on patch #2903830: "Updated Translation Prototype" by alexbevi which in turn is based on patch #1739965 by jvprat. Currently it builds all translations right into ScummVM. Once the feature will be accepted more widely, i.e. more translations will pop up, it will be trivial to move translation strings to external file. Finished translation: Russian Unfinished translation: Hungarian Things which are nice to do: - Language code -> language mapping for more user friendness - Specifying fonts to be used with language - Updating of interface language without restart. It will require moving of much code to reflowLayout() methods for each dialog The .po files must be in single byte encodings. I.e. no support for Unicode. svn-id: r49759
Diffstat (limited to 'tools')
-rw-r--r--tools/module.mk1
-rwxr-xr-xtools/po2c280
2 files changed, 280 insertions, 1 deletions
diff --git a/tools/module.mk b/tools/module.mk
index 896a2e504b..2c62e427ea 100644
--- a/tools/module.mk
+++ b/tools/module.mk
@@ -65,7 +65,6 @@ md5scumm: tools/md5table$(EXEEXT)
tools/md5table$(EXEEXT) --c++ < $(srcdir)/tools/scumm-md5.txt > $(srcdir)/engines/scumm/scumm-md5.h
cp $(srcdir)/tools/scumm-md5.txt $(srcdir)/../../web/trunk/data/scumm-md5.txt
-
#
# Rules which automatically and implicitly rebuild the credits and
# MD5 tables when needed.
diff --git a/tools/po2c b/tools/po2c
new file mode 100755
index 0000000000..ac1744aa2c
--- /dev/null
+++ b/tools/po2c
@@ -0,0 +1,280 @@
+#!/usr/bin/perl
+
+#
+# po2c - Converts .po files to C code
+#
+# Copyright (C) 2004 Angel Ortega <angel@triptico.com>
+#
+# This program 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.
+#
+# This program 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# http://www.triptico.com
+#
+
+$VERSION = "1.0.2";
+
+if(scalar(@ARGV) == 0)
+{
+ print "Usage: po2c {po file[s]}\n";
+ exit 1;
+}
+
+%msgs = ();
+%msgids = ();
+
+# stage 1: loading
+
+# arguments are .po files
+foreach my $f (@ARGV)
+{
+ my ($lang);
+ my ($langDesc);
+
+ next unless(($lang) = ($f =~ /([^\/]+)\.po$/));
+
+ if(open F, $f)
+ {
+ my ($msgid, $val, %a);
+
+ while(<F>)
+ {
+ chomp;
+
+ # ignore blank lines or comments
+ next if /^$/ or /^#/;
+
+ if(/^msgid\s+\"(.*)\"\s*$/)
+ {
+ # store previous msgid
+ if(defined($msgid))
+ {
+ $a{$msgid} = $val;
+ $msgids{$msgid} ++;
+ }
+
+ # start of msgid
+ $val = $1;
+ }
+ elsif(/^msgstr\s+\"(.*)\"\s*$/)
+ {
+ # store previous msgid
+ $msgid = $val;
+
+ # start of msgstr
+ $val = $1;
+ }
+ elsif(/^\"(.*)\"\s*$/)
+ {
+ # add to current value
+ $val .= $1;
+ }
+ }
+
+ # store previous msgid
+ if(defined($msgid))
+ {
+ $a{$msgid} = $val;
+ $msgids{$msgid} ++;
+ }
+
+ close F;
+
+ # add to the global message pool
+ $msgs{$lang} = \%a;
+ }
+}
+
+# stage 2: convert the data
+
+# stores all sorted msgids into @msgids
+@msgids = sort(keys(%msgids));
+
+# travels again, storing indexes into %msgids
+for(my $n = 0;$n < scalar(@msgids);$n++)
+{
+ $msgids{$msgids[$n]} = $n;
+}
+
+# stage 3: dump as C code
+
+print "/* generated by po2c $VERSION - Do not modify */\n\n";
+print "#include <stdio.h>\n";
+print "#include <string.h>\n\n";
+
+# dump first the msgid array
+print "static const char * _po2c_msgids[] = {\n";
+
+for(my $n = 0;$n < scalar(@msgids);$n++)
+{
+ print "\t/* $n */ \"" . $msgids[$n] . "\",\n";
+}
+
+print "\tNULL\n};\n\n";
+
+# dump the lang structure
+print "struct _po2c_msg {\n";
+print "\tint msgid;\n";
+print "\tconst char * msgstr;\n";
+print "};\n\n";
+
+# dump now each language
+
+foreach my $l (keys(%msgs))
+{
+ print "static struct _po2c_msg _po2c_lang_${l}\[\] = {\n";
+
+ # get the translation table for the language $l
+ my ($m) = $msgs{$l};
+
+# while (my ($msgstr, $msgid) = each (%$m))
+ foreach my $msgid (sort(keys(%$m)))
+ {
+ my ($msgstr) = "";
+
+ # make it 7-bit safe
+ foreach $c (split(//, $m->{$msgid})) {
+ if (ord($c) > 0x7f) {
+ $msgstr .= sprintf("\\%o", ord($c));
+ } else {
+ $msgstr .= $c;
+ }
+ }
+
+ print "\t{ " . $msgids{$msgid} . ", \"" . $msgstr . "\" },\n"
+ if $msgstr;
+ }
+
+ print "\t{ -1, NULL }\n};\n\n";
+}
+
+# finally, dump the languages
+
+print "static struct {\n";
+print "\tconst char * lang;\n";
+print "\tconst char * charset;\n";
+print "\tstruct _po2c_msg * msgs;\n";
+print "} _po2c_langs[] = {\n";
+
+foreach my $l (keys(%msgs))
+{
+ $header = $msgs{$l}->{""};
+ $header =~ /charset=([^\\]+)/;
+ $charset = $1;
+ print "\t{ \"" . $l . "\", \"" . $charset . "\", _po2c_lang_${l} },\n";
+}
+
+print "\t{ NULL, NULL, NULL }\n};\n\n";
+
+print "/* code */\n";
+print << 'EOF';
+
+static struct _po2c_msg * _po2c_lang=NULL;
+static int _po2c_lang_size=0;
+static const char * _po2c_charset=NULL;
+
+void po2c_setlang(const char * lang)
+{
+ int n;
+
+ _po2c_lang=NULL;
+ _po2c_lang_size=0;
+ _po2c_charset=NULL;
+
+ /* if lang is NULL or "", deactivate it */
+ if(lang == NULL || *lang == '\0')
+ return;
+
+ /* searches for a valid language array */
+ for(n=0;_po2c_lang == NULL && _po2c_langs[n].lang != NULL;n++)
+ {
+ if(strcmp(lang, _po2c_langs[n].lang) == 0) {
+ _po2c_lang=_po2c_langs[n].msgs;
+ _po2c_charset=_po2c_langs[n].charset;
+ }
+ }
+
+ /* try partial searches */
+ for(n=0;_po2c_lang == NULL && _po2c_langs[n].lang != NULL;n++)
+ {
+ if(strncmp(lang, _po2c_langs[n].lang, 2) == 0) {
+ _po2c_lang=_po2c_langs[n].msgs;
+ _po2c_charset=_po2c_langs[n].charset;
+ }
+ }
+
+ /* if found, count entries */
+ if(_po2c_lang != NULL)
+ {
+ struct _po2c_msg * m;
+
+ for(m=_po2c_lang;m->msgid != -1;m++)
+ _po2c_lang_size++;
+ }
+}
+
+const char * po2c_gettext(const char * msgid)
+{
+ struct _po2c_msg * m;
+ int b, t, n, c;
+
+ /* if no language is set or msgid is empty, return msgid as is */
+ if(_po2c_lang == NULL || *msgid == '\0')
+ return(msgid);
+
+ /* binary-search for the msgid */
+ b=0; t=_po2c_lang_size - 1;
+
+ while(t >= b)
+ {
+ n=(b + t) / 2;
+ m=&_po2c_lang[n];
+
+ c=strcmp(msgid, _po2c_msgids[m->msgid]);
+
+ if(c == 0)
+ return(m->msgstr);
+ else
+ if(c < 0)
+ t=n - 1;
+ else
+ b=n + 1;
+ }
+
+ return(msgid);
+}
+
+const char * po2c_getcharset(void)
+{
+ if (_po2c_charset)
+ return _po2c_charset;
+ else
+ return "ASCII";
+}
+
+int po2c_getnumlangs(void)
+{
+ int n = 0;
+ while (_po2c_langs[n].lang)
+ n++;
+
+ return n;
+}
+
+const char * po2c_getlang(int num)
+{
+ return _po2c_langs[num].lang;
+}
+EOF
+
+exit 0;