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
|
||||
wchar_t* or UTF-8 encoded char*: */
|
||||
#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
|
||||
#define wxUSE_UNICODE_UTF8 0
|
||||
#endif
|
||||
|
@@ -19,6 +19,20 @@
|
||||
|
||||
#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
|
||||
char *strtok_r(char *, const char *, char **);
|
||||
#endif
|
||||
@@ -99,7 +113,7 @@
|
||||
#define wxToupper(c) _totupper((wxUChar)(wxChar)(c))
|
||||
|
||||
/* locale.h functons */
|
||||
#define wxSetlocale _tsetlocale
|
||||
#define wxSetlocale_ _tsetlocale
|
||||
|
||||
/* string.h functions */
|
||||
#define wxStrcat _tcscat
|
||||
@@ -476,7 +490,7 @@
|
||||
#define wxToupper toupper
|
||||
|
||||
/* locale.h functons */
|
||||
#define wxSetlocale setlocale
|
||||
#define wxSetlocale_ setlocale
|
||||
|
||||
/* string.h functions */
|
||||
#define wxStrcat strcat
|
||||
@@ -772,11 +786,14 @@ WXDLLIMPEXP_BASE wxChar * wxStrtok(wxChar *psz, const wxChar *delim, wxChar **sa
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef wxSetlocale
|
||||
class WXDLLIMPEXP_BASE wxWCharBuffer;
|
||||
WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale(int category, const wxChar *locale);
|
||||
#endif
|
||||
#endif
|
||||
#ifndef wxSetlocale_
|
||||
class WXDLLIMPEXP_BASE wxWCharBuffer;
|
||||
WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale_(int category, const wxChar *locale);
|
||||
WXDLLIMPEXP_BASE wxWCharBuffer wxSetlocale(int category, const wxChar *locale);
|
||||
#else
|
||||
WXDLLIMPEXP_BASE const wxChar *wxSetlocale(int category, const wxChar *locale);
|
||||
#endif // defined(wxSetlocale_)
|
||||
#endif // __cplusplus
|
||||
|
||||
/* stdio.h functions */
|
||||
#ifdef wxNEED_WX_STDIO_H
|
||||
|
@@ -513,6 +513,7 @@ GSocketGUIFunctionsTable* wxConsoleAppTraitsBase::GetSocketGUIFunctionsTable()
|
||||
void wxAppTraitsBase::SetLocale()
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
wxUpdateLocaleIsUtf8();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -1600,10 +1600,14 @@ bool wxLocale::Init(const wxString& name,
|
||||
|
||||
|
||||
#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);
|
||||
if ( !l && lc && lc[0] != 0 )
|
||||
wxMB2WXbuf l;
|
||||
|
||||
// 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 buf2;
|
||||
@@ -1625,10 +1629,15 @@ static wxWCharBuffer wxSetlocaleTryUTF(int c, const wxChar *lc)
|
||||
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;
|
||||
}
|
||||
#else
|
||||
#define wxSetlocaleTryUTF(c, lc) wxSetlocale(c, lc)
|
||||
#define wxSetlocaleTryUTF8(c, lc) wxSetlocale(c, lc)
|
||||
#endif
|
||||
|
||||
bool wxLocale::Init(int language, int flags)
|
||||
@@ -1666,13 +1675,13 @@ bool wxLocale::Init(int language, int flags)
|
||||
if (language != wxLANGUAGE_DEFAULT)
|
||||
locale = info->CanonicalName;
|
||||
|
||||
wxMB2WXbuf retloc = wxSetlocaleTryUTF(LC_ALL, locale);
|
||||
wxMB2WXbuf retloc = wxSetlocaleTryUTF8(LC_ALL, locale);
|
||||
|
||||
const wxString langOnly = locale.Left(2);
|
||||
if ( !retloc )
|
||||
{
|
||||
// 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
|
||||
@@ -1713,9 +1722,9 @@ bool wxLocale::Init(int language, int flags)
|
||||
|
||||
if ( !localeAlt.empty() )
|
||||
{
|
||||
retloc = wxSetlocaleTryUTF(LC_ALL, localeAlt);
|
||||
retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt);
|
||||
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.
|
||||
wxMB2WXbuf oldLocale = wxSetlocale(LC_ALL, wxEmptyString);
|
||||
wxMB2WXbuf tmp = wxSetlocaleTryUTF(LC_ALL, info->CanonicalName);
|
||||
wxMB2WXbuf tmp = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName);
|
||||
if ( !tmp )
|
||||
{
|
||||
// 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 )
|
||||
return false;
|
||||
}
|
||||
|
@@ -804,14 +804,30 @@ int WXDLLEXPORT wxStrnicmp(const wxChar *s1, const wxChar *s2, size_t n)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef wxSetlocale
|
||||
WXDLLEXPORT wxWCharBuffer wxSetlocale(int category, const wxChar *locale)
|
||||
#ifndef wxSetlocale_
|
||||
wxWCharBuffer wxSetlocale_(int category, const wxChar *locale)
|
||||
{
|
||||
char *localeOld = setlocale(category, wxConvLibc.cWX2MB(locale));
|
||||
|
||||
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)
|
||||
WXDLLEXPORT size_t wxWcslen(const wchar_t *s)
|
||||
@@ -1350,3 +1366,56 @@ int wxRemove(const wxChar *path)
|
||||
}
|
||||
|
||||
#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
|
||||
init_result = gtk_init_check( &argcGTK, &argvGTK );
|
||||
#endif
|
||||
wxUpdateLocaleIsUtf8();
|
||||
|
||||
if ( argcGTK != argc )
|
||||
{
|
||||
|
@@ -362,6 +362,7 @@ static wxString GetSM()
|
||||
void wxGUIAppTraits::SetLocale()
|
||||
{
|
||||
gtk_set_locale();
|
||||
wxUpdateLocaleIsUtf8();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user