diff --git a/configure b/configure index fa8141305a..ca5b78ace9 100755 --- a/configure +++ b/configure @@ -32627,6 +32627,9 @@ $as_echo "$as_me: WARNING: I18n code requires wxFile... disabled" >&2;} fi if test "$wxUSE_XLOCALE" = "yes" ; then + $as_echo "#define wxUSE_XLOCALE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for complete xlocale" >&5 $as_echo_n "checking for complete xlocale... " >&6; } if ${wx_cv_func_strtod_l+:} false; then : @@ -32676,7 +32679,7 @@ fi $as_echo "$wx_cv_func_strtod_l" >&6; } if test "$wx_cv_func_strtod_l" = "yes" ; then - $as_echo "#define wxUSE_XLOCALE 1" >>confdefs.h + $as_echo "#define HAVE_LOCALE_T 1" >>confdefs.h fi fi diff --git a/configure.in b/configure.in index 9b0bbd969e..8eb3571261 100644 --- a/configure.in +++ b/configure.in @@ -5747,6 +5747,8 @@ if test "$wxUSE_INTL" = "yes" ; then fi if test "$wxUSE_XLOCALE" = "yes" ; then + AC_DEFINE(wxUSE_XLOCALE) + dnl even if xlocale.h exists, it may not contain all that dnl wx needs. check if strtod_l() really is available. AC_CACHE_CHECK([for complete xlocale], @@ -5770,7 +5772,9 @@ if test "$wxUSE_XLOCALE" = "yes" ; then ]) if test "$wx_cv_func_strtod_l" = "yes" ; then - AC_DEFINE(wxUSE_XLOCALE) + dnl We don't test (just) for locale_t existence, but we still define + dnl this symbol to avoid changing the existing code using it. + AC_DEFINE(HAVE_LOCALE_T) fi fi diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 1fc2b8d989..96dd2389d6 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -208,12 +208,17 @@ wxString wxLanguageInfo::GetLocaleName() const const char* const orig = wxSetlocale(LC_ALL, NULL); const char* const ret = TrySetLocale(); - if ( !ret ) - return wxString(); + wxString retval; + if ( ret ) + { + // Note that we must copy the returned value before calling setlocale() + // again as the string "ret" points to can (and, at least under Linux + // with glibc, actually always will) be changed by this call. + retval = ret; + wxSetlocale(LC_ALL, orig); + } - wxSetlocale(LC_ALL, orig); - - return ret; + return retval; } // ---------------------------------------------------------------------------- diff --git a/src/common/xlocale.cpp b/src/common/xlocale.cpp index 02c9d2ca2d..e8095a1132 100644 --- a/src/common/xlocale.cpp +++ b/src/common/xlocale.cpp @@ -90,12 +90,10 @@ wxXLocale& wxXLocale::GetCLocale() #if wxUSE_INTL wxXLocale::wxXLocale(wxLanguage lang) { + m_locale = NULL; + const wxLanguageInfo * const info = wxLocale::GetLanguageInfo(lang); - if ( !info ) - { - m_locale = NULL; - } - else + if ( info ) { Init(info->GetLocaleName().c_str()); } diff --git a/tests/intl/intltest.cpp b/tests/intl/intltest.cpp index ecf8770640..4e39762a0f 100644 --- a/tests/intl/intltest.cpp +++ b/tests/intl/intltest.cpp @@ -42,7 +42,6 @@ private: CPPUNIT_TEST( Domain ); CPPUNIT_TEST( Headers ); CPPUNIT_TEST( DateTimeFmtFrench ); - CPPUNIT_TEST( DateTimeFmtC ); CPPUNIT_TEST( IsAvailable ); CPPUNIT_TEST_SUITE_END(); @@ -50,7 +49,6 @@ private: void Domain(); void Headers(); void DateTimeFmtFrench(); - void DateTimeFmtC(); void IsAvailable(); static wxString GetDecimalPoint() @@ -189,50 +187,27 @@ void IntlTestCase::DateTimeFmtFrench() #else static const char *FRENCH_DATE_FMT = "%d/%m/%Y"; static const char *FRENCH_LONG_DATE_FMT = "%A %d %B %Y"; -#ifdef __WXOSX__ - static const char *FRENCH_DATE_TIME_FMT = "%A %d %B %Y %H:%M:%S"; -#else static const char *FRENCH_DATE_TIME_FMT = "%d/%m/%Y %H:%M:%S"; -#endif #endif WX_ASSERT_EQUAL_FORMAT( "French short date", FRENCH_DATE_FMT, - m_locale->GetInfo(wxLOCALE_SHORT_DATE_FMT) ); + wxLocale::GetInfo(wxLOCALE_SHORT_DATE_FMT) ); WX_ASSERT_EQUAL_FORMAT( "French long date", FRENCH_LONG_DATE_FMT, - m_locale->GetInfo(wxLOCALE_LONG_DATE_FMT) ); - WX_ASSERT_EQUAL_FORMAT( "French date and time", FRENCH_DATE_TIME_FMT, - m_locale->GetInfo(wxLOCALE_DATE_TIME_FMT) ); - WX_ASSERT_EQUAL_FORMAT( "French time", "%H:%M:%S", - m_locale->GetInfo(wxLOCALE_TIME_FMT) ); -} + wxLocale::GetInfo(wxLOCALE_LONG_DATE_FMT) ); -void IntlTestCase::DateTimeFmtC() -{ - // again, glibc uses different defaults -#ifdef __GLIBC__ - static const char *C_DATE_FMT = "%m/%d/%y"; - static const char *C_LONG_DATE_FMT = "%a %b %d %Y"; - static const char *C_DATE_TIME_FMT = "%a %b %d %H:%M:%S %Y"; -#else - static const char *C_DATE_FMT = "%d/%m/%Y"; - static const char *C_LONG_DATE_FMT = "%A %d %B %Y"; + const wxString fmtDT = wxLocale::GetInfo(wxLOCALE_DATE_TIME_FMT); #ifdef __WXOSX__ - static const char *C_DATE_TIME_FMT = "%A %d %B %Y %H:%M:%S"; + // Things are difficult to test under macOS as the format keeps changing, + // e.g. at some time between 10.10 and 10.12 a new " à " string appeared in + // its middle, so test it piece-wise and hope it doesn't change too much. + INFO("French date and time format is \"" << fmtDT << "\""); + CHECK( fmtDT.StartsWith("%A %d %B %Y") ); + CHECK( fmtDT.EndsWith("%H:%M:%S") ); #else - static const char *C_DATE_TIME_FMT = "%d/%m/%Y %H:%M:%S"; + WX_ASSERT_EQUAL_FORMAT( "French date and time", FRENCH_DATE_TIME_FMT, fmtDT ); #endif -#endif - - setlocale(LC_ALL, "C"); - - WX_ASSERT_EQUAL_FORMAT( "C short date", C_DATE_FMT, - m_locale->GetInfo(wxLOCALE_SHORT_DATE_FMT) ); - WX_ASSERT_EQUAL_FORMAT( "C long date", C_LONG_DATE_FMT, - m_locale->GetInfo(wxLOCALE_LONG_DATE_FMT) ); - WX_ASSERT_EQUAL_FORMAT( "C date and time", C_DATE_TIME_FMT, - m_locale->GetInfo(wxLOCALE_DATE_TIME_FMT) ); - WX_ASSERT_EQUAL_FORMAT( "C time", "%H:%M:%S", - m_locale->GetInfo(wxLOCALE_TIME_FMT) ); + WX_ASSERT_EQUAL_FORMAT( "French time", "%H:%M:%S", + wxLocale::GetInfo(wxLOCALE_TIME_FMT) ); } void IntlTestCase::IsAvailable()