From 8713d7346683db459d15054322c36cf730c79757 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 14 Jul 2017 19:07:20 +0200 Subject: [PATCH] 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. --- include/wx/intl.h | 7 +++++++ src/common/intl.cpp | 50 ++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/include/wx/intl.h b/include/wx/intl.h index 26c940fb1f..f1a9dafd9b 100644 --- a/include/wx/intl.h +++ b/include/wx/intl.h @@ -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; }; // ---------------------------------------------------------------------------- diff --git a/src/common/intl.cpp b/src/common/intl.cpp index c819090e1f..a951a655c6 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -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