LCOV - code coverage report
Current view: top level - src - gettext.cpp (source / functions) Hit Total Coverage
Test: report Lines: 6 6 100.0 %
Date: 2015-07-11 18:23:49 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include <string>
      21             : #include <string.h>
      22             : #include <iostream>
      23             : #include <stdlib.h>
      24             : #include "gettext.h"
      25             : #include "util/string.h"
      26             : #include "log.h"
      27             : 
      28             : #if USE_GETTEXT && defined(_MSC_VER)
      29             : #include <windows.h>
      30             : #include <map>
      31             : #include <direct.h>
      32             : #include "filesys.h"
      33             : 
      34             : #define setlocale(category, localename) \
      35             :         setlocale(category, MSVC_LocaleLookup(localename))
      36             : 
      37             : static std::map<std::wstring, std::wstring> glb_supported_locales;
      38             : 
      39             : /******************************************************************************/
      40             : BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
      41             : {
      42             :         char* endptr = 0;
      43             :         int LOCALEID = strtol(pStr, &endptr,16);
      44             : 
      45             :         wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
      46             :         memset(buffer, 0, sizeof(buffer));
      47             :         if (GetLocaleInfoW(
      48             :                 LOCALEID,
      49             :                 LOCALE_SISO639LANGNAME,
      50             :                 buffer,
      51             :                 LOCALE_NAME_MAX_LENGTH)) {
      52             : 
      53             :                 std::wstring name = buffer;
      54             : 
      55             :                 memset(buffer, 0, sizeof(buffer));
      56             :                 GetLocaleInfoW(
      57             :                 LOCALEID,
      58             :                 LOCALE_SISO3166CTRYNAME,
      59             :                 buffer,
      60             :                 LOCALE_NAME_MAX_LENGTH);
      61             : 
      62             :                 std::wstring country = buffer;
      63             : 
      64             :                 memset(buffer, 0, sizeof(buffer));
      65             :                 GetLocaleInfoW(
      66             :                 LOCALEID,
      67             :                 LOCALE_SENGLISHLANGUAGENAME,
      68             :                 buffer,
      69             :                 LOCALE_NAME_MAX_LENGTH);
      70             : 
      71             :                 std::wstring languagename = buffer;
      72             : 
      73             :                 /* set both short and long variant */
      74             :                 glb_supported_locales[name] = languagename;
      75             :                 glb_supported_locales[name + L"_" + country] = languagename;
      76             :         }
      77             :         return true;
      78             : }
      79             : 
      80             : /******************************************************************************/
      81             : const char* MSVC_LocaleLookup(const char* raw_shortname) {
      82             : 
      83             :         /* NULL is used to read locale only so we need to return it too */
      84             :         if (raw_shortname == NULL) return NULL;
      85             : 
      86             :         std::string shortname(raw_shortname);
      87             :         if (shortname == "C") return "C";
      88             :         if (shortname == "") return "";
      89             : 
      90             :         static std::string last_raw_value = "";
      91             :         static std::string last_full_name = "";
      92             :         static bool first_use = true;
      93             : 
      94             :         if (last_raw_value == shortname) {
      95             :                 return last_full_name.c_str();
      96             :         }
      97             : 
      98             :         if (first_use) {
      99             :                 EnumSystemLocalesA(UpdateLocaleCallback, LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
     100             :                 first_use = false;
     101             :         }
     102             : 
     103             :         last_raw_value = shortname;
     104             : 
     105             :         if (glb_supported_locales.find(narrow_to_wide(shortname)) != glb_supported_locales.end()) {
     106             :                 last_full_name = wide_to_narrow(glb_supported_locales[narrow_to_wide(shortname)]);
     107             :                 return last_full_name.c_str();
     108             :         }
     109             : 
     110             :         /* empty string is system default */
     111             :         errorstream << "MSVC_LocaleLookup: unsupported locale: \"" << shortname
     112             :                                 << "\" switching to system default!" << std::endl;
     113             :         return "";
     114             : }
     115             : 
     116             : #endif
     117             : 
     118             : /******************************************************************************/
     119             : #ifdef _MSC_VER
     120             : void init_gettext(const char *path, const std::string &configured_language, int argc, char** argv) {
     121             : #else
     122           1 : void init_gettext(const char *path, const std::string &configured_language) {
     123             : #endif
     124             : #if USE_GETTEXT
     125             :         /** first try to set user override environment **/
     126             :         if (configured_language.length() != 0) {
     127             : #ifndef _WIN32
     128             :                 /* add user specified locale to environment */
     129             :                 setenv("LANGUAGE", configured_language.c_str(), 1);
     130             : 
     131             :                 /* reload locale with changed environment */
     132             :                 setlocale(LC_ALL, "");
     133             : #elif defined(_MSC_VER)
     134             :                 std::string current_language_var("");
     135             :                 if (getenv("LANGUAGE") != 0) {
     136             :                         current_language_var = std::string(getenv("LANGUAGE"));
     137             :                 }
     138             : 
     139             :                 char *lang_str = (char*)calloc(10 + configured_language.length(), sizeof(char));
     140             :                 strcat(lang_str, "LANGUAGE=");
     141             :                 strcat(lang_str, configured_language.c_str());
     142             :                 putenv(lang_str);
     143             : 
     144             :                 SetEnvironmentVariableA("LANGUAGE",configured_language.c_str());
     145             : 
     146             : #ifndef SERVER
     147             :                 //very very dirty workaround to force gettext to see the right environment
     148             :                 if (current_language_var != configured_language) {
     149             :                         STARTUPINFO startupinfo;
     150             :                         PROCESS_INFORMATION processinfo;
     151             :                         memset(&startupinfo, 0, sizeof(startupinfo));
     152             :                         memset(&processinfo, 0, sizeof(processinfo));
     153             :                         errorstream << "MSVC localization workaround active restating minetest in new environment!" << std::endl;
     154             : 
     155             :                         std::string parameters = "";
     156             : 
     157             :                         for (unsigned int i=1;i < argc; i++) {
     158             :                                 if (parameters != "") {
     159             :                                         parameters += " ";
     160             :                                 }
     161             :                                 parameters += argv[i];
     162             :                         }
     163             : 
     164             :                         const char* ptr_parameters = 0;
     165             : 
     166             :                         if (parameters != "") {
     167             :                                 ptr_parameters = parameters.c_str();
     168             :                         }
     169             :                         
     170             :                         /** users may start by short name in commandline without extention **/
     171             :                         std::string appname = argv[0];
     172             :                         if (appname.substr(appname.length() - 4) != ".exe") {
     173             :                                 appname += ".exe";
     174             :                         }
     175             : 
     176             :                         if (!CreateProcess(appname.c_str(),
     177             :                                         (char*) ptr_parameters,
     178             :                                         NULL,
     179             :                                         NULL,
     180             :                                         false,
     181             :                                         DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT,
     182             :                                         NULL,
     183             :                                         NULL,
     184             :                                         &startupinfo,
     185             :                                         &processinfo)) {
     186             :                                 char buffer[1024];              
     187             :                                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
     188             :                                         NULL,
     189             :                                         GetLastError(),
     190             :                                         MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
     191             :                                         buffer,
     192             :                                         sizeof(buffer)-1,
     193             :                                         NULL);
     194             :                                 errorstream << "*******************************************************" << std::endl;
     195             :                                 errorstream << "CMD: " << appname << std::endl;
     196             :                                 errorstream << "Failed to restart with current locale: " << std::endl;
     197             :                                 errorstream << buffer;
     198             :                                 errorstream << "Expect language to be broken!" << std::endl;
     199             :                                 errorstream << "*******************************************************" << std::endl;
     200             :                         }
     201             :                         else {
     202             :                                 exit(0);
     203             :                         }
     204             : #else
     205             :                         errorstream << "*******************************************************" << std::endl;
     206             :                         errorstream << "Can't apply locale workaround for server!" << std::endl;
     207             :                         errorstream << "Expect language to be broken!" << std::endl;
     208             :                         errorstream << "*******************************************************" << std::endl;
     209             : 
     210             : #endif
     211             :                 }
     212             : 
     213             :                 setlocale(LC_ALL,configured_language.c_str());
     214             : #else // Mingw
     215             :                 char *lang_str = (char*)calloc(10 + configured_language.length(), sizeof(char));
     216             :                 strcat(lang_str, "LANGUAGE=");
     217             :                 strcat(lang_str, configured_language.c_str());
     218             :                 putenv(lang_str);
     219             : 
     220             :                 setlocale(LC_ALL, "");
     221             : #endif // ifndef _WIN32
     222             :         }
     223             :         else {
     224             :                  /* set current system default locale */
     225             :                 setlocale(LC_ALL, "");
     226             :         }
     227             : 
     228             : #if defined(_WIN32)
     229             :         if (getenv("LANGUAGE") != 0) {
     230             :                 setlocale(LC_ALL, getenv("LANGUAGE"));
     231             :         }
     232             : #ifdef _MSC_VER
     233             :         else if (getenv("LANG") != 0) {
     234             :                 setlocale(LC_ALL, getenv("LANG"));
     235             :         }
     236             : #endif
     237             : #endif
     238             : 
     239             :         static std::string name = lowercase(PROJECT_NAME);
     240             :         bindtextdomain(name.c_str(), path);
     241             :         textdomain(name.c_str());
     242             : 
     243             : #if defined(_WIN32)
     244             :         // Set character encoding for Win32
     245             :         char *tdomain = textdomain( (char *) NULL );
     246             :         if( tdomain == NULL )
     247             :         {
     248             :                 errorstream << "Warning: domainname parameter is the null pointer" <<
     249             :                                 ", default domain is not set" << std::endl;
     250             :                 tdomain = (char *) "messages";
     251             :         }
     252             :         /* char *codeset = */bind_textdomain_codeset( tdomain, "UTF-8" );
     253             :         //errorstream << "Gettext debug: domainname = " << tdomain << "; codeset = "<< codeset << std::endl;
     254             : #endif // defined(_WIN32)
     255             : 
     256             : #else
     257             :         /* set current system default locale */
     258           1 :         setlocale(LC_ALL, "");
     259             : #endif // if USE_GETTEXT
     260             : 
     261             :         /* no matter what locale is used we need number format to be "C" */
     262             :         /* to ensure formspec parameters are evaluated correct!          */
     263             : 
     264           1 :         setlocale(LC_NUMERIC, "C");
     265           1 :         infostream << "Message locale is now set to: "
     266           2 :                         << setlocale(LC_ALL, 0) << std::endl;
     267           4 : }
     268             : 

Generated by: LCOV version 1.11