X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a243da29c8135be476e47a035a81e695bbb21e26..319faba717040fd0af134f4a36fba3f0b8e284ab:/src/common/xlocale.cpp?ds=sidebyside diff --git a/src/common/xlocale.cpp b/src/common/xlocale.cpp index f89a755766..d0197463f8 100644 --- a/src/common/xlocale.cpp +++ b/src/common/xlocale.cpp @@ -32,6 +32,7 @@ #include "wx/xlocale.h" #include +#include // ---------------------------------------------------------------------------- // module globals @@ -76,7 +77,9 @@ wxXLocale& wxXLocale::GetCLocale() { if ( !gs_cLocale ) { - gs_cLocale = new wxXLocale(static_cast(NULL)); + // NOTE: bcc551 has trouble doing static_cast with incomplete + // type definition. reinterpret_cast used as workaround + gs_cLocale = new wxXLocale( reinterpret_cast(NULL) ); } return *gs_cLocale; @@ -276,70 +279,91 @@ int wxToupper_l(const wxUniChar& c, const wxXLocale& loc) case !wxHAS_XLOCALE_SUPPORT... */ -/* - Note that this code is similar to (a portion of) wxLocale::IsAvailable code -*/ -#define IMPLEMENT_STRTOX_L_START \ - wxCHECK(loc.IsOk(), 0); \ - \ - /* (Try to) temporary set the 'C' locale */ \ - const char *oldLocale = wxSetlocale(LC_NUMERIC, "C"); \ - if ( !oldLocale ) \ - { \ - /* the current locale was not changed; no need to */ \ - /* restore the previous one... */ \ - errno = EINVAL; \ - /* signal an error (better than nothing) */ \ - return 0; \ +namespace +{ + +// Helper class that changes LC_NUMERIC facet of the global locale in its ctor +// to "C" locale and restores it in its dtor later. +class CNumericLocaleSetter +{ +public: + CNumericLocaleSetter() + : m_oldLocale(wxStrdupA(setlocale(LC_NUMERIC, NULL))) + { + if ( !wxSetlocale(LC_NUMERIC, "C") ) + { + // Setting locale to "C" should really always work. + wxFAIL_MSG( wxS("Couldn't set LC_NUMERIC to \"C\"") ); + } } -#define IMPLEMENT_STRTOX_L_END \ - /* restore the original locale */ \ - wxSetlocale(LC_NUMERIC, oldLocale); \ - return ret; + ~CNumericLocaleSetter() + { + wxSetlocale(LC_NUMERIC, m_oldLocale); + free(m_oldLocale); + } + +private: + char * const m_oldLocale; + + wxDECLARE_NO_COPY_CLASS(CNumericLocaleSetter); +}; + +} // anonymous namespace double wxStrtod_l(const wchar_t* str, wchar_t **endptr, const wxXLocale& loc) { - IMPLEMENT_STRTOX_L_START - double ret = wxStrtod(str, endptr); - IMPLEMENT_STRTOX_L_END + wxCHECK( loc.IsOk(), 0. ); + + CNumericLocaleSetter locSetter; + + return wxStrtod(str, endptr); } double wxStrtod_l(const char* str, char **endptr, const wxXLocale& loc) { - IMPLEMENT_STRTOX_L_START - double ret = wxStrtod(str, endptr); - IMPLEMENT_STRTOX_L_END + wxCHECK( loc.IsOk(), 0. ); + + CNumericLocaleSetter locSetter; + + return wxStrtod(str, endptr); } long wxStrtol_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc) { - IMPLEMENT_STRTOX_L_START - long ret = wxStrtol(str, endptr, base); - IMPLEMENT_STRTOX_L_END + wxCHECK( loc.IsOk(), 0 ); + + CNumericLocaleSetter locSetter; + + return wxStrtol(str, endptr, base); } long wxStrtol_l(const char* str, char **endptr, int base, const wxXLocale& loc) { - IMPLEMENT_STRTOX_L_START - long ret = wxStrtol(str, endptr, base); - IMPLEMENT_STRTOX_L_END + wxCHECK( loc.IsOk(), 0 ); + + CNumericLocaleSetter locSetter; + + return wxStrtol(str, endptr, base); } unsigned long wxStrtoul_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc) { - IMPLEMENT_STRTOX_L_START - unsigned long ret = wxStrtoul(str, endptr, base); - IMPLEMENT_STRTOX_L_END + wxCHECK( loc.IsOk(), 0 ); + + CNumericLocaleSetter locSetter; + + return wxStrtoul(str, endptr, base); } unsigned long wxStrtoul_l(const char* str, char **endptr, int base, const wxXLocale& loc) { - IMPLEMENT_STRTOX_L_START - unsigned long ret = wxStrtoul(str, endptr, base); - IMPLEMENT_STRTOX_L_END -} + wxCHECK( loc.IsOk(), 0 ); + + CNumericLocaleSetter locSetter; + return wxStrtoul(str, endptr, base); +} #endif // !defined(wxHAS_XLOCALE_SUPPORT)