aboutsummaryrefslogtreecommitdiff
path: root/tools/po2c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/po2c')
-rwxr-xr-xtools/po2c280
1 files changed, 280 insertions, 0 deletions
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;