[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pingus-CVS] r2981 - in branches/pingus_sdl/src: . tinygettext worldmap
From: |
grumbel at BerliOS |
Subject: |
[Pingus-CVS] r2981 - in branches/pingus_sdl/src: . tinygettext worldmap |
Date: |
Fri, 17 Aug 2007 00:43:47 +0200 |
Author: grumbel
Date: 2007-08-17 00:43:45 +0200 (Fri, 17 Aug 2007)
New Revision: 2981
Added:
branches/pingus_sdl/src/tinygettext/dictionary.cpp
branches/pingus_sdl/src/tinygettext/dictionary.hpp
branches/pingus_sdl/src/tinygettext/dictionary_manager.cpp
branches/pingus_sdl/src/tinygettext/dictionary_manager.hpp
branches/pingus_sdl/src/tinygettext/language_def.cpp
branches/pingus_sdl/src/tinygettext/language_def.hpp
branches/pingus_sdl/src/tinygettext/po_file_reader.cpp
branches/pingus_sdl/src/tinygettext/po_file_reader.hpp
Removed:
branches/pingus_sdl/src/tinygettext/tinygettext.cpp
branches/pingus_sdl/src/tinygettext/tinygettext.hpp
Modified:
branches/pingus_sdl/src/SConscript
branches/pingus_sdl/src/gettext.h
branches/pingus_sdl/src/worldmap/manager.cpp
Log:
- splitted tinygettext into seperate files
Modified: branches/pingus_sdl/src/SConscript
===================================================================
--- branches/pingus_sdl/src/SConscript 2007-08-16 21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/SConscript 2007-08-16 22:43:45 UTC (rev 2981)
@@ -246,7 +246,10 @@
'math/rect.cpp',
'system.cpp',
'timer.cpp',
-'tinygettext/tinygettext.cpp',
+'tinygettext/po_file_reader.cpp',
+'tinygettext/dictionary_manager.cpp',
+'tinygettext/dictionary.cpp',
+'tinygettext/language_def.cpp',
'true_server.cpp',
'math/vector2f.cpp',
'math/vector2i.cpp',
Modified: branches/pingus_sdl/src/gettext.h
===================================================================
--- branches/pingus_sdl/src/gettext.h 2007-08-16 21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/gettext.h 2007-08-16 22:43:45 UTC (rev 2981)
@@ -20,7 +20,8 @@
#ifndef HEADER_GETTEXT_HXX
#define HEADER_GETTEXT_HXX
-#include "tinygettext/tinygettext.hpp"
+#include "tinygettext/dictionary_manager.hpp"
+#include "tinygettext/dictionary.hpp"
extern TinyGetText::DictionaryManager dictionary_manager;
Added: branches/pingus_sdl/src/tinygettext/dictionary.cpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/dictionary.cpp 2007-08-16 21:52:17 UTC
(rev 2980)
+++ branches/pingus_sdl/src/tinygettext/dictionary.cpp 2007-08-16 22:43:45 UTC
(rev 2981)
@@ -0,0 +1,122 @@
+// $Id$
+//
+// TinyGetText - A small flexible gettext() replacement
+// Copyright (C) 2004 Ingo Ruhnke <address@hidden>
+//
+// 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.
+
+#include "dictionary.hpp"
+
+namespace TinyGetText {
+
+Dictionary::Dictionary(const LanguageDef& language_, const std::string&
charset_)
+ : language(language_), charset(charset_)
+{
+}
+
+Dictionary::Dictionary()
+ : language(lang_en)
+{
+}
+
+std::string
+Dictionary::get_charset() const
+{
+ return charset;
+}
+
+void
+Dictionary::set_charset(const std::string& charset_)
+{
+ charset = charset_;
+}
+
+void
+Dictionary::set_language(const LanguageDef& lang)
+{
+ language = lang;
+}
+
+std::string
+Dictionary::translate(const std::string& msgid, const std::string& msgid2, int
num)
+{
+ PluralEntries::iterator i = plural_entries.find(msgid);
+ std::map<int, std::string>& msgstrs = i->second;
+
+ if (i != plural_entries.end() && !msgstrs.empty())
+ {
+ int g = language.plural(num);
+ std::map<int, std::string>::iterator j = msgstrs.find(g);
+ if (j != msgstrs.end())
+ {
+ return j->second;
+ }
+ else
+ {
+ // Return the first translation, in case we can't translate the
specific number
+ return msgstrs.begin()->second;
+ }
+ }
+ else
+ {
+#ifdef TRANSLATION_DEBUG
+ std::cerr << "Warning: Couldn't translate: " << msgid << std::endl;
+ std::cerr << "Candidates: " << std::endl;
+ for (PluralEntries::iterator i = plural_entries.begin(); i !=
plural_entries.end(); ++i)
+ std::cout << "'" << i->first << "'" << std::endl;
+#endif
+
+ if (plural2_1(num)) // default to english rules
+ return msgid2;
+ else
+ return msgid;
+ }
+}
+
+std::string
+Dictionary::translate(const std::string& msgid)
+{
+ Entries::iterator i = entries.find(msgid);
+ if (i != entries.end() && !i->second.empty())
+ {
+ return i->second;
+ }
+ else
+ {
+#ifdef TRANSLATION_DBEUG
+ std::cout << "Error: Couldn't translate: " << msgid << std::endl;
+#endif
+ return msgid;
+ }
+}
+
+void
+Dictionary::add_translation(const std::string& msgid, const std::string& ,
+ const std::map<int, std::string>& msgstrs)
+{
+ // Do we need msgid2 for anything? its after all supplied to the
+ // translate call, so we just throw it away
+ plural_entries[msgid] = msgstrs;
+}
+
+void
+Dictionary::add_translation(const std::string& msgid, const std::string&
msgstr)
+{
+ entries[msgid] = msgstr;
+}
+
+} // namespace TinyGetText
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/dictionary.cpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: branches/pingus_sdl/src/tinygettext/dictionary.hpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/dictionary.hpp 2007-08-16 21:52:17 UTC
(rev 2980)
+++ branches/pingus_sdl/src/tinygettext/dictionary.hpp 2007-08-16 22:43:45 UTC
(rev 2981)
@@ -0,0 +1,89 @@
+// $Id$
+//
+// TinyGetText - A small flexible gettext() replacement
+// Copyright (C) 2004 Ingo Ruhnke <address@hidden>
+//
+// 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.
+
+#ifndef HEADER_DICTIONARY_HPP
+#define HEADER_DICTIONARY_HPP
+
+#include <string>
+#include <map>
+
+#include "language_def.hpp"
+
+namespace TinyGetText {
+
+/** A simple dictionary class that mimics gettext() behaviour. Each
+ Dictionary only works for a single language, for managing multiple
+ languages and .po files at once use the DictionaryManager. */
+class Dictionary
+{
+private:
+ typedef std::map<std::string, std::string> Entries;
+ Entries entries;
+
+ typedef std::map<std::string, std::map<int, std::string> > PluralEntries;
+ PluralEntries plural_entries;
+
+ LanguageDef language;
+ std::string charset;
+public:
+ /** */
+ Dictionary(const LanguageDef& language_, const std::string& charset = "");
+
+ Dictionary();
+
+ /** Return the charset used for this dictionary */
+ std::string get_charset() const;
+
+ /** Set a charset for this dictionary, this will NOT convert stuff,
+ it is for information only, you have to convert stuff yourself
+ when you add it with \a add_translation() */
+ void set_charset(const std::string& charset);
+
+ /** Set the language that is used for this dictionary, this is
+ mainly needed to evaluate plural forms */
+ void set_language(const LanguageDef& lang);
+
+ LanguageDef get_language() const { return language; }
+
+ /** Translate the string \a msgid to its correct plural form, based
+ on the number of items given by \a num. \a msgid2 is \a msgid in
+ plural form. */
+ std::string translate(const std::string& msgid, const std::string& msgid2,
int num);
+
+ /** Translate the string \a msgid. */
+ std::string translate(const std::string& msgid);
+
+ /** Add a translation from \a msgid to \a msgstr to the dictionary,
+ where \a msgid is the singular form of the message, msgid2 the
+ plural form and msgstrs a table of translations. The right
+ translation will be calculated based on the \a num argument to
+ translate(). */
+ void add_translation(const std::string& msgid, const std::string& msgid2,
+ const std::map<int, std::string>& msgstrs);
+
+ /** Add a translation from \a msgid to \a msgstr to the
+ dictionary */
+ void add_translation(const std::string& msgid, const std::string& msgstr);
+};
+
+} // namespace TinyGetText
+
+#endif
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/dictionary.hpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: branches/pingus_sdl/src/tinygettext/dictionary_manager.cpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/dictionary_manager.cpp 2007-08-16
21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/tinygettext/dictionary_manager.cpp 2007-08-16
22:43:45 UTC (rev 2981)
@@ -0,0 +1,222 @@
+// $Id$
+//
+// TinyGetText - A small flexible gettext() replacement
+// Copyright (C) 2004 Ingo Ruhnke <address@hidden>
+//
+// 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.
+
+#include <iostream>
+#include <sys/types.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#else
+#include "../win32/uce_dirent.h"
+#endif
+
+#include <fstream>
+#include "dictionary_manager.hpp"
+#include "po_file_reader.hpp"
+
+namespace TinyGetText {
+
+static bool has_suffix(const std::string& lhs, const std::string rhs)
+{
+ if (lhs.length() < rhs.length())
+ return false;
+ else
+ return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0;
+}
+
+DictionaryManager::DictionaryManager()
+ : current_dict(&empty_dict)
+{
+ parseLocaleAliases();
+ // setup language from environment vars
+ const char* lang = getenv("LC_ALL");
+ if(!lang)
+ lang = getenv("LC_MESSAGES");
+ if(!lang)
+ lang = getenv("LANG");
+
+ if(lang)
+ set_language(lang);
+}
+
+void
+DictionaryManager::parseLocaleAliases()
+{
+ // try to parse language alias list
+ std::ifstream in("/usr/share/locale/locale.alias");
+
+ char c = ' ';
+ while(in.good() && !in.eof()) {
+ while(isspace(c) && !in.eof())
+ in.get(c);
+
+ if(c == '#') { // skip comments
+ while(c != '\n' && !in.eof())
+ in.get(c);
+ continue;
+ }
+
+ std::string alias;
+ while(!isspace(c) && !in.eof()) {
+ alias += c;
+ in.get(c);
+ }
+ while(isspace(c) && !in.eof())
+ in.get(c);
+ std::string language;
+ while(!isspace(c) && !in.eof()) {
+ language += c;
+ in.get(c);
+ }
+
+ if(in.eof())
+ break;
+ set_language_alias(alias, language);
+ }
+}
+
+Dictionary&
+DictionaryManager::get_dictionary(const std::string& spec)
+{
+ std::string lang = get_language_from_spec(spec);
+ Dictionaries::iterator i = dictionaries.find(get_language_from_spec(lang));
+ if (i != dictionaries.end())
+ {
+ return i->second;
+ }
+ else // Dictionary for languages lang isn't loaded, so we load it
+ {
+ //std::cout << "get_dictionary: " << lang << std::endl;
+ Dictionary& dict = dictionaries[lang];
+
+ dict.set_language(get_language_def(lang));
+ if(charset != "")
+ dict.set_charset(charset);
+
+ for (SearchPath::iterator p = search_path.begin(); p !=
search_path.end(); ++p)
+ {
+ DIR* dir = opendir(p->c_str());
+ if (!dir)
+ {
+ std::cerr << "TinyGetText: Error: opendir() failed on " << *p <<
std::endl;
+ }
+ else
+ {
+ struct dirent* ent;
+ while((ent = readdir(dir)))
+ {
+ if (std::string(ent->d_name) == lang + ".po")
+ {
+ std::string pofile = *p + "/" + ent->d_name;
+ std::ifstream in(pofile.c_str());
+ if (!in)
+ {
+ std::cerr << "Error: Failure file opening: " <<
pofile << std::endl;
+ }
+ else
+ {
+ POFileReader reader(in, dict);
+ }
+ }
+ }
+ closedir(dir);
+ }
+ }
+
+ return dict;
+ }
+}
+
+std::set<std::string>
+DictionaryManager::get_languages()
+{
+ std::set<std::string> languages;
+
+ for (SearchPath::iterator p = search_path.begin(); p != search_path.end();
++p)
+ {
+ DIR* dir = opendir(p->c_str());
+ if (!dir)
+ {
+ std::cerr << "Error: opendir() failed on " << *p << std::endl;
+ }
+ else
+ {
+ struct dirent* ent;
+ while((ent = readdir(dir)))
+ {
+ if (has_suffix(ent->d_name, ".po"))
+ {
+ std::string filename = ent->d_name;
+ languages.insert(filename.substr(0, filename.length()-3));
+ }
+ }
+ closedir(dir);
+ }
+ }
+ return languages;
+}
+
+void
+DictionaryManager::set_language(const std::string& lang)
+{
+ language = get_language_from_spec(lang);
+ current_dict = & (get_dictionary(language));
+}
+
+void
+DictionaryManager::set_charset(const std::string& charset)
+{
+ dictionaries.clear(); // changing charset invalidates cache
+ this->charset = charset;
+ set_language(language);
+}
+
+void
+DictionaryManager::set_language_alias(const std::string& alias,
+ const std::string& language)
+{
+ language_aliases.insert(std::make_pair(alias, language));
+}
+
+std::string
+DictionaryManager::get_language_from_spec(const std::string& spec)
+{
+ std::string lang = spec;
+ Aliases::iterator i = language_aliases.find(lang);
+ if(i != language_aliases.end()) {
+ lang = i->second;
+ }
+
+ std::string::size_type s = lang.find_first_of("_.");
+ if(s == std::string::npos)
+ return lang;
+
+ return std::string(lang, 0, s);
+}
+
+void
+DictionaryManager::add_directory(const std::string& pathname)
+{
+ dictionaries.clear(); // adding directories invalidates cache
+ search_path.push_back(pathname);
+ set_language(language);
+}
+
+} // namespace TinyGetText
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/dictionary_manager.cpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: branches/pingus_sdl/src/tinygettext/dictionary_manager.hpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/dictionary_manager.hpp 2007-08-16
21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/tinygettext/dictionary_manager.hpp 2007-08-16
22:43:45 UTC (rev 2981)
@@ -0,0 +1,82 @@
+// $Id$
+//
+// TinyGetText - A small flexible gettext() replacement
+// Copyright (C) 2004 Ingo Ruhnke <address@hidden>
+//
+// 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.
+
+#ifndef HEADER_DICTIONARY_MANAGER_HPP
+#define HEADER_DICTIONARY_MANAGER_HPP
+
+#include <vector>
+#include <set>
+#include "dictionary.hpp"
+
+namespace TinyGetText {
+
+/** Manager class for dictionaries, you give it a bunch of directories
+ with .po files and it will then automatically load the right file
+ on demand depending on which language was set. */
+class DictionaryManager
+{
+private:
+ typedef std::map<std::string, Dictionary> Dictionaries;
+ Dictionaries dictionaries;
+ typedef std::vector<std::string> SearchPath;
+ SearchPath search_path;
+ typedef std::map<std::string, std::string> Aliases;
+ Aliases language_aliases;
+ std::string charset;
+ std::string language;
+ Dictionary* current_dict;
+ Dictionary empty_dict;
+
+public:
+ DictionaryManager();
+
+ /** Return the currently active dictionary, if none is set, an empty
+ dictionary is returned. */
+ Dictionary& get_dictionary()
+ { return *current_dict; }
+
+ /** Get dictionary for lang */
+ Dictionary& get_dictionary(const std::string& langspec);
+
+ /** Set a language based on a four? letter country code */
+ void set_language(const std::string& langspec);
+
+ /** Set a charset that will be set on the returned dictionaries */
+ void set_charset(const std::string& charset);
+
+ /** Define an alias for a language */
+ void set_language_alias(const std::string& alias, const std::string& lang);
+
+ /** Add a directory to the search path for dictionaries */
+ void add_directory(const std::string& pathname);
+
+ /** Return a set of the available languages in their country code */
+ std::set<std::string> get_languages();
+
+private:
+ void parseLocaleAliases();
+ /// returns the language part in a language spec (like de_DE.UTF-8 -> de)
+ std::string get_language_from_spec(const std::string& spec);
+};
+
+} // namespace TinyGetText
+
+#endif
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/dictionary_manager.hpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: branches/pingus_sdl/src/tinygettext/language_def.cpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/language_def.cpp 2007-08-16
21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/tinygettext/language_def.cpp 2007-08-16
22:43:45 UTC (rev 2981)
@@ -0,0 +1,119 @@
+/* $Id$
+** __ __ __ ___ __ __ __ __
+** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
+** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
+** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
+** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
+** \/ \/ \/ \/ \/
+** Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+**
+** 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.
+*/
+
+#include "language_def.hpp"
+
+namespace TinyGetText {
+
+int plural1(int ) { return 0; }
+int plural2_1(int n) { return (n != 1); }
+int plural2_2(int n) { return (n > 1); }
+int plural3_lv(int n) { return (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
+int plural3_ga(int n) { return n==1 ? 0 : n==2 ? 1 : 2; }
+int plural3_lt(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 &&
(n%100<10 || n%100>=20) ? 1 : 2); }
+int plural3_1(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4
&& (n%100<10 || n%100>=20) ? 1 : 2); }
+int plural3_sk(int n) { return (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; }
+int plural3_pl(int n) { return (n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2); }
+int plural3_sl(int n) { return (n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 ||
n%100==4 ? 2 : 3); }
+
+/** Language Definitions */
+//*{
+LanguageDef lang_hu("hu", "Hungarian", 1, plural1); // "nplurals=1;
plural=0;"
+LanguageDef lang_ja("ja", "Japanese", 1, plural1); // "nplurals=1;
plural=0;"
+LanguageDef lang_ko("ko", "Korean", 1, plural1); // "nplurals=1;
plural=0;"
+LanguageDef lang_tr("tr", "Turkish", 1, plural1); // "nplurals=1;
plural=0;"
+LanguageDef lang_da("da", "Danish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_nl("nl", "Dutch", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_en("en", "English", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_fo("fo", "Faroese", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_de("de", "German", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_nb("nb", "Norwegian Bokmal", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_no("no", "Norwegian", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_nn("nn", "Norwegian Nynorsk", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_sv("sv", "Swedish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_et("et", "Estonian", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_fi("fi", "Finnish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_el("el", "Greek", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_he("he", "Hebrew", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_it("it", "Italian", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_pt("pt", "Portuguese", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_es("es", "Spanish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_eo("eo", "Esperanto", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
+LanguageDef lang_fr("fr", "French", 2, plural2_2); // "nplurals=2;
plural=(n > 1);"
+LanguageDef lang_pt_BR("pt_BR", "Brazilian", 2, plural2_2); // "nplurals=2;
plural=(n > 1);"
+LanguageDef lang_lv("lv", "Latvian", 3, plural3_lv); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
+LanguageDef lang_ga("ga", "Irish", 3, plural3_ga); // "nplurals=3;
plural=n==1 ? 0 : n==2 ? 1 : 2;"
+LanguageDef lang_lt("lt", "Lithuanian", 3, plural3_lt); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
+LanguageDef lang_hr("hr", "Croatian", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
+LanguageDef lang_cs("cs", "Czech", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
+LanguageDef lang_ru("ru", "Russian", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
+LanguageDef lang_uk("uk", "Ukrainian", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
+LanguageDef lang_sk("sk", "Slovak", 3, plural3_sk); // "nplurals=3;
plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
+LanguageDef lang_pl("pl", "Polish", 3, plural3_pl); // "nplurals=3;
plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
+LanguageDef lang_sl("sl", "Slovenian", 3, plural3_sl); // "nplurals=4;
plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
+//*}
+
+LanguageDef&
+get_language_def(const std::string& name)
+{
+ if (name == "hu") return lang_hu;
+ else if (name == "ja") return lang_ja;
+ else if (name == "ko") return lang_ko;
+ else if (name == "tr") return lang_tr;
+ else if (name == "da") return lang_da;
+ else if (name == "nl") return lang_nl;
+ else if (name == "en") return lang_en;
+ else if (name == "fo") return lang_fo;
+ else if (name == "de") return lang_de;
+ else if (name == "nb") return lang_nb;
+ else if (name == "no") return lang_no;
+ else if (name == "nn") return lang_nn;
+ else if (name == "sv") return lang_sv;
+ else if (name == "et") return lang_et;
+ else if (name == "fi") return lang_fi;
+ else if (name == "el") return lang_el;
+ else if (name == "he") return lang_he;
+ else if (name == "it") return lang_it;
+ else if (name == "pt") return lang_pt;
+ else if (name == "es") return lang_es;
+ else if (name == "eo") return lang_eo;
+ else if (name == "fr") return lang_fr;
+ else if (name == "pt_BR") return lang_pt_BR;
+ else if (name == "lv") return lang_lv;
+ else if (name == "ga") return lang_ga;
+ else if (name == "lt") return lang_lt;
+ else if (name == "hr") return lang_hr;
+ else if (name == "cs") return lang_cs;
+ else if (name == "ru") return lang_ru;
+ else if (name == "uk") return lang_uk;
+ else if (name == "sk") return lang_sk;
+ else if (name == "pl") return lang_pl;
+ else if (name == "sl") return lang_sl;
+ else return lang_en;
+}
+
+} // namespace TinyGetText
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/language_def.cpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: branches/pingus_sdl/src/tinygettext/language_def.hpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/language_def.hpp 2007-08-16
21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/tinygettext/language_def.hpp 2007-08-16
22:43:45 UTC (rev 2981)
@@ -0,0 +1,100 @@
+/* $Id$
+** __ __ __ ___ __ __ __ __
+** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
+** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
+** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
+** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
+** \/ \/ \/ \/ \/
+** Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+**
+** 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.
+*/
+
+#ifndef HEADER_LANGUAGE_DEF_HPP
+#define HEADER_LANGUAGE_DEF_HPP
+
+#include <string>
+
+namespace TinyGetText {
+
+typedef int (*PluralFunc)(int n);
+
+struct LanguageDef {
+ const char* code;
+ const char* name;
+ int nplural;
+ PluralFunc plural;
+
+ LanguageDef(const char* code_, const char* name_, int nplural_, PluralFunc
plural_)
+ : code(code_), name(name_), nplural(nplural_), plural(plural_)
+ {}
+};
+
+/** Read the content of the .po file given as \a in into the
+ dictionary given as \a dict */
+LanguageDef& get_language_def(const std::string& name);
+
+extern LanguageDef lang_hu;
+extern LanguageDef lang_ja;
+extern LanguageDef lang_ko;
+extern LanguageDef lang_tr;
+extern LanguageDef lang_da;
+extern LanguageDef lang_nl;
+extern LanguageDef lang_en;
+extern LanguageDef lang_fo;
+extern LanguageDef lang_de;
+extern LanguageDef lang_nb;
+extern LanguageDef lang_no;
+extern LanguageDef lang_nn;
+extern LanguageDef lang_sv;
+extern LanguageDef lang_et;
+extern LanguageDef lang_fi;
+extern LanguageDef lang_el;
+extern LanguageDef lang_he;
+extern LanguageDef lang_it;
+extern LanguageDef lang_pt;
+extern LanguageDef lang_es;
+extern LanguageDef lang_eo;
+extern LanguageDef lang_fr;
+extern LanguageDef lang_pt_BR;
+extern LanguageDef lang_lv;
+extern LanguageDef lang_ga;
+extern LanguageDef lang_lt;
+extern LanguageDef lang_hr;
+extern LanguageDef lang_cs;
+extern LanguageDef lang_ru;
+extern LanguageDef lang_uk;
+extern LanguageDef lang_sk;
+extern LanguageDef lang_pl;
+extern LanguageDef lang_sl;
+
+int plural1(int );
+int plural2_1(int n);
+int plural2_2(int n);
+int plural3_lv(int n);
+int plural3_ga(int n);
+int plural3_lt(int n);
+int plural3_1(int n);
+int plural3_sk(int n);
+int plural3_pl(int n);
+int plural3_sl(int n);
+
+} // namespace TinyGetText
+
+
+#endif
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/language_def.hpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: branches/pingus_sdl/src/tinygettext/po_file_reader.cpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/po_file_reader.cpp 2007-08-16
21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/tinygettext/po_file_reader.cpp 2007-08-16
22:43:45 UTC (rev 2981)
@@ -0,0 +1,390 @@
+// $Id$
+//
+// TinyGetText - A small flexible gettext() replacement
+// Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+//
+// 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.
+
+#include <config.h>
+#include <vector>
+#include <iconv.h>
+#include <errno.h>
+#include <sstream>
+#include <stdexcept>
+#include "po_file_reader.hpp"
+
+namespace TinyGetText {
+
+static bool has_prefix(const std::string& lhs, const std::string rhs)
+{
+ if (lhs.length() < rhs.length())
+ return false;
+ else
+ return lhs.compare(0, rhs.length(), rhs) == 0;
+}
+
+
+class charconv
+{
+public:
+ std::string incharset;
+ std::string outcharset;
+
+ charconv() : m_conv(0)
+ {}
+
+ charconv(const std::string& incharset_, const std::string& outcharset_)
+ : incharset(incharset_),
+ outcharset(outcharset_),
+ m_conv(0)
+ {
+ create(incharset, outcharset);
+ }
+
+ ~charconv()
+ {
+ close();
+ }
+
+ void create(const std::string& incharset, const std::string& outcharset)
+ {
+ // Create the converter.
+ if(!(m_conv = iconv_open(incharset.c_str(),
outcharset.c_str())))
+ {
+ if(errno == EINVAL)
+ {
+ std::ostringstream sstr;
+ sstr << "Unsupported conversion: " << incharset
+ << " => " << outcharset << "!";
+ throw std::runtime_error(sstr.str());
+ }
+ else
+ {
+ throw std::runtime_error(strerror(errno));
+ }
+ std::cout << "Something when very wrong" << std::endl;
+ exit(1);
+ }
+ }
+
+ void close()
+ {
+ // Free, if exists.
+ if(m_conv)
+ {
+ iconv_close(m_conv);
+ m_conv = 0;
+ }
+ }
+
+ /// Convert a string from encoding to another.
+ std::string convert(std::string text)
+ {
+ if(!m_conv) return text;
+
+ size_t in_size = text.size();
+ size_t out_size = 4*in_size; // Worst case scenario: ASCII ->
UTF-32?
+ std::string result(out_size, ' ');
+ ICONV_CONST char* in_str = &text[0];
+ char* out_str = &result[0];
+
+ // Try to convert the text.
+ if(iconv(m_conv, &in_str, &in_size, &out_str, &out_size) != 0) {
+ std::cout << "TinyGetText: text: \"" << text << "\"" <<
std::endl;
+ std::cout << "TinyGetText: Error while converting ("
+ << incharset << " -> " << outcharset
+ << "): " << strerror(errno) << std::endl;
+ exit(1);
+ }
+ // Eat off the spare space.
+ result.resize(out_str - &result[0]);
+ return result;
+ }
+protected:
+ iconv_t m_conv;
+};
+
+
+/** Convert \a which is in \a from_charset to \a to_charset and return it */
+std::string convert(const std::string& text,
+ const std::string& from_charset,
+ const std::string& to_charset)
+{
+ if (from_charset == to_charset)
+ return text;
+
+ charconv *cc = new charconv(from_charset, to_charset);
+ std::string ret = cc->convert(text);
+ cc->close();
+ return ret;
+}
+/*
+ iconv_t cd = iconv_open(to_charset.c_str(), from_charset.c_str());
+
+ size_t in_len = text.length();
+ size_t out_len = text.length()*4; // Should be large enough to hold UTF-32
+
+ char* out_orig = new char[out_len]; // FIXME: cross fingers that this is
enough
+ char* in_orig = new char[in_len+1];
+ strcpy(in_orig, text.c_str());
+
+ char* out = out_orig;
+ const char* in = in_orig;
+
+ //std::cout << "IN: " << (int)in << " " << in_len << " " << (int)out << " "
<< out_len << std::endl;
+ int retval = iconv(cd, &in, &in_len, &out, &out_len);
+ //std::cout << "OUT: " << (int)in << " " << in_len << " " << (int)out << " "
<< out_len << std::endl;
+
+ if (retval != 0)
+ {
+ std::cerr << strerror(errno) << std::endl;
+ std::cerr << "Error: conversion from " << from_charset
+ << " to " << to_charset << " went wrong: " << retval <<
std::endl;
+ }
+ iconv_close(cd);
+
+
+ <dolphin> your code is also buggy
+<dolphin> there will be extra spaces at the end of the string
+<dolphin> the lenght of the final string should be: out_str - out_orig
+<dolphin> or: out_size_before_iconv_call - out_size_after_iconv_call
+
+ std::string ret(out_orig, out_len);
+ delete[] out_orig;
+ delete[] in_orig;
+ return ret;
+}
+*/
+
+POFileReader::POFileReader(std::istream& in, Dictionary& dict_)
+ : dict(dict_)
+{
+ state = WANT_MSGID;
+ line_num = 0;
+ tokenize_po(in);
+}
+
+void
+POFileReader::parse_header(const std::string& header)
+{
+ // Seperate the header in lines
+ typedef std::vector<std::string> Lines;
+ Lines lines;
+
+ std::string::size_type start = 0;
+ for(std::string::size_type i = 0; i < header.length(); ++i)
+ {
+ if (header[i] == '\n')
+ {
+ lines.push_back(header.substr(start, i - start));
+ start = i+1;
+ }
+ }
+
+ for(Lines::iterator i = lines.begin(); i != lines.end(); ++i)
+ {
+ if (has_prefix(*i, "Content-Type: text/plain; charset=")) {
+ from_charset = i->substr(strlen("Content-Type: text/plain; charset="));
+ }
+ }
+
+ if (from_charset.empty() || from_charset == "CHARSET")
+ {
+ std::cerr << "Error: Charset not specified for .po, fallback to
ISO-8859-1" << std::endl;
+ from_charset = "ISO-8859-1";
+ }
+
+ to_charset = dict.get_charset();
+ if (to_charset.empty())
+ { // No charset requested from the dict, so we use the one from the .po
+ to_charset = from_charset;
+ dict.set_charset(from_charset);
+ }
+}
+
+void
+POFileReader::add_token(const Token& token)
+{
+ switch(state)
+ {
+ case WANT_MSGID:
+ if (token.keyword == "msgid")
+ {
+ current_msgid = token.content;
+ state = WANT_MSGID_PLURAL;
+ }
+ else if (token.keyword.empty())
+ {
+ //std::cerr << "Got EOF, everything looks ok." << std::endl;
+ }
+ else
+ {
+ std::cerr << "tinygettext: expected 'msgid' keyword, got '" <<
token.keyword
+ << "' at line " << line_num << std::endl;
+ }
+ break;
+
+ case WANT_MSGID_PLURAL:
+ if (token.keyword == "msgid_plural")
+ {
+ current_msgid_plural = token.content;
+ state = WANT_MSGSTR_PLURAL;
+ }
+ else
+ {
+ state = WANT_MSGSTR;
+ add_token(token);
+ }
+ break;
+
+ case WANT_MSGSTR:
+ if (token.keyword == "msgstr")
+ {
+ if (current_msgid == "")
+ { // .po Header is hidden in the msgid with the empty string
+ parse_header(token.content);
+ }
+ else
+ {
+ dict.add_translation(current_msgid, convert(token.content,
from_charset, to_charset));
+ }
+ state = WANT_MSGID;
+ }
+ else
+ {
+ std::cerr << "tinygettext: expected 'msgstr' keyword, got " <<
token.keyword
+ << " at line " << line_num << std::endl;
+ }
+ break;
+
+ case WANT_MSGSTR_PLURAL:
+ if (has_prefix(token.keyword, "msgstr["))
+ {
+ int num;
+ if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1)
+ {
+ std::cerr << "Error: Couldn't parse: " << token.keyword <<
std::endl;
+ }
+ else
+ {
+ msgstr_plural[num] = convert(token.content, from_charset,
to_charset);
+ }
+ }
+ else
+ {
+ dict.add_translation(current_msgid, current_msgid_plural,
msgstr_plural);
+
+ state = WANT_MSGID;
+ add_token(token);
+ }
+ break;
+ }
+}
+
+void
+POFileReader::tokenize_po(std::istream& in)
+{
+ enum State { READ_KEYWORD,
+ READ_CONTENT,
+ READ_CONTENT_IN_STRING,
+ SKIP_COMMENT };
+
+ State state = READ_KEYWORD;
+ int c;
+ Token token;
+
+ while((c = getchar(in)) != EOF)
+ {
+ //std::cout << "Lexing char: '" << char(c) << "' " << c << " state: " <<
state << std::endl;
+ switch(state)
+ {
+ case READ_KEYWORD:
+ if (c == '#')
+ {
+ state = SKIP_COMMENT;
+ }
+ else if (isspace(c))
+ {
+ state = READ_KEYWORD;
+ }
+ else
+ {
+ // Read a new token
+ token = Token();
+
+ do { // Read keyword
+ token.keyword += c;
+ } while((c = getchar(in)) != EOF && !isspace(c));
+ in.unget();
+
+ state = READ_CONTENT;
+ }
+ break;
+
+ case READ_CONTENT:
+ while((c = getchar(in)) != EOF)
+ {
+ if (c == '"') {
+ // Found start of content
+ state = READ_CONTENT_IN_STRING;
+ break;
+ } else if (isspace(c)) {
+ // skip
+ } else { // Read something that may be a keyword
+ in.unget();
+ state = READ_KEYWORD;
+ add_token(token);
+ break;
+ }
+ }
+ break;
+
+ case READ_CONTENT_IN_STRING:
+ if (c == '\\') {
+ c = getchar(in);
+ if (c != EOF)
+ {
+ if (c == 'n') token.content += '\n';
+ else if (c == 't') token.content += '\t';
+ else if (c == 'r') token.content += '\r';
+ else if (c == '"') token.content += '"';
+ else
+ {
+ std::cout << "Unhandled escape character: " << char(c) <<
std::endl;
+ }
+ }
+ else
+ {
+ std::cout << "Unterminated string" << std::endl;
+ }
+ } else if (c == '"') { // Content string is terminated
+ state = READ_CONTENT;
+ } else {
+ token.content += c;
+ }
+ break;
+
+ case SKIP_COMMENT:
+ if (c == '\n')
+ state = READ_KEYWORD;
+ break;
+ }
+ }
+ // add_token(token);
+}
+
+} // namespace TinyGetText
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/po_file_reader.cpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: branches/pingus_sdl/src/tinygettext/po_file_reader.hpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/po_file_reader.hpp 2007-08-16
21:52:17 UTC (rev 2980)
+++ branches/pingus_sdl/src/tinygettext/po_file_reader.hpp 2007-08-16
22:43:45 UTC (rev 2981)
@@ -0,0 +1,72 @@
+// $Id$
+//
+// TinyGetText - A small flexible gettext() replacement
+// Copyright (C) 2007 Ingo Ruhnke <address@hidden>
+//
+// 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.
+
+#ifndef HEADER_PO_FILE_READER_HPP
+#define HEADER_PO_FILE_READER_HPP
+
+#include <string>
+#include <iostream>
+#include "dictionary.hpp"
+
+namespace TinyGetText {
+
+class POFileReader
+{
+private:
+ struct Token
+ {
+ std::string keyword;
+ std::string content;
+ };
+
+ Dictionary& dict;
+
+ std::string from_charset;
+ std::string to_charset;
+
+ std::string current_msgid;
+ std::string current_msgid_plural;
+ std::map<int, std::string> msgstr_plural;
+
+ int line_num;
+
+ enum { WANT_MSGID, WANT_MSGSTR, WANT_MSGSTR_PLURAL, WANT_MSGID_PLURAL }
state;
+
+public:
+ POFileReader(std::istream& in, Dictionary& dict_);
+
+ void parse_header(const std::string& header);
+ void add_token(const Token& token);
+ void tokenize_po(std::istream& in);
+
+ inline int getchar(std::istream& in)
+ {
+ int c = in.get();
+ if (c == '\n')
+ line_num += 1;
+ return c;
+ }
+
+};
+
+} // namespace TinyGetText
+
+#endif
+
+/* EOF */
Property changes on: branches/pingus_sdl/src/tinygettext/po_file_reader.hpp
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Deleted: branches/pingus_sdl/src/tinygettext/tinygettext.cpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/tinygettext.cpp 2007-08-16 21:52:17 UTC
(rev 2980)
+++ branches/pingus_sdl/src/tinygettext/tinygettext.cpp 2007-08-16 22:43:45 UTC
(rev 2981)
@@ -1,792 +0,0 @@
-// $Id: tinygettext.cpp,v 1.4 2004/11/25 13:15:56 matzebraun Exp $
-//
-// TinyGetText - A small flexible gettext() replacement
-// Copyright (C) 2004 Ingo Ruhnke <address@hidden>
-//
-// 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.
-
-#include <config.h>
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#else
-#include "../win32/uce_dirent.h"
-#endif
-
-#include <sys/types.h>
-#include <iconv.h>
-#include <fstream>
-#include <iostream>
-#include <ctype.h>
-#include <errno.h>
-#include "tinygettext.hpp"
-
-//#define TRANSLATION_DEBUG
-
-namespace TinyGetText {
-
-class charconv
-{
-public:
- charconv() : m_conv(0)
- {}
-
- charconv(const std::string& incharset, const std::string& outcharset)
- : m_conv(0)
- {
- create(incharset, outcharset);
- }
-
- ~charconv()
- {
- close();
- }
-
- void create(const std::string& incharset, const std::string& outcharset)
- {
- // Create the converter.
- if(!(m_conv = iconv_open(incharset.c_str(),
outcharset.c_str())))
- {
- /*if(errno == EINVAL)
- {
- ostringstream sstr;
- sstr << "Unsupported conversion: " << incharset
- << " => " << outcharset << "!";
- throw runtime_error(sstr.str());
- }
- else
- throw runtime_error(strerror(errno));
- */
- exit(1);
- }
- }
-
- void close()
- {
- // Free, if exists.
- if(m_conv)
- {
- iconv_close(m_conv);
- m_conv = 0;
- }
- }
-
- /// Convert a string from encoding to another.
- std::string convert(std::string text)
- {
- if(!m_conv) return text;
-
- size_t in_size = text.size();
- size_t out_size = 4*in_size; // Worst case scenario: ASCII ->
UTF-32?
- std::string result(out_size, ' ');
- ICONV_CONST char* in_str = &text[0];
- char* out_str = &result[0];
-
- // Try to convert the text.
- if(iconv(m_conv, &in_str, &in_size, &out_str, &out_size) != 0)
- //PingusError::raise("Error while converting: " +
strerror(errno));
- exit(1);
- // Eat off the spare space.
- result.resize(out_str - &result[0]);
- return result;
- }
-protected:
- iconv_t m_conv;
-};
-
-
-/** Convert \a which is in \a from_charset to \a to_charset and return it */
-std::string convert(const std::string& text,
- const std::string& from_charset,
- const std::string& to_charset)
-{
- if (from_charset == to_charset)
- return text;
-
- charconv *cc = new charconv(from_charset, to_charset);
- std::string ret = cc->convert(text);
- cc->close();
- return ret;
-}
-/*
- iconv_t cd = iconv_open(to_charset.c_str(), from_charset.c_str());
-
- size_t in_len = text.length();
- size_t out_len = text.length()*4; // Should be large enough to hold UTF-32
-
- char* out_orig = new char[out_len]; // FIXME: cross fingers that this is
enough
- char* in_orig = new char[in_len+1];
- strcpy(in_orig, text.c_str());
-
- char* out = out_orig;
- const char* in = in_orig;
-
- //std::cout << "IN: " << (int)in << " " << in_len << " " << (int)out << " "
<< out_len << std::endl;
- int retval = iconv(cd, &in, &in_len, &out, &out_len);
- //std::cout << "OUT: " << (int)in << " " << in_len << " " << (int)out << " "
<< out_len << std::endl;
-
- if (retval != 0)
- {
- std::cerr << strerror(errno) << std::endl;
- std::cerr << "Error: conversion from " << from_charset
- << " to " << to_charset << " went wrong: " << retval <<
std::endl;
- }
- iconv_close(cd);
-
-
- <dolphin> your code is also buggy
-<dolphin> there will be extra spaces at the end of the string
-<dolphin> the lenght of the final string should be: out_str - out_orig
-<dolphin> or: out_size_before_iconv_call - out_size_after_iconv_call
-
- std::string ret(out_orig, out_len);
- delete[] out_orig;
- delete[] in_orig;
- return ret;
-}
-*/
-
-bool has_suffix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0;
-}
-
-bool has_prefix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(0, rhs.length(), rhs) == 0;
-}
-
-int plural1(int ) { return 0; }
-int plural2_1(int n) { return (n != 1); }
-int plural2_2(int n) { return (n > 1); }
-int plural3_lv(int n) { return (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
-int plural3_ga(int n) { return n==1 ? 0 : n==2 ? 1 : 2; }
-int plural3_lt(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 &&
(n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_1(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4
&& (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_sk(int n) { return (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; }
-int plural3_pl(int n) { return (n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2); }
-int plural3_sl(int n) { return (n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 ||
n%100==4 ? 2 : 3); }
-
-/** Language Definitions */
-//*{
-LanguageDef lang_hu("hu", "Hungarian", 1, plural1); // "nplurals=1;
plural=0;"
-LanguageDef lang_ja("ja", "Japanese", 1, plural1); // "nplurals=1;
plural=0;"
-LanguageDef lang_ko("ko", "Korean", 1, plural1); // "nplurals=1;
plural=0;"
-LanguageDef lang_tr("tr", "Turkish", 1, plural1); // "nplurals=1;
plural=0;"
-LanguageDef lang_da("da", "Danish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_nl("nl", "Dutch", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_en("en", "English", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_fo("fo", "Faroese", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_de("de", "German", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_nb("nb", "Norwegian Bokmal", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_no("no", "Norwegian", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_nn("nn", "Norwegian Nynorsk", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_sv("sv", "Swedish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_et("et", "Estonian", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_fi("fi", "Finnish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_el("el", "Greek", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_he("he", "Hebrew", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_it("it", "Italian", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_pt("pt", "Portuguese", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_es("es", "Spanish", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_eo("eo", "Esperanto", 2, plural2_1); // "nplurals=2;
plural=(n != 1);"
-LanguageDef lang_fr("fr", "French", 2, plural2_2); // "nplurals=2;
plural=(n > 1);"
-LanguageDef lang_pt_BR("pt_BR", "Brazilian", 2, plural2_2); // "nplurals=2;
plural=(n > 1);"
-LanguageDef lang_lv("lv", "Latvian", 3, plural3_lv); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
-LanguageDef lang_ga("ga", "Irish", 3, plural3_ga); // "nplurals=3;
plural=n==1 ? 0 : n==2 ? 1 : 2;"
-LanguageDef lang_lt("lt", "Lithuanian", 3, plural3_lt); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_hr("hr", "Croatian", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
-LanguageDef lang_cs("cs", "Czech", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
-LanguageDef lang_ru("ru", "Russian", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
-LanguageDef lang_uk("uk", "Ukrainian", 3, plural3_1); // "nplurals=3;
plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 ||
n%100>=20) ? 1 : 2);"
-LanguageDef lang_sk("sk", "Slovak", 3, plural3_sk); // "nplurals=3;
plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
-LanguageDef lang_pl("pl", "Polish", 3, plural3_pl); // "nplurals=3;
plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
-LanguageDef lang_sl("sl", "Slovenian", 3, plural3_sl); // "nplurals=4;
plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
-//*}
-
-LanguageDef&
-get_language_def(const std::string& name)
-{
- if (name == "hu") return lang_hu;
- else if (name == "ja") return lang_ja;
- else if (name == "ko") return lang_ko;
- else if (name == "tr") return lang_tr;
- else if (name == "da") return lang_da;
- else if (name == "nl") return lang_nl;
- else if (name == "en") return lang_en;
- else if (name == "fo") return lang_fo;
- else if (name == "de") return lang_de;
- else if (name == "nb") return lang_nb;
- else if (name == "no") return lang_no;
- else if (name == "nn") return lang_nn;
- else if (name == "sv") return lang_sv;
- else if (name == "et") return lang_et;
- else if (name == "fi") return lang_fi;
- else if (name == "el") return lang_el;
- else if (name == "he") return lang_he;
- else if (name == "it") return lang_it;
- else if (name == "pt") return lang_pt;
- else if (name == "es") return lang_es;
- else if (name == "eo") return lang_eo;
- else if (name == "fr") return lang_fr;
- else if (name == "pt_BR") return lang_pt_BR;
- else if (name == "lv") return lang_lv;
- else if (name == "ga") return lang_ga;
- else if (name == "lt") return lang_lt;
- else if (name == "hr") return lang_hr;
- else if (name == "cs") return lang_cs;
- else if (name == "ru") return lang_ru;
- else if (name == "uk") return lang_uk;
- else if (name == "sk") return lang_sk;
- else if (name == "pl") return lang_pl;
- else if (name == "sl") return lang_sl;
- else return lang_en;
-}
-
-DictionaryManager::DictionaryManager()
- : current_dict(&empty_dict)
-{
- parseLocaleAliases();
- // setup language from environment vars
- const char* lang = getenv("LC_ALL");
- if(!lang)
- lang = getenv("LC_MESSAGES");
- if(!lang)
- lang = getenv("LANG");
-
- if(lang)
- set_language(lang);
-}
-
-void
-DictionaryManager::parseLocaleAliases()
-{
- // try to parse language alias list
- std::ifstream in("/usr/share/locale/locale.alias");
-
- char c = ' ';
- while(in.good() && !in.eof()) {
- while(isspace(c) && !in.eof())
- in.get(c);
-
- if(c == '#') { // skip comments
- while(c != '\n' && !in.eof())
- in.get(c);
- continue;
- }
-
- std::string alias;
- while(!isspace(c) && !in.eof()) {
- alias += c;
- in.get(c);
- }
- while(isspace(c) && !in.eof())
- in.get(c);
- std::string language;
- while(!isspace(c) && !in.eof()) {
- language += c;
- in.get(c);
- }
-
- if(in.eof())
- break;
- set_language_alias(alias, language);
- }
-}
-
-Dictionary&
-DictionaryManager::get_dictionary(const std::string& spec)
-{
- std::string lang = get_language_from_spec(spec);
- Dictionaries::iterator i = dictionaries.find(get_language_from_spec(lang));
- if (i != dictionaries.end())
- {
- return i->second;
- }
- else // Dictionary for languages lang isn't loaded, so we load it
- {
- //std::cout << "get_dictionary: " << lang << std::endl;
- Dictionary& dict = dictionaries[lang];
-
- dict.set_language(get_language_def(lang));
- if(charset != "")
- dict.set_charset(charset);
-
- for (SearchPath::iterator p = search_path.begin(); p !=
search_path.end(); ++p)
- {
- DIR* dir = opendir(p->c_str());
- if (!dir)
- {
- std::cerr << "TinyGetText: Error: opendir() failed on " << *p <<
std::endl;
- }
- else
- {
- struct dirent* ent;
- while((ent = readdir(dir)))
- {
- if (std::string(ent->d_name) == lang + ".po")
- {
- std::string pofile = *p + "/" + ent->d_name;
- std::ifstream in(pofile.c_str());
- if (!in)
- {
- std::cerr << "Error: Failure file opening: " <<
pofile << std::endl;
- }
- else
- {
- read_po_file(dict, in);
- }
- }
- }
- closedir(dir);
- }
- }
-
- return dict;
- }
-}
-
-std::set<std::string>
-DictionaryManager::get_languages()
-{
- std::set<std::string> languages;
-
- for (SearchPath::iterator p = search_path.begin(); p != search_path.end();
++p)
- {
- DIR* dir = opendir(p->c_str());
- if (!dir)
- {
- std::cerr << "Error: opendir() failed on " << *p << std::endl;
- }
- else
- {
- struct dirent* ent;
- while((ent = readdir(dir)))
- {
- if (has_suffix(ent->d_name, ".po"))
- {
- std::string filename = ent->d_name;
- languages.insert(filename.substr(0, filename.length()-3));
- }
- }
- closedir(dir);
- }
- }
- return languages;
-}
-
-void
-DictionaryManager::set_language(const std::string& lang)
-{
- language = get_language_from_spec(lang);
- current_dict = & (get_dictionary(language));
-}
-
-void
-DictionaryManager::set_charset(const std::string& charset)
-{
- dictionaries.clear(); // changing charset invalidates cache
- this->charset = charset;
- set_language(language);
-}
-
-void
-DictionaryManager::set_language_alias(const std::string& alias,
- const std::string& language)
-{
- language_aliases.insert(std::make_pair(alias, language));
-}
-
-std::string
-DictionaryManager::get_language_from_spec(const std::string& spec)
-{
- std::string lang = spec;
- Aliases::iterator i = language_aliases.find(lang);
- if(i != language_aliases.end()) {
- lang = i->second;
- }
-
- std::string::size_type s = lang.find_first_of("_.");
- if(s == std::string::npos)
- return lang;
-
- return std::string(lang, 0, s);
-}
-
-void
-DictionaryManager::add_directory(const std::string& pathname)
-{
- dictionaries.clear(); // adding directories invalidates cache
- search_path.push_back(pathname);
- set_language(language);
-}
-
-//---------------------------------------------------------------------------
-
-Dictionary::Dictionary(const LanguageDef& language_, const std::string&
charset_)
- : language(language_), charset(charset_)
-{
-}
-
-Dictionary::Dictionary()
- : language(lang_en)
-{
-}
-
-std::string
-Dictionary::get_charset() const
-{
- return charset;
-}
-
-void
-Dictionary::set_charset(const std::string& charset_)
-{
- charset = charset_;
-}
-
-void
-Dictionary::set_language(const LanguageDef& lang)
-{
- language = lang;
-}
-
-std::string
-Dictionary::translate(const std::string& msgid, const std::string& msgid2, int
num)
-{
- PluralEntries::iterator i = plural_entries.find(msgid);
- std::map<int, std::string>& msgstrs = i->second;
-
- if (i != plural_entries.end() && !msgstrs.empty())
- {
- int g = language.plural(num);
- std::map<int, std::string>::iterator j = msgstrs.find(g);
- if (j != msgstrs.end())
- {
- return j->second;
- }
- else
- {
- // Return the first translation, in case we can't translate the
specific number
- return msgstrs.begin()->second;
- }
- }
- else
- {
-#ifdef TRANSLATION_DEBUG
- std::cerr << "Warning: Couldn't translate: " << msgid << std::endl;
- std::cerr << "Candidates: " << std::endl;
- for (PluralEntries::iterator i = plural_entries.begin(); i !=
plural_entries.end(); ++i)
- std::cout << "'" << i->first << "'" << std::endl;
-#endif
-
- if (plural2_1(num)) // default to english rules
- return msgid2;
- else
- return msgid;
- }
-}
-
-std::string
-Dictionary::translate(const std::string& msgid)
-{
- Entries::iterator i = entries.find(msgid);
- if (i != entries.end() && !i->second.empty())
- {
- return i->second;
- }
- else
- {
-#ifdef TRANSLATION_DBEUG
- std::cout << "Error: Couldn't translate: " << msgid << std::endl;
-#endif
- return msgid;
- }
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string& ,
- const std::map<int, std::string>& msgstrs)
-{
- // Do we need msgid2 for anything? its after all supplied to the
- // translate call, so we just throw it away
- plural_entries[msgid] = msgstrs;
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string&
msgstr)
-{
- entries[msgid] = msgstr;
-}
-
-class POFileReader
-{
-private:
- struct Token
- {
- std::string keyword;
- std::string content;
- };
-
- Dictionary& dict;
-
- std::string from_charset;
- std::string to_charset;
-
- std::string current_msgid;
- std::string current_msgid_plural;
- std::map<int, std::string> msgstr_plural;
-
- int line_num;
-
- enum { WANT_MSGID, WANT_MSGSTR, WANT_MSGSTR_PLURAL, WANT_MSGID_PLURAL }
state;
-
-public:
- POFileReader(std::istream& in, Dictionary& dict_)
- : dict(dict_)
- {
- state = WANT_MSGID;
- line_num = 0;
- tokenize_po(in);
- }
-
- void parse_header(const std::string& header)
- {
- // Seperate the header in lines
- typedef std::vector<std::string> Lines;
- Lines lines;
-
- std::string::size_type start = 0;
- for(std::string::size_type i = 0; i < header.length(); ++i)
- {
- if (header[i] == '\n')
- {
- lines.push_back(header.substr(start, i - start));
- start = i+1;
- }
- }
-
- for(Lines::iterator i = lines.begin(); i != lines.end(); ++i)
- {
- if (has_prefix(*i, "Content-Type: text/plain; charset=")) {
- from_charset = i->substr(strlen("Content-Type: text/plain;
charset="));
- }
- }
-
- if (from_charset.empty() || from_charset == "CHARSET")
- {
- std::cerr << "Error: Charset not specified for .po, fallback to
ISO-8859-1" << std::endl;
- from_charset = "ISO-8859-1";
- }
-
- to_charset = dict.get_charset();
- if (to_charset.empty())
- { // No charset requested from the dict, so we use the one from the .po
- to_charset = from_charset;
- dict.set_charset(from_charset);
- }
- }
-
- void add_token(const Token& token)
- {
- switch(state)
- {
- case WANT_MSGID:
- if (token.keyword == "msgid")
- {
- current_msgid = token.content;
- state = WANT_MSGID_PLURAL;
- }
- else if (token.keyword.empty())
- {
- //std::cerr << "Got EOF, everything looks ok." << std::endl;
- }
- else
- {
- std::cerr << "tinygettext: expected 'msgid' keyword, got '" <<
token.keyword
- << "' at line " << line_num << std::endl;
- }
- break;
-
- case WANT_MSGID_PLURAL:
- if (token.keyword == "msgid_plural")
- {
- current_msgid_plural = token.content;
- state = WANT_MSGSTR_PLURAL;
- }
- else
- {
- state = WANT_MSGSTR;
- add_token(token);
- }
- break;
-
- case WANT_MSGSTR:
- if (token.keyword == "msgstr")
- {
- if (current_msgid == "")
- { // .po Header is hidden in the msgid with the empty string
- parse_header(token.content);
- }
- else
- {
- dict.add_translation(current_msgid, convert(token.content,
from_charset, to_charset));
- }
- state = WANT_MSGID;
- }
- else
- {
- std::cerr << "tinygettext: expected 'msgstr' keyword, got " <<
token.keyword
- << " at line " << line_num << std::endl;
- }
- break;
-
- case WANT_MSGSTR_PLURAL:
- if (has_prefix(token.keyword, "msgstr["))
- {
- int num;
- if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1)
- {
- std::cerr << "Error: Couldn't parse: " << token.keyword <<
std::endl;
- }
- else
- {
- msgstr_plural[num] = convert(token.content, from_charset,
to_charset);
- }
- }
- else
- {
- dict.add_translation(current_msgid, current_msgid_plural,
msgstr_plural);
-
- state = WANT_MSGID;
- add_token(token);
- }
- break;
- }
- }
-
- inline int getchar(std::istream& in)
- {
- int c = in.get();
- if (c == '\n')
- line_num += 1;
- return c;
- }
-
- void tokenize_po(std::istream& in)
- {
- enum State { READ_KEYWORD,
- READ_CONTENT,
- READ_CONTENT_IN_STRING,
- SKIP_COMMENT };
-
- State state = READ_KEYWORD;
- int c;
- Token token;
-
- while((c = getchar(in)) != EOF)
- {
- //std::cout << "Lexing char: '" << char(c) << "' " << c << " state: "
<< state << std::endl;
- switch(state)
- {
- case READ_KEYWORD:
- if (c == '#')
- {
- state = SKIP_COMMENT;
- }
- else if (isspace(c))
- {
- state = READ_KEYWORD;
- }
- else
- {
- // Read a new token
- token = Token();
-
- do { // Read keyword
- token.keyword += c;
- } while((c = getchar(in)) != EOF && !isspace(c));
- in.unget();
-
- state = READ_CONTENT;
- }
- break;
-
- case READ_CONTENT:
- while((c = getchar(in)) != EOF)
- {
- if (c == '"') {
- // Found start of content
- state = READ_CONTENT_IN_STRING;
- break;
- } else if (isspace(c)) {
- // skip
- } else { // Read something that may be a keyword
- in.unget();
- state = READ_KEYWORD;
- add_token(token);
- break;
- }
- }
- break;
-
- case READ_CONTENT_IN_STRING:
- if (c == '\\') {
- c = getchar(in);
- if (c != EOF)
- {
- if (c == 'n') token.content += '\n';
- else if (c == 't') token.content += '\t';
- else if (c == 'r') token.content += '\r';
- else if (c == '"') token.content += '"';
- else
- {
- std::cout << "Unhandled escape character: " << char(c)
<< std::endl;
- }
- }
- else
- {
- std::cout << "Unterminated string" << std::endl;
- }
- } else if (c == '"') { // Content string is terminated
- state = READ_CONTENT;
- } else {
- token.content += c;
- }
- break;
-
- case SKIP_COMMENT:
- if (c == '\n')
- state = READ_KEYWORD;
- break;
- }
- }
- // add_token(token);
- }
-};
-
-void read_po_file(Dictionary& dict_, std::istream& in)
-{
- POFileReader reader(in, dict_);
-}
-
-} // namespace TinyGetText
-
-/* EOF */
Deleted: branches/pingus_sdl/src/tinygettext/tinygettext.hpp
===================================================================
--- branches/pingus_sdl/src/tinygettext/tinygettext.hpp 2007-08-16 21:52:17 UTC
(rev 2980)
+++ branches/pingus_sdl/src/tinygettext/tinygettext.hpp 2007-08-16 22:43:45 UTC
(rev 2981)
@@ -1,156 +0,0 @@
-// $Id: tinygettext.h,v 1.2 2004/11/24 23:10:01 matzebraun Exp $
-//
-// TinyGetText - A small flexible gettext() replacement
-// Copyright (C) 2004 Ingo Ruhnke <address@hidden>
-//
-// 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.
-
-#ifndef HEADER_TINYGETTEXT_HXX
-#define HEADER_TINYGETTEXT_HXX
-
-#include <map>
-#include <vector>
-#include <set>
-#include <string>
-
-namespace TinyGetText {
-
-typedef int (*PluralFunc)(int n);
-
-struct LanguageDef {
- const char* code;
- const char* name;
- int nplural;
- PluralFunc plural;
-
- LanguageDef(const char* code_, const char* name_, int nplural_, PluralFunc
plural_)
- : code(code_), name(name_), nplural(nplural_), plural(plural_)
- {}
-};
-
-/** A simple dictionary class that mimics gettext() behaviour. Each
- Dictionary only works for a single language, for managing multiple
- languages and .po files at once use the DictionaryManager. */
-class Dictionary
-{
-private:
- typedef std::map<std::string, std::string> Entries;
- Entries entries;
-
- typedef std::map<std::string, std::map<int, std::string> > PluralEntries;
- PluralEntries plural_entries;
-
- LanguageDef language;
- std::string charset;
-public:
- /** */
- Dictionary(const LanguageDef& language_, const std::string& charset = "");
-
- Dictionary();
-
- /** Return the charset used for this dictionary */
- std::string get_charset() const;
-
- /** Set a charset for this dictionary, this will NOT convert stuff,
- it is for information only, you have to convert stuff yourself
- when you add it with \a add_translation() */
- void set_charset(const std::string& charset);
-
- /** Set the language that is used for this dictionary, this is
- mainly needed to evaluate plural forms */
- void set_language(const LanguageDef& lang);
-
- LanguageDef get_language() const { return language; }
-
- /** Translate the string \a msgid to its correct plural form, based
- on the number of items given by \a num. \a msgid2 is \a msgid in
- plural form. */
- std::string translate(const std::string& msgid, const std::string& msgid2,
int num);
-
- /** Translate the string \a msgid. */
- std::string translate(const std::string& msgid);
-
- /** Add a translation from \a msgid to \a msgstr to the dictionary,
- where \a msgid is the singular form of the message, msgid2 the
- plural form and msgstrs a table of translations. The right
- translation will be calculated based on the \a num argument to
- translate(). */
- void add_translation(const std::string& msgid, const std::string& msgid2,
- const std::map<int, std::string>& msgstrs);
-
- /** Add a translation from \a msgid to \a msgstr to the
- dictionary */
- void add_translation(const std::string& msgid, const std::string& msgstr);
-};
-
-/** Manager class for dictionaries, you give it a bunch of directories
- with .po files and it will then automatically load the right file
- on demand depending on which language was set. */
-class DictionaryManager
-{
-private:
- typedef std::map<std::string, Dictionary> Dictionaries;
- Dictionaries dictionaries;
- typedef std::vector<std::string> SearchPath;
- SearchPath search_path;
- typedef std::map<std::string, std::string> Aliases;
- Aliases language_aliases;
- std::string charset;
- std::string language;
- Dictionary* current_dict;
- Dictionary empty_dict;
-
-public:
- DictionaryManager();
-
- /** Return the currently active dictionary, if none is set, an empty
- dictionary is returned. */
- Dictionary& get_dictionary()
- { return *current_dict; }
-
- /** Get dictionary for lang */
- Dictionary& get_dictionary(const std::string& langspec);
-
- /** Set a language based on a four? letter country code */
- void set_language(const std::string& langspec);
-
- /** Set a charset that will be set on the returned dictionaries */
- void set_charset(const std::string& charset);
-
- /** Define an alias for a language */
- void set_language_alias(const std::string& alias, const std::string& lang);
-
- /** Add a directory to the search path for dictionaries */
- void add_directory(const std::string& pathname);
-
- /** Return a set of the available languages in their country code */
- std::set<std::string> get_languages();
-
-private:
- void parseLocaleAliases();
- /// returns the language part in a language spec (like de_DE.UTF-8 -> de)
- std::string get_language_from_spec(const std::string& spec);
-};
-
-/** Read the content of the .po file given as \a in into the
- dictionary given as \a dict */
-void read_po_file(Dictionary& dict, std::istream& in);
-LanguageDef& get_language_def(const std::string& name);
-
-} // namespace TinyGetText
-
-#endif
-
-/* EOF */
Modified: branches/pingus_sdl/src/worldmap/manager.cpp
===================================================================
--- branches/pingus_sdl/src/worldmap/manager.cpp 2007-08-16 21:52:17 UTC
(rev 2980)
+++ branches/pingus_sdl/src/worldmap/manager.cpp 2007-08-16 22:43:45 UTC
(rev 2981)
@@ -204,7 +204,7 @@
gc.print_right(Fonts::chalk_small,
(float)Display::get_width() - 40,
(float)Display::get_height() - 25,
- _("Enter"));
+ _("Enter?"));
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pingus-CVS] r2981 - in branches/pingus_sdl/src: . tinygettext worldmap,
grumbel at BerliOS <=