Clean up gettext initialization

This commit is contained in:
sfan5 2023-12-19 22:01:28 +01:00
parent 93c2aff2cf
commit b8dc349099
3 changed files with 83 additions and 82 deletions

@ -25,6 +25,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/string.h" #include "util/string.h"
#include "log.h" #include "log.h"
#ifdef _WIN32
#define setenv(n,v,o) _putenv_s(n,v)
#endif
#if USE_GETTEXT && defined(_MSC_VER) #if USE_GETTEXT && defined(_MSC_VER)
#include <windows.h> #include <windows.h>
#include <map> #include <map>
@ -37,7 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
static std::map<std::wstring, std::wstring> glb_supported_locales; static std::map<std::wstring, std::wstring> glb_supported_locales;
/******************************************************************************/ /******************************************************************************/
BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr) static BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
{ {
char* endptr = 0; char* endptr = 0;
int LOCALEID = strtol(pStr, &endptr,16); int LOCALEID = strtol(pStr, &endptr,16);
@ -78,7 +82,8 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
} }
/******************************************************************************/ /******************************************************************************/
const char* MSVC_LocaleLookup(const char* raw_shortname) { static const char* MSVC_LocaleLookup(const char* raw_shortname)
{
/* NULL is used to read locale only so we need to return it too */ /* NULL is used to read locale only so we need to return it too */
if (raw_shortname == NULL) return NULL; if (raw_shortname == NULL) return NULL;
@ -102,9 +107,9 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) {
last_raw_value = shortname; last_raw_value = shortname;
if (glb_supported_locales.find(utf8_to_wide(shortname)) != glb_supported_locales.end()) { auto key = utf8_to_wide(shortname);
last_full_name = wide_to_utf8( if (glb_supported_locales.find(key) != glb_supported_locales.end()) {
glb_supported_locales[utf8_to_wide(shortname)]); last_full_name = wide_to_utf8(glb_supported_locales[key]);
return last_full_name.c_str(); return last_full_name.c_str();
} }
@ -114,37 +119,8 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) {
return ""; return "";
} }
#endif static void MSVC_LocaleWorkaround()
/******************************************************************************/
void init_gettext(const char *path, const std::string &configured_language,
int argc, char *argv[])
{ {
#if USE_GETTEXT
// First, try to set user override environment
if (!configured_language.empty()) {
#ifndef _WIN32
// Add user specified locale to environment
setenv("LANGUAGE", configured_language.c_str(), 1);
#ifdef __ANDROID__
setenv("LANG", configured_language.c_str(), 1);
#endif
// Reload locale with changed environment
setlocale(LC_ALL, "");
#elif defined(_MSC_VER)
std::string current_language;
const char *env_lang = getenv("LANGUAGE");
if (env_lang)
current_language = env_lang;
_putenv(("LANGUAGE=" + configured_language).c_str());
SetEnvironmentVariableA("LANGUAGE", configured_language.c_str());
#ifndef SERVER
// Hack to force gettext to see the right environment
if (current_language != configured_language) {
errorstream << "MSVC localization workaround active. " errorstream << "MSVC localization workaround active. "
"Restarting " PROJECT_NAME_C " in a new environment!" << std::endl; "Restarting " PROJECT_NAME_C " in a new environment!" << std::endl;
@ -188,7 +164,38 @@ void init_gettext(const char *path, const std::string &configured_language,
errorstream << "Expect language to be broken!" << std::endl; errorstream << "Expect language to be broken!" << std::endl;
errorstream << "*******************************************************" << std::endl; errorstream << "*******************************************************" << std::endl;
} }
} }
}
#endif
/******************************************************************************/
void init_gettext(const char *path, const std::string &configured_language,
int argc, char *argv[])
{
#if USE_GETTEXT
// First, try to set user override environment
if (!configured_language.empty()) {
// Set LANGUAGE which overrides all others, see
// <https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html>
#ifndef _MSC_VER
setenv("LANGUAGE", configured_language.c_str(), 1);
// Reload locale with changed environment
setlocale(LC_ALL, "");
#else
std::string current_language;
const char *env_lang = getenv("LANGUAGE");
if (env_lang)
current_language = env_lang;
setenv("LANGUAGE", configured_language.c_str(), 1);
SetEnvironmentVariableA("LANGUAGE", configured_language.c_str());
#ifndef SERVER
// Hack to force gettext to see the right environment
if (current_language != configured_language)
MSVC_LocaleWorkaround();
#else #else
errorstream << "*******************************************************" << std::endl; errorstream << "*******************************************************" << std::endl;
errorstream << "Can't apply locale workaround for server!" << std::endl; errorstream << "Can't apply locale workaround for server!" << std::endl;
@ -197,15 +204,8 @@ void init_gettext(const char *path, const std::string &configured_language,
#endif #endif
setlocale(LC_ALL, configured_language.c_str()); setlocale(LC_ALL, configured_language.c_str());
#else // Mingw #endif // ifdef _MSC_VER
_putenv(("LANGUAGE=" + configured_language).c_str()); } else {
setlocale(LC_ALL, "");
#endif // ifndef _WIN32
}
else {
#ifdef __ANDROID__
setenv("LANG", porting::getLanguageAndroid().c_str(), 1);
#endif
/* set current system default locale */ /* set current system default locale */
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
} }
@ -228,18 +228,13 @@ void init_gettext(const char *path, const std::string &configured_language,
bindtextdomain(name.c_str(), path); bindtextdomain(name.c_str(), path);
textdomain(name.c_str()); textdomain(name.c_str());
#if defined(_WIN32) #ifdef _WIN32
// Set character encoding for Win32 // set character encoding
char *tdomain = textdomain( (char *) NULL ); char *tdomain = textdomain(nullptr);
if( tdomain == NULL ) assert(tdomain);
{ if (tdomain)
errorstream << "Warning: domainname parameter is the null pointer" << bind_textdomain_codeset(tdomain, "UTF-8");
", default domain is not set" << std::endl; #endif
tdomain = (char *) "messages";
}
/* char *codeset = */bind_textdomain_codeset( tdomain, "UTF-8" );
//errorstream << "Gettext debug: domainname = " << tdomain << "; codeset = "<< codeset << std::endl;
#endif // defined(_WIN32)
#else #else
/* set current system default locale */ /* set current system default locale */
@ -247,7 +242,7 @@ void init_gettext(const char *path, const std::string &configured_language,
#endif // if USE_GETTEXT #endif // if USE_GETTEXT
/* no matter what locale is used we need number format to be "C" */ /* no matter what locale is used we need number format to be "C" */
/* to ensure formspec parameters are evaluated correct! */ /* to ensure formspec parameters are evaluated correctly! */
setlocale(LC_NUMERIC, "C"); setlocale(LC_NUMERIC, "C");
infostream << "Message locale is now set to: " infostream << "Message locale is now set to: "

@ -40,7 +40,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
extern int main(int argc, char *argv[]); extern int main(int argc, char *argv[]);
namespace porting { namespace porting {
void cleanupAndroid(); // used here // used here:
void cleanupAndroid();
std::string getLanguageAndroid();
bool setSystemPaths(); // used in porting.cpp bool setSystemPaths(); // used in porting.cpp
} }
@ -101,6 +103,11 @@ void osSpecificInit()
"porting::initAndroid unable to find Java native activity class" << "porting::initAndroid unable to find Java native activity class" <<
std::endl; std::endl;
// Set default language
auto lang = getLanguageAndroid();
unsetenv("LANGUAGE");
setenv("LANG", lang.c_str(), 1);
#ifdef GPROF #ifdef GPROF
// in the start-up code // in the start-up code
warningstream << "Initializing GPROF profiler" << std::endl; warningstream << "Initializing GPROF profiler" << std::endl;

@ -71,5 +71,4 @@ float getDisplayDensity();
v2u32 getDisplaySize(); v2u32 getDisplaySize();
#endif #endif
std::string getLanguageAndroid();
} }