added code for checking if the current locale is UTF-8 at runtime
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45609 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -190,6 +190,14 @@
|
|||||||
/* depending on the platform, Unicode build can either store wxStrings as
|
/* depending on the platform, Unicode build can either store wxStrings as
|
||||||
wchar_t* or UTF-8 encoded char*: */
|
wchar_t* or UTF-8 encoded char*: */
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
|
// FIXME-UTF8: what would be better place for this?
|
||||||
|
#if defined(wxUSE_UTF8_LOCALE_ONLY) && !defined(wxUSE_UNICODE_UTF8)
|
||||||
|
#error "wxUSE_UTF8_LOCALE_ONLY only makes sense with wxUSE_UNICODE_UTF8"
|
||||||
|
#endif
|
||||||
|
#ifndef wxUSE_UTF8_LOCALE_ONLY
|
||||||
|
#define wxUSE_UTF8_LOCALE_ONLY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef wxUSE_UNICODE_UTF8
|
#ifndef wxUSE_UNICODE_UTF8
|
||||||
#define wxUSE_UNICODE_UTF8 0
|
#define wxUSE_UNICODE_UTF8 0
|
||||||
#endif
|
#endif
|
||||||
|
@@ -19,6 +19,20 @@
|
|||||||
|
|
||||||
#include <stdio.h> /* we use FILE below */
|
#include <stdio.h> /* we use FILE below */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#if wxUSE_UNICODE_UTF8
|
||||||
|
// flag indicating whether the current locale uses UTF-8 or not; must be
|
||||||
|
// updated every time the locale is changed!
|
||||||
|
#if !wxUSE_UTF8_LOCALE_ONLY
|
||||||
|
extern WXDLLIMPEXP_BASE bool wxLocaleIsUtf8;
|
||||||
|
#endif
|
||||||
|
// function used to update the flag:
|
||||||
|
extern WXDLLIMPEXP_BASE void wxUpdateLocaleIsUtf8();
|
||||||
|
#else // !wxUSE_UNICODE_UTF8
|
||||||
|
inline WXDLLIMPEXP_BASE void wxUpdateLocaleIsUtf8() {}
|
||||||
|
#endif // wxUSE_UNICODE_UTF8/!wxUSE_UNICODE_UTF8
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#if defined(HAVE_STRTOK_R) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
|
#if defined(HAVE_STRTOK_R) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
|
||||||
char *strtok_r(char *, const char *, char **);
|
char *strtok_r(char *, const char *, char **);
|
||||||
#endif
|
#endif
|
||||||
@@ -99,7 +113,7 @@
|
|||||||
#define wxToupper(c) _totupper((wxUChar)(wxChar)(c))
|
#define wxToupper(c) _totupper((wxUChar)(wxChar)(c))
|
||||||
|
|
||||||
/* locale.h functons */
|
/* locale.h functons */
|
||||||
#define wxSetlocale _tsetlocale
|
#define wxSetlocale_ _tsetlocale
|
||||||
|
|
||||||
/* string.h functions */
|
/* string.h functions */
|
||||||
#define wxStrcat _tcscat
|
#define wxStrcat _tcscat
|
||||||
@@ -476,7 +490,7 @@
|
|||||||
#define wxToupper toupper
|
#define wxToupper toupper
|
||||||
|
|
||||||
/* locale.h functons */
|
/* locale.h functons */
|
||||||
#define wxSetlocale setlocale
|
#define wxSetlocale_ setlocale
|
||||||
|
|
||||||
/* string.h functions */
|
/* string.h functions */
|
||||||
#define wxStrcat strcat
|
#define wxStrcat strcat
|
||||||
@@ -772,11 +786,14 @@ WXDLLIMPEXP_BASE wxChar * wxStrtok(wxChar *psz, const wxChar *delim, wxChar **sa
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#ifndef wxSetlocale
|
#ifndef wxSetlocale_
|
||||||
class WXDLLIMPEXP_BASE wxWCharBuffer;
|
class WXDLLIMPEXP_BASE wxWCharBuffer;
|
||||||
WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale(int category, const wxChar *locale);
|
WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale_(int category, const wxChar *locale);
|
||||||
#endif
|
WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale(int category, const wxChar *locale);
|
||||||
#endif
|
#else
|
||||||
|
WXDLLIMPEXP_BASE const wxChar *wxSetlocale(int category, const wxChar *locale);
|
||||||
|
#endif // defined(wxSetlocale_)
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
/* stdio.h functions */
|
/* stdio.h functions */
|
||||||
#ifdef wxNEED_WX_STDIO_H
|
#ifdef wxNEED_WX_STDIO_H
|
||||||
|
@@ -513,6 +513,7 @@ GSocketGUIFunctionsTable* wxConsoleAppTraitsBase::GetSocketGUIFunctionsTable()
|
|||||||
void wxAppTraitsBase::SetLocale()
|
void wxAppTraitsBase::SetLocale()
|
||||||
{
|
{
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
wxUpdateLocaleIsUtf8();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -1600,10 +1600,14 @@ bool wxLocale::Init(const wxString& name,
|
|||||||
|
|
||||||
|
|
||||||
#if defined(__UNIX__) && wxUSE_UNICODE && !defined(__WXMAC__)
|
#if defined(__UNIX__) && wxUSE_UNICODE && !defined(__WXMAC__)
|
||||||
static wxWCharBuffer wxSetlocaleTryUTF(int c, const wxChar *lc)
|
static wxWCharBuffer wxSetlocaleTryUTF8(int c, const wxChar *lc)
|
||||||
{
|
{
|
||||||
wxMB2WXbuf l = wxSetlocale(c, lc);
|
wxMB2WXbuf l;
|
||||||
if ( !l && lc && lc[0] != 0 )
|
|
||||||
|
// NB: We prefer to set UTF-8 locale if it's possible and only fall back to
|
||||||
|
// non-UTF-8 locale if it fails
|
||||||
|
|
||||||
|
if ( lc && lc[0] != 0 )
|
||||||
{
|
{
|
||||||
wxString buf(lc);
|
wxString buf(lc);
|
||||||
wxString buf2;
|
wxString buf2;
|
||||||
@@ -1625,10 +1629,15 @@ static wxWCharBuffer wxSetlocaleTryUTF(int c, const wxChar *lc)
|
|||||||
l = wxSetlocale(c, buf2.c_str());
|
l = wxSetlocale(c, buf2.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we can't set UTF-8 locale, try non-UTF-8 one:
|
||||||
|
if ( !l )
|
||||||
|
l = wxSetlocale(c, lc);
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define wxSetlocaleTryUTF(c, lc) wxSetlocale(c, lc)
|
#define wxSetlocaleTryUTF8(c, lc) wxSetlocale(c, lc)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool wxLocale::Init(int language, int flags)
|
bool wxLocale::Init(int language, int flags)
|
||||||
@@ -1666,13 +1675,13 @@ bool wxLocale::Init(int language, int flags)
|
|||||||
if (language != wxLANGUAGE_DEFAULT)
|
if (language != wxLANGUAGE_DEFAULT)
|
||||||
locale = info->CanonicalName;
|
locale = info->CanonicalName;
|
||||||
|
|
||||||
wxMB2WXbuf retloc = wxSetlocaleTryUTF(LC_ALL, locale);
|
wxMB2WXbuf retloc = wxSetlocaleTryUTF8(LC_ALL, locale);
|
||||||
|
|
||||||
const wxString langOnly = locale.Left(2);
|
const wxString langOnly = locale.Left(2);
|
||||||
if ( !retloc )
|
if ( !retloc )
|
||||||
{
|
{
|
||||||
// Some C libraries don't like xx_YY form and require xx only
|
// Some C libraries don't like xx_YY form and require xx only
|
||||||
retloc = wxSetlocaleTryUTF(LC_ALL, langOnly);
|
retloc = wxSetlocaleTryUTF8(LC_ALL, langOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_FONTMAP
|
#if wxUSE_FONTMAP
|
||||||
@@ -1713,9 +1722,9 @@ bool wxLocale::Init(int language, int flags)
|
|||||||
|
|
||||||
if ( !localeAlt.empty() )
|
if ( !localeAlt.empty() )
|
||||||
{
|
{
|
||||||
retloc = wxSetlocaleTryUTF(LC_ALL, localeAlt);
|
retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt);
|
||||||
if ( !retloc )
|
if ( !retloc )
|
||||||
retloc = wxSetlocaleTryUTF(LC_ALL, localeAlt.Left(2));
|
retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt.Left(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2741,11 +2750,11 @@ bool wxLocale::IsAvailable(int lang)
|
|||||||
|
|
||||||
// Test if setting the locale works, then set it back.
|
// Test if setting the locale works, then set it back.
|
||||||
wxMB2WXbuf oldLocale = wxSetlocale(LC_ALL, wxEmptyString);
|
wxMB2WXbuf oldLocale = wxSetlocale(LC_ALL, wxEmptyString);
|
||||||
wxMB2WXbuf tmp = wxSetlocaleTryUTF(LC_ALL, info->CanonicalName);
|
wxMB2WXbuf tmp = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName);
|
||||||
if ( !tmp )
|
if ( !tmp )
|
||||||
{
|
{
|
||||||
// Some C libraries don't like xx_YY form and require xx only
|
// Some C libraries don't like xx_YY form and require xx only
|
||||||
tmp = wxSetlocaleTryUTF(LC_ALL, info->CanonicalName.Left(2));
|
tmp = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName.Left(2));
|
||||||
if ( !tmp )
|
if ( !tmp )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -804,14 +804,30 @@ int WXDLLEXPORT wxStrnicmp(const wxChar *s1, const wxChar *s2, size_t n)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef wxSetlocale
|
#ifndef wxSetlocale_
|
||||||
WXDLLEXPORT wxWCharBuffer wxSetlocale(int category, const wxChar *locale)
|
wxWCharBuffer wxSetlocale_(int category, const wxChar *locale)
|
||||||
{
|
{
|
||||||
char *localeOld = setlocale(category, wxConvLibc.cWX2MB(locale));
|
char *localeOld = setlocale(category, wxConvLibc.cWX2MB(locale));
|
||||||
|
|
||||||
return wxWCharBuffer(wxConvLibc.cMB2WC(localeOld));
|
return wxWCharBuffer(wxConvLibc.cMB2WC(localeOld));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
wxWCharBuffer wxSetlocale(int category, const wxChar *locale)
|
||||||
|
{
|
||||||
|
wxWCharBuffer rv = wxSetlocale_(category, locale);
|
||||||
|
if ( rv )
|
||||||
|
wxUpdateLocaleIsUtf8();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#else // defined(wxSetlocale_)
|
||||||
|
const wxChar *wxSetlocale(int category, const wxChar *locale)
|
||||||
|
{
|
||||||
|
const wxChar *rv = wxSetlocale_(category, locale);
|
||||||
|
if ( rv )
|
||||||
|
wxUpdateLocaleIsUtf8();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#endif // wxSetlocale_ defined or not
|
||||||
|
|
||||||
#if wxUSE_WCHAR_T && !defined(HAVE_WCSLEN)
|
#if wxUSE_WCHAR_T && !defined(HAVE_WCSLEN)
|
||||||
WXDLLEXPORT size_t wxWcslen(const wchar_t *s)
|
WXDLLEXPORT size_t wxWcslen(const wchar_t *s)
|
||||||
@@ -1350,3 +1366,56 @@ int wxRemove(const wxChar *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxLocaleIsUtf8
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if wxUSE_UNICODE_UTF8
|
||||||
|
|
||||||
|
#if !wxUSE_UTF8_LOCALE_ONLY
|
||||||
|
bool wxLocaleIsUtf8 = false; // the safer setting if not known
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool wxIsLocaleUtf8()
|
||||||
|
{
|
||||||
|
// NB: we intentionally don't use wxLocale::GetSystemEncodingName(),
|
||||||
|
// because a) it may be unavailable in some builds and b) has slightly
|
||||||
|
// different semantics (default locale instead of current)
|
||||||
|
|
||||||
|
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
|
||||||
|
// GNU libc provides current character set this way (this conforms to
|
||||||
|
// Unix98)
|
||||||
|
const char *charset = nl_langinfo(CODESET);
|
||||||
|
if ( charset )
|
||||||
|
{
|
||||||
|
// "UTF-8" is used by modern glibc versions, but test other variants
|
||||||
|
// as well, just in case:
|
||||||
|
return strcmp(charset, "UTF-8") == 0 ||
|
||||||
|
strcmp(charset, "utf-8") == 0 ||
|
||||||
|
strcmp(charset, "UTF8") == 0 ||
|
||||||
|
strcmp(charset, "utf8") == 0;
|
||||||
|
}
|
||||||
|
else // nl_langinfo() failed
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// we don't know what charset libc is using, so assume the worst
|
||||||
|
// to be safe:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxUpdateLocaleIsUtf8()
|
||||||
|
{
|
||||||
|
#if wxUSE_UTF8_LOCALE_ONLY
|
||||||
|
if ( !wxIsLocaleUtf8() )
|
||||||
|
{
|
||||||
|
wxLogFatalError(_T("This program requires UTF-8 locale to run."));
|
||||||
|
}
|
||||||
|
#else // !wxUSE_UTF8_LOCALE_ONLY
|
||||||
|
wxLocaleIsUtf8 = wxIsLocaleUtf8();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_UTF8_LOCALE_ONLY
|
||||||
|
@@ -423,6 +423,7 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
|
|||||||
#else
|
#else
|
||||||
init_result = gtk_init_check( &argcGTK, &argvGTK );
|
init_result = gtk_init_check( &argcGTK, &argvGTK );
|
||||||
#endif
|
#endif
|
||||||
|
wxUpdateLocaleIsUtf8();
|
||||||
|
|
||||||
if ( argcGTK != argc )
|
if ( argcGTK != argc )
|
||||||
{
|
{
|
||||||
|
@@ -362,6 +362,7 @@ static wxString GetSM()
|
|||||||
void wxGUIAppTraits::SetLocale()
|
void wxGUIAppTraits::SetLocale()
|
||||||
{
|
{
|
||||||
gtk_set_locale();
|
gtk_set_locale();
|
||||||
|
wxUpdateLocaleIsUtf8();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user