Skip to content

Commit 22a59b3

Browse files
sapiersapier
sapier
authored and
sapier
committedNov 11, 2013
Fix win32/msvc i18n (quite UGLY version, blame Microsoft)
1 parent 0f9440f commit 22a59b3

17 files changed

+313
-109
lines changed
 

‎src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ set(common_SRCS
306306
serverlist.cpp
307307
pathfinder.cpp
308308
convert_json.cpp
309+
gettext.cpp
309310
${JTHREAD_SRCS}
310311
${common_SCRIPT_SRCS}
311312
${UTIL_SRCS}

‎src/cguittfont/irrUString.h

+10-6
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ inline core::array<u8> getUnicodeBOM(EUTF_ENCODE mode)
205205
case EUTFE_UTF32_LE:
206206
COPY_ARRAY(BOM_ENCODE_UTF32_LE, BOM_ENCODE_UTF32_LEN);
207207
break;
208+
case EUTFE_NONE:
209+
// TODO sapier: fixed warning only,
210+
// don't know if something needs to be done here
211+
break;
208212
}
209213
return ret;
210214

@@ -257,7 +261,7 @@ class ustring16
257261
_set(c);
258262
return *this;
259263
}
260-
264+
261265
//! Increments the value by 1.
262266
//! \return Myself.
263267
_ustring16_iterator_access& operator++()
@@ -392,7 +396,7 @@ class ustring16
392396
return unicode::toUTF32(a[pos], a[pos + 1]);
393397
}
394398
}
395-
399+
396400
//! Sets a uchar32_t at our current position.
397401
void _set(uchar32_t c)
398402
{
@@ -707,7 +711,6 @@ class ustring16
707711
//! Moves the iterator to the end of the string.
708712
void toEnd()
709713
{
710-
const uchar16_t* a = ref->c_str();
711714
pos = ref->size_raw();
712715
}
713716

@@ -732,12 +735,13 @@ class ustring16
732735
typedef typename _Base::const_pointer const_pointer;
733736
typedef typename _Base::const_reference const_reference;
734737

738+
735739
typedef typename _Base::value_type value_type;
736740
typedef typename _Base::difference_type difference_type;
737741
typedef typename _Base::distance_type distance_type;
738742
typedef access pointer;
739743
typedef access reference;
740-
744+
741745
using _Base::pos;
742746
using _Base::ref;
743747

@@ -2096,7 +2100,7 @@ class ustring16
20962100
}
20972101
#endif
20982102

2099-
2103+
21002104
//! Appends a number to this ustring16.
21012105
//! \param c Number to append.
21022106
//! \return A reference to our current string.
@@ -2958,7 +2962,7 @@ class ustring16
29582962
if (endian != unicode::EUTFEE_NATIVE && getEndianness() != endian)
29592963
{
29602964
for (u32 i = 0; i <= used; ++i)
2961-
*ptr++ = unicode::swapEndian16(*ptr);
2965+
ptr[i] = unicode::swapEndian16(ptr[i]);
29622966
}
29632967
ret.set_used(used + (addBOM ? unicode::BOM_UTF16_LEN : 0));
29642968
ret.push_back(0);

‎src/gettext.cpp

