Clean up gettext initialization
This commit is contained in:
		
							parent
							
								
									93c2aff2cf
								
							
						
					
					
						commit
						b8dc349099
					
				
							
								
								
									
										155
									
								
								src/gettext.cpp
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								src/gettext.cpp
									
									
									
									
									
								
							| @ -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,6 +119,54 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) { | |||||||
| 	return ""; | 	return ""; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void MSVC_LocaleWorkaround() | ||||||
|  | { | ||||||
|  | 	errorstream << "MSVC localization workaround active.  " | ||||||
|  | 		"Restarting " PROJECT_NAME_C " in a new environment!" << std::endl; | ||||||
|  | 
 | ||||||
|  | 	std::string parameters; | ||||||
|  | 	for (int i = 1; i < argc; i++) { | ||||||
|  | 		if (i > 1) | ||||||
|  | 			parameters += ' '; | ||||||
|  | 		parameters += porting::QuoteArgv(argv[i]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	char *ptr_parameters = nullptr; | ||||||
|  | 	if (!parameters.empty()) | ||||||
|  | 		ptr_parameters = ¶meters[0]; | ||||||
|  | 
 | ||||||
|  | 	// Allow calling without an extension
 | ||||||
|  | 	std::string app_name = argv[0]; | ||||||
|  | 	if (app_name.compare(app_name.size() - 4, 4, ".exe") != 0) | ||||||
|  | 		app_name += ".exe"; | ||||||
|  | 
 | ||||||
|  | 	STARTUPINFO startup_info = {}; | ||||||
|  | 	PROCESS_INFORMATION process_info = {}; | ||||||
|  | 
 | ||||||
|  | 	bool success = CreateProcess(app_name.c_str(), ptr_parameters, | ||||||
|  | 		NULL, NULL, false, DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT, | ||||||
|  | 		NULL, NULL, &startup_info, &process_info); | ||||||
|  | 
 | ||||||
|  | 	if (success) { | ||||||
|  | 		exit(0); | ||||||
|  | 		// NOTREACHED
 | ||||||
|  | 	} else { | ||||||
|  | 		char buffer[1024]; | ||||||
|  | 
 | ||||||
|  | 		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | ||||||
|  | 			MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), buffer, | ||||||
|  | 			sizeof(buffer) - 1, NULL); | ||||||
|  | 
 | ||||||
|  | 		errorstream << "*******************************************************" << std::endl; | ||||||
|  | 		errorstream << "CMD: " << app_name << std::endl; | ||||||
|  | 		errorstream << "Failed to restart with current locale: " << std::endl; | ||||||
|  | 		errorstream << buffer; | ||||||
|  | 		errorstream << "Expect language to be broken!" << std::endl; | ||||||
|  | 		errorstream << "*******************************************************" << std::endl; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /******************************************************************************/ | /******************************************************************************/ | ||||||
| @ -123,72 +176,26 @@ void init_gettext(const char *path, const std::string &configured_language, | |||||||
| #if USE_GETTEXT | #if USE_GETTEXT | ||||||
| 	// First, try to set user override environment
 | 	// First, try to set user override environment
 | ||||||
| 	if (!configured_language.empty()) { | 	if (!configured_language.empty()) { | ||||||
| #ifndef _WIN32 | 		// Set LANGUAGE which overrides all others, see
 | ||||||
| 		// Add user specified locale to environment
 | 		// <https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html>
 | ||||||
|  | #ifndef _MSC_VER | ||||||
| 		setenv("LANGUAGE", configured_language.c_str(), 1); | 		setenv("LANGUAGE", configured_language.c_str(), 1); | ||||||
| 
 | 
 | ||||||
| #ifdef __ANDROID__ |  | ||||||
| 		setenv("LANG", configured_language.c_str(), 1); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 		// Reload locale with changed environment
 | 		// Reload locale with changed environment
 | ||||||
| 		setlocale(LC_ALL, ""); | 		setlocale(LC_ALL, ""); | ||||||
| #elif defined(_MSC_VER) | #else | ||||||
| 		std::string current_language; | 		std::string current_language; | ||||||
| 		const char *env_lang = getenv("LANGUAGE"); | 		const char *env_lang = getenv("LANGUAGE"); | ||||||
| 		if (env_lang) | 		if (env_lang) | ||||||
| 			current_language = env_lang; | 			current_language = env_lang; | ||||||
| 
 | 
 | ||||||
| 		_putenv(("LANGUAGE=" + configured_language).c_str()); | 		setenv("LANGUAGE", configured_language.c_str(), 1); | ||||||
| 		SetEnvironmentVariableA("LANGUAGE", configured_language.c_str()); | 		SetEnvironmentVariableA("LANGUAGE", configured_language.c_str()); | ||||||
| 
 | 
 | ||||||
| #ifndef SERVER | #ifndef SERVER | ||||||
| 		// Hack to force gettext to see the right environment
 | 		// Hack to force gettext to see the right environment
 | ||||||
| 		if (current_language != configured_language) { | 		if (current_language != configured_language) | ||||||
| 			errorstream << "MSVC localization workaround active.  " | 			MSVC_LocaleWorkaround(); | ||||||
| 				"Restarting " PROJECT_NAME_C " in a new environment!" << std::endl; |  | ||||||
| 
 |  | ||||||
| 			std::string parameters; |  | ||||||
| 			for (int i = 1; i < argc; i++) { |  | ||||||
| 				if (i > 1) |  | ||||||
| 					parameters += ' '; |  | ||||||
| 				parameters += porting::QuoteArgv(argv[i]); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			char *ptr_parameters = nullptr; |  | ||||||
| 			if (!parameters.empty()) |  | ||||||
| 				ptr_parameters = ¶meters[0]; |  | ||||||
| 
 |  | ||||||
| 			// Allow calling without an extension
 |  | ||||||
| 			std::string app_name = argv[0]; |  | ||||||
| 			if (app_name.compare(app_name.size() - 4, 4, ".exe") != 0) |  | ||||||
| 				app_name += ".exe"; |  | ||||||
| 
 |  | ||||||
| 			STARTUPINFO startup_info = {}; |  | ||||||
| 			PROCESS_INFORMATION process_info = {}; |  | ||||||
| 
 |  | ||||||
| 			bool success = CreateProcess(app_name.c_str(), ptr_parameters, |  | ||||||
| 				NULL, NULL, false, DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT, |  | ||||||
| 				NULL, NULL, &startup_info, &process_info); |  | ||||||
| 
 |  | ||||||
| 			if (success) { |  | ||||||
| 				exit(0); |  | ||||||
| 				// NOTREACHED
 |  | ||||||
| 			} else { |  | ||||||
| 				char buffer[1024]; |  | ||||||
| 
 |  | ||||||
| 				FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), |  | ||||||
| 					MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), buffer, |  | ||||||
| 					sizeof(buffer) - 1, NULL); |  | ||||||
| 
 |  | ||||||
| 				errorstream << "*******************************************************" << std::endl; |  | ||||||
| 				errorstream << "CMD: " << app_name << std::endl; |  | ||||||
| 				errorstream << "Failed to restart with current locale: " << std::endl; |  | ||||||
| 				errorstream << buffer; |  | ||||||
| 				errorstream << "Expect language to be broken!" << std::endl; |  | ||||||
| 				errorstream << "*******************************************************" << std::endl; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| #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(); |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user