Fix gettext on MSVC

This commit is contained in:
BlockMen 2015-02-12 02:55:50 +01:00 committed by Craig Robbins
parent 15c037614f
commit e62927ed71
3 changed files with 31 additions and 25 deletions

@ -26,24 +26,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#if USE_GETTEXT && defined(_MSC_VER) #if USE_GETTEXT && defined(_MSC_VER)
#include <WinNls.h> #include <windows.h>
#include <map> #include <map>
#include <direct.h> #include <direct.h>
#include "filesys.h" #include "filesys.h"
#define setlocale(category,localename) \ #define setlocale(category, localename) \
setlocale(category,MSVC_LocaleLookup(localename)) setlocale(category, MSVC_LocaleLookup(localename))
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) BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
{ {
char* endptr = 0; char* endptr = 0;
int LOCALEID = strtol(pStr,&endptr,16); int LOCALEID = strtol(pStr, &endptr,16);
wchar_t buffer[LOCALE_NAME_MAX_LENGTH]; wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
memset(buffer,0,sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
if (GetLocaleInfoW( if (GetLocaleInfoW(
LOCALEID, LOCALEID,
LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME,
@ -52,7 +52,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
std::wstring name = buffer; std::wstring name = buffer;
memset(buffer,0,sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
GetLocaleInfoW( GetLocaleInfoW(
LOCALEID, LOCALEID,
LOCALE_SISO3166CTRYNAME, LOCALE_SISO3166CTRYNAME,
@ -61,7 +61,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
std::wstring country = buffer; std::wstring country = buffer;
memset(buffer,0,sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
GetLocaleInfoW( GetLocaleInfoW(
LOCALEID, LOCALEID,
LOCALE_SENGLISHLANGUAGENAME, LOCALE_SENGLISHLANGUAGENAME,
@ -96,7 +96,7 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) {
} }
if (first_use) { if (first_use) {
EnumSystemLocalesA(UpdateLocaleCallback,LCID_SUPPORTED | LCID_ALTERNATE_SORTS); EnumSystemLocalesA(UpdateLocaleCallback, LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
first_use = false; first_use = false;
} }
@ -148,8 +148,8 @@ void init_gettext(const char *path, const std::string &configured_language) {
if (current_language_var != configured_language) { if (current_language_var != configured_language) {
STARTUPINFO startupinfo; STARTUPINFO startupinfo;
PROCESS_INFORMATION processinfo; PROCESS_INFORMATION processinfo;
memset(&startupinfo,0,sizeof(startupinfo)); memset(&startupinfo, 0, sizeof(startupinfo));
memset(&processinfo,0,sizeof(processinfo)); memset(&processinfo, 0, sizeof(processinfo));
errorstream << "MSVC localization workaround active restating minetest in new environment!" << std::endl; errorstream << "MSVC localization workaround active restating minetest in new environment!" << std::endl;
std::string parameters = ""; std::string parameters = "";
@ -169,7 +169,7 @@ void init_gettext(const char *path, const std::string &configured_language) {
/** users may start by short name in commandline without extention **/ /** users may start by short name in commandline without extention **/
std::string appname = argv[0]; std::string appname = argv[0];
if (appname.substr(appname.length() -4) != ".exe") { if (appname.substr(appname.length() - 4) != ".exe") {
appname += ".exe"; appname += ".exe";
} }
@ -260,7 +260,7 @@ void init_gettext(const char *path, const std::string &configured_language) {
/* 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 correct! */
setlocale(LC_NUMERIC,"C"); setlocale(LC_NUMERIC, "C");
infostream << "Message locale is now set to: " infostream << "Message locale is now set to: "
<< setlocale(LC_ALL, 0) << std::endl; << setlocale(LC_ALL, 0) << std::endl;
} }

@ -41,16 +41,19 @@ void init_gettext(const char *path, const std::string &configured_language);
extern const wchar_t *narrow_to_wide_c(const char *mbs); extern const wchar_t *narrow_to_wide_c(const char *mbs);
extern std::wstring narrow_to_wide(const std::string &mbs); extern std::wstring narrow_to_wide(const std::string &mbs);
// You must free the returned string! // You must free the returned string!
inline const wchar_t *wgettext(const char *str) inline const wchar_t *wgettext(const char *str)
{ {
return narrow_to_wide_c(gettext(str)); return narrow_to_wide_c(gettext(str));
} }
// Gettext under MSVC needs this strange way. Just don't ask...
inline std::wstring wstrgettext(const std::string &text) inline std::wstring wstrgettext(const std::string &text)
{ {
return narrow_to_wide(gettext(text.c_str())); const wchar_t *tmp = wgettext(text.c_str());
std::wstring retval = (std::wstring)tmp;
delete[] tmp;
return retval;
} }
inline std::string strgettext(const std::string &text) inline std::string strgettext(const std::string &text)

@ -98,11 +98,13 @@ const wchar_t *narrow_to_wide_c(const char *mbs)
{ {
wchar_t *wcs = NULL; wchar_t *wcs = NULL;
#if defined(_WIN32) #if defined(_WIN32)
int wcl = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, NULL, 0); int nResult = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, 0, 0);
if (!wcl) if (nResult == 0) {
return NULL; errorstream << "gettext: MultiByteToWideChar returned null" << std::endl;
wcs = new wchar_t[wcl]; } else {
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, (WCHAR *) wcs, wcl); wcs = new wchar_t[nResult];
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, (WCHAR *) wcs, nResult);
}
#else #else
size_t wcl = mbstowcs(NULL, mbs, 0); size_t wcl = mbstowcs(NULL, mbs, 0);
if (wcl == (size_t) -1) if (wcl == (size_t) -1)
@ -120,12 +122,13 @@ const wchar_t *narrow_to_wide_c(const char *mbs)
std::wstring narrow_to_wide(const std::string& mbs) std::wstring narrow_to_wide(const std::string& mbs)
{ {
const wchar_t *wcs = narrow_to_wide_c(mbs.c_str()); size_t wcl = mbs.size();
if (!wcs) Buffer<wchar_t> wcs(wcl + 1);
size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
if (l == (size_t)(-1))
return L"<invalid multibyte string>"; return L"<invalid multibyte string>";
std::wstring wstr(wcs); wcs[l] = 0;
delete [] wcs; return *wcs;
return wstr;
} }
#ifdef __ANDROID__ #ifdef __ANDROID__