fix cr/lfs and remove trailing whitespaces...
[supertux.git] / src / tinygettext / tinygettext.cpp
index 0d3ec23..a9bb964 100644 (file)
@@ -1,7 +1,7 @@
 //  $Id$
-// 
-//  TinyGetText - A small flexible gettext() replacement
-//  Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+//  TinyGetText
+//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
 //  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 <sys/types.h>
@@ -29,6 +30,7 @@
 #include "log.hpp"
 #include "physfs/physfs_stream.hpp"
 #include "log.hpp"
+#include "findlocale.hpp"
 
 //#define TRANSLATION_DEBUG
 
@@ -43,7 +45,7 @@ std::string convert(const std::string& text,
     return text;
 
   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()*3; // FIXME: cross fingers that this is enough
 
@@ -172,22 +174,25 @@ get_language_def(const std::string& name)
   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; 
+  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);
+  // Environment variable SUPERTUX_LANG overrides language settings.
+  const char* lang = getenv( "SUPERTUX_LANG" );
+  if( lang ){
+    set_language( lang );
+    return;
+  }
+  // use findlocale to setup language
+  FL_Locale *locale;
+  FL_FindLocale( &locale, FL_MESSAGES );
+      if( locale->lang)
+        set_language( locale->lang );
+  FL_FreeLocale( &locale );
 }
 
 void
@@ -195,18 +200,18 @@ 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;
@@ -225,7 +230,7 @@ DictionaryManager::parseLocaleAliases()
     set_language_alias(alias, language);
   }
 }
-  
+
 Dictionary&
 DictionaryManager::get_dictionary(const std::string& spec)
 {
@@ -247,7 +252,7 @@ DictionaryManager::get_dictionary(const std::string& spec)
       for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
         {
           char** files = PHYSFS_enumerateFiles(p->c_str());
-          if(!files) 
+          if(!files)
             {
               log_warning << "Error: enumerateFiles() failed on " << *p << std::endl;
             }
@@ -296,7 +301,7 @@ DictionaryManager::get_languages()
           }
           PHYSFS_freeList(files);
         }
-    }  
+    }
   return languages;
 }
 
@@ -336,12 +341,12 @@ DictionaryManager::get_language_from_spec(const std::string& spec)
   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);  
+  return std::string(lang, 0, s);
 }
 
 void
@@ -383,7 +388,7 @@ Dictionary::set_language(const LanguageDef& lang)
 }
 
 std::string
-Dictionary::translate(const std::string& msgid, const std::string& msgid2, int num) 
+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;
@@ -436,7 +441,7 @@ Dictionary::translate(const char* msgid)
 }
 
 std::string
-Dictionary::translate(const std::string& msgid) 
+Dictionary::translate(const std::string& msgid)
 {
   Entries::iterator i = entries.find(msgid);
   if (i != entries.end() && !i->second.empty())
@@ -451,7 +456,7 @@ Dictionary::translate(const std::string& msgid)
       return msgid;
     }
 }
-  
+
 void
 Dictionary::add_translation(const std::string& msgid, const std::string& ,
                             const std::map<int, std::string>& msgstrs)
@@ -461,8 +466,8 @@ Dictionary::add_translation(const std::string& msgid, const std::string& ,
   plural_entries[msgid] = msgstrs;
 }
 
-void 
-Dictionary::add_translation(const std::string& msgid, const std::string& msgstr) 
+void
+Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
 {
   entries[msgid] = msgstr;
 }
@@ -510,7 +515,7 @@ public:
     // 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)
       {
@@ -544,10 +549,10 @@ public:
 
   void add_token(const Token& token)
   {
-    switch(state) 
+    switch(state)
       {
       case WANT_MSGID:
-        if (token.keyword == "msgid") 
+        if (token.keyword == "msgid")
           {
             current_msgid = token.content;
             state = WANT_MSGID_PLURAL;
@@ -561,13 +566,13 @@ public:
             log_warning << "tinygettext: expected 'msgid' keyword, got " << token.keyword << " at line " << line_num << std::endl;
           }
         break;
-    
+
       case WANT_MSGID_PLURAL:
-        if (token.keyword == "msgid_plural") 
+        if (token.keyword == "msgid_plural")
           {
             current_msgid_plural = token.content;
             state = WANT_MSGSTR_PLURAL;
-          } 
+          }
         else
           {
             state = WANT_MSGSTR;
@@ -576,9 +581,9 @@ public:
         break;
 
       case WANT_MSGSTR:
-        if (token.keyword == "msgstr") 
+        if (token.keyword == "msgstr")
           {
-            if (current_msgid == "") 
+            if (current_msgid == "")
               { // .po Header is hidden in the msgid with the empty string
                 parse_header(token.content);
               }
@@ -587,7 +592,7 @@ public:
                 dict.add_translation(current_msgid, convert(token.content, from_charset, to_charset));
               }
             state = WANT_MSGID;
-          } 
+          }
         else
           {
             log_warning << "tinygettext: expected 'msgstr' keyword, got " << token.keyword << " at line " << line_num << std::endl;
@@ -595,19 +600,19 @@ public:
         break;
 
       case WANT_MSGSTR_PLURAL:
-        if (has_prefix(token.keyword, "msgstr[")) 
+        if (has_prefix(token.keyword, "msgstr["))
           {
             int num;
-            if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1) 
+            if (sscanf(token.keyword.c_str(), "msgstr[%d]", &num) != 1)
               {
                 log_warning << "Error: Couldn't parse: " << token.keyword << std::endl;
-              } 
-            else 
+              }
+            else
               {
                 msgstr_plural[num] = convert(token.content, from_charset, to_charset);
               }
           }
-        else 
+        else
           {
             dict.add_translation(current_msgid, current_msgid_plural, msgstr_plural);
 
@@ -617,18 +622,18 @@ public:
         break;
       }
   }
-  
-  inline int getchar(std::istream& in) 
+
+  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, 
+    enum State { READ_KEYWORD,
                  READ_CONTENT,
                  READ_CONTENT_IN_STRING,
                  SKIP_COMMENT };
@@ -651,8 +656,8 @@ public:
               {
                 // Read a new token
                 token = Token();
-                
-                do { // Read keyword 
+
+                do { // Read keyword
                   token.keyword += c;
                 } while((c = getchar(in)) != EOF && !isspace(c));
                 in.unget();
@@ -664,7 +669,7 @@ public:
           case READ_CONTENT:
             while((c = getchar(in)) != EOF)
               {
-                if (c == '"') { 
+                if (c == '"') {
                   // Found start of content
                   state = READ_CONTENT_IN_STRING;
                   break;
@@ -714,7 +719,7 @@ public:
   }
 };
 
-void read_po_file(Dictionary& dict_, std::istream& in) 
+void read_po_file(Dictionary& dict_, std::istream& in)
 {
   POFileReader reader(in, dict_);
 }