pingus-cvs
[Top][All Lists]
Advanced

[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?"));
     }
 }
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]