Avoid at least some unnecessary setlocale() calls

Instead of calling wxLanguageInfo::GetLocaleName(), which called
setlocale() at least thrice (first to query the current locale, second
to try to change it and third to restore the original locale) and then
calling setlocale() again if it succeeded, use the new TrySetLocale()
method which calls setlocale() just once and doesn't require calling it
again in the caller.

This makes the code slightly more efficient but, more importantly,
shorter and more clear.
This commit is contained in:
Vadim Zeitlin
2017-07-14 19:07:20 +02:00
parent 1003cf3e92
commit 8713d73466
2 changed files with 29 additions and 28 deletions

View File

@@ -75,6 +75,13 @@ struct WXDLLIMPEXP_BASE wxLanguageInfo
// setlocale() on the current system or empty string if this locale is not
// supported
wxString GetLocaleName() const;
// Call setlocale() and return non-null value if it works for this language.
//
// This function is mostly for internal use, as changing locale involves
// more than just calling setlocale() on some platforms, use wxLocale to
// do everything that needs to be done instead of calling this method.
const char* TrySetLocale() const;
};
// ----------------------------------------------------------------------------

View File

@@ -111,18 +111,6 @@ inline wxString ExtractNotLang(const wxString& langFull)
#endif // __UNIX__
// Test if setting the given locale works without actually changing it.
bool CanSetLocale(const wxString& locale)
{
const char* const orig = wxSetlocale(LC_ALL, NULL);
if ( !wxSetlocale(LC_ALL, locale) )
return false;
wxSetlocale(LC_ALL, orig);
return true;
}
} // anonymous namespace
// ----------------------------------------------------------------------------
@@ -155,7 +143,7 @@ wxUint32 wxLanguageInfo::GetLCID() const
return MAKELCID(MAKELANGID(WinLang, WinSublang), SORT_DEFAULT);
}
wxString wxLanguageInfo::GetLocaleName() const
const char* wxLanguageInfo::TrySetLocale() const
{
wxString locale;
@@ -178,15 +166,16 @@ wxString wxLanguageInfo::GetLocaleName() const
wxLogLastError(wxT("GetLocaleInfo(LOCALE_SNAME)"));
}
if ( CanSetLocale(locale) )
return locale;
const char* const retloc = wxSetlocale(LC_ALL, locale);
if ( retloc )
return retloc;
//else: fall back to LOCALE_SENGLANGUAGE
}
if ( !::GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, buffer, WXSIZEOF(buffer)) )
{
wxLogLastError(wxT("GetLocaleInfo(LOCALE_SENGLANGUAGE)"));
return locale;
return NULL;
}
locale = buffer;
@@ -202,18 +191,31 @@ wxString wxLanguageInfo::GetLocaleName() const
locale << wxT('.') << cp;
}
return CanSetLocale(locale) ? locale : wxString();
return wxSetlocale(LC_ALL, locale);
}
#else // !__WINDOWS__
wxString wxLanguageInfo::GetLocaleName() const
const char* wxLanguageInfo::TrySetLocale() const
{
return CanSetLocale(CanonicalName) ? CanonicalName : wxString();
return wxSetlocale(LC_ALL, CanonicalName);
}
#endif // __WINDOWS__/!__WINDOWS__
wxString wxLanguageInfo::GetLocaleName() const
{
const char* const orig = wxSetlocale(LC_ALL, NULL);
const char* const ret = TrySetLocale();
if ( !ret )
return wxString();
wxSetlocale(LC_ALL, orig);
return ret;
}
// ----------------------------------------------------------------------------
// wxLocale
// ----------------------------------------------------------------------------
@@ -520,15 +522,7 @@ bool wxLocale::Init(int language, int flags)
}
// and also call setlocale() to change locale used by the CRT
const wxString locale = info->GetLocaleName();
if ( locale.empty() )
{
ret = false;
}
else // have a valid locale
{
retloc = wxSetlocale(LC_ALL, locale);
}
retloc = info->TrySetLocale();
}
#if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__))
// VC++ setlocale() (also used by Mingw) can't set locale to languages that