+259
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
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+
27+
#if USE_GETTEXT and defined(_MSC_VER)
28+
#include <WinNls.h>
29+
#include <map>
30+
#include <direct.h>
31+
#include "filesys.h"
32+
33+
#define setlocale(category,localename) \
34+
setlocale(category,MSVC_LocaleLookup(localename))
35+
36+
static std::map<std::wstring,std::wstring> glb_supported_locales;
37+
38+
/******************************************************************************/
39+
BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
40+
{
41+
char* endptr = 0;
42+
int LOCALEID = strtol(pStr,&endptr,16);
43+
44+
wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
45+
memset(buffer,0,sizeof(buffer));
46+
if (GetLocaleInfoW(
47+
LOCALEID,
48+
LOCALE_SISO639LANGNAME,
49+
buffer,
50+
LOCALE_NAME_MAX_LENGTH)) {
51+
52+
std::wstring name = buffer;
53+
54+
memset(buffer,0,sizeof(buffer));
55+
GetLocaleInfoW(
56+
LOCALEID,
57+
LOCALE_SISO3166CTRYNAME,
58+
buffer,
59+
LOCALE_NAME_MAX_LENGTH);
60+
61+
std::wstring country = buffer;
62+
63+
memset(buffer,0,sizeof(buffer));
64+
GetLocaleInfoW(
65+
LOCALEID,
66+
LOCALE_SENGLISHLANGUAGENAME,
67+
buffer,
68+
LOCALE_NAME_MAX_LENGTH);
69+
70+
std::wstring languagename = buffer;
71+
72+
/* set both short and long variant */
73+
glb_supported_locales[name] = languagename;
74+
glb_supported_locales[name + L"_" + country] = languagename;
75+
}
76+
return true;
77+
}
78+
79+
/******************************************************************************/
80+
const char* MSVC_LocaleLookup(const char* raw_shortname) {
81+
82+
/* NULL is used to read locale only so we need to return it too */
83+
if (raw_shortname == NULL) return NULL;
84+
85+
std::string shortname(raw_shortname);
86+
if (shortname == "C") return "C";
87+
if (shortname == "") return "";
88+
89+
static std::string last_raw_value = "";
90+
static std::string last_full_name = "";
91+
static bool first_use = true;
92+
93+
if (last_raw_value == shortname) {
94+
return last_full_name.c_str();
95+
}
96+
97+
if (first_use) {
98+
EnumSystemLocalesA(UpdateLocaleCallback,LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
99+
first_use = false;
100+
}
101+
102+
last_raw_value = shortname;
103+
104+
if (glb_supported_locales.find(narrow_to_wide(shortname)) != glb_supported_locales.end()) {
105+
last_full_name = wide_to_narrow(glb_supported_locales[narrow_to_wide(shortname)]);
106+
return last_full_name.c_str();
107+
}
108+
109+
/* empty string is system default */
110+
errorstream << "MSVC_LocaleLookup: unsupported locale: \"" << shortname
111+
<< "\" switching to system default!" << std::endl;
112+
return "";
113+
}
114+
115+
#endif
116+
117+
/******************************************************************************/
118+
#ifdef _MSC_VER
119+
void init_gettext(const char *path,std::string configured_language,int argc, char** argv) {
120+
#else
121+
void init_gettext(const char *path,std::string configured_language) {
122+
#endif
123+
#if USE_GETTEXT
124+
/** first try to set user override environment **/
125+
if (configured_language.length() != 0) {
126+
#ifndef _WIN32
127+
/* add user specified locale to environment */
128+
setenv("LANGUAGE", configured_language.c_str(), 1);
129+
130+
/* reload locale with changed environment */
131+
setlocale(LC_ALL, "");
132+
#elif defined(_MSC_VER)
133+
std::string current_language_var("");
134+
if (getenv("LANGUAGE") != 0) {
135+
current_language_var = std::string(getenv("LANGUAGE"));
136+
}
137+
138+
char *lang_str = (char*)calloc(10 + configured_language.length(), sizeof(char));
139+
strcat(lang_str, "LANGUAGE=");
140+
strcat(lang_str, configured_language.c_str());
141+
putenv(lang_str);
142+
143+
SetEnvironmentVariableA("LANGUAGE",configured_language.c_str());
144+
145+
//very very dirty workaround to force gettext to see the right environment
146+
if (current_language_var != configured_language) {
147+
STARTUPINFO startupinfo;
148+
PROCESS_INFORMATION processinfo;
149+
memset(&startupinfo,0,sizeof(startupinfo));
150+
memset(&processinfo,0,sizeof(processinfo));
151+
errorstream << "MSVC localization workaround aktive restating minetest in new environment!" << std::endl;
152+
153+
std::string parameters = "";
154+
155+
for (unsigned int i=1;i < argc; i++) {
156+
if (parameters != "") {
157+
parameters += " ";
158+
}
159+
parameters += argv[i];
160+
}
161+
162+
const char* ptr_parameters = 0;
163+
164+
if (parameters != "") {
165+
ptr_parameters = parameters.c_str();
166+
}
167+
168+
/** users may start by short name in commandline without extention **/
169+
std::string appname = argv[0];
170+
if (appname.substr(appname.length() -4) != ".exe") {
171+
appname += ".exe";
172+
}
173+
174+
if (!CreateProcess(appname.c_str(),
175+
(char*) ptr_parameters,
176+
NULL,
177+
NULL,
178+
false,
179+
DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT,
180+
NULL,
181+
NULL,
182+
&startupinfo,
183+
&processinfo)) {
184+
char buffer[1024];
185+
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
186+
NULL,
187+
GetLastError(),
188+
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
189+
buffer,
190+
sizeof(buffer)-1,
191+
NULL);
192+
errorstream << "*******************************************************" << std::endl;
193+
errorstream << "CMD: " << appname << std::endl;
194+
errorstream << "Failed to restart with current locale: " << std::endl;
195+
errorstream << buffer;
196+
errorstream << "Expect language to be broken!" << std::endl;
197+
errorstream << "*******************************************************" << std::endl;
198+
}
199+
else {
200+
exit(0);
201+
}
202+
}
203+
204+
setlocale(LC_ALL,configured_language.c_str());
205+
#else // Mingw
206+
char *lang_str = (char*)calloc(10 + configured_language.length(), sizeof(char));
207+
strcat(lang_str, "LANGUAGE=");
208+
strcat(lang_str, configured_language.c_str());
209+
putenv(lang_str);
210+
211+
setlocale(LC_ALL, "");
212+
#endif // ifndef _WIN32
213+
}
214+
else {
215+
/* set current system default locale */
216+
setlocale(LC_ALL, "");
217+
}
218+
219+
#if defined(_WIN32)
220+
if (getenv("LANGUAGE") != 0) {
221+
setlocale(LC_ALL, getenv("LANGUAGE"));
222+
}
223+
#ifdef _MSC_VER
224+
else if (getenv("LANG") != 0) {
225+
setlocale(LC_ALL, getenv("LANG"));
226+
}
227+
#endif
228+
#endif
229+
230+
bindtextdomain(PROJECT_NAME, path);
231+
textdomain(PROJECT_NAME);
232+
233+
#if defined(_WIN32)
234+
// Set character encoding for Win32
235+
char *tdomain = textdomain( (char *) NULL );
236+
if( tdomain == NULL )
237+
{
238+
errorstream << "Warning: domainname parameter is the null pointer" <<
239+
", default domain is not set" << std::endl;
240+
tdomain = (char *) "messages";
241+
}
242+
/* char *codeset = */bind_textdomain_codeset( tdomain, "UTF-8" );
243+
//errorstream << "Gettext debug: domainname = " << tdomain << "; codeset = "<< codeset << std::endl;
244+
#endif // defined(_WIN32)
245+
246+
/* no matter what locale is used we need number format to be "C" */
247+
/* to ensure formspec parameters are evaluated correct! */
248+
249+
250+
setlocale(LC_NUMERIC,"C");
251+
infostream << "Message locale is now set to: "
252+
<< setlocale(LC_ALL,0) << std::endl;
253+
254+
#endif // if USE_GETTEXT
255+
}
256+
257+
258+
259+

0 commit comments

Comments
 (0)
Please sign in to comment.