Don't use C++ streams in wxString::FromCDouble() implementation.
This doesn't work if the global C++ locale had been changed and we can't call imbue(locale::classic()) to ensure that the stream we use here uses the C locale because imbue() is hopelessly broken in some implementations. So just get rid of this code and keep only the hack replacing the decimal separator with the dot explicitly. This is ugly but should always work in practice and is also consistent with ToCDouble(). Closes #16343. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76796 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1795,6 +1795,8 @@ bool wxString::ToCULong(unsigned long *pVal, int base) const
|
||||
// point which is different in different locales.
|
||||
bool wxString::ToCDouble(double *pVal) const
|
||||
{
|
||||
// See the explanations in FromCDouble() below for the reasons for all this.
|
||||
|
||||
// Create a copy of this string using the decimal point instead of whatever
|
||||
// separator the current locale uses.
|
||||
#if wxUSE_INTL
|
||||
@@ -1852,20 +1854,19 @@ wxString wxString::FromCDouble(double val, int precision)
|
||||
{
|
||||
wxCHECK_MSG( precision >= -1, wxString(), "Invalid negative precision" );
|
||||
|
||||
#if wxUSE_STD_IOSTREAM && wxUSE_STD_STRING
|
||||
// We assume that we can use the ostream and not wstream for numbers.
|
||||
wxSTD ostringstream os;
|
||||
if ( precision != -1 )
|
||||
{
|
||||
os.precision(precision);
|
||||
os.setf(std::ios::fixed, std::ios::floatfield);
|
||||
}
|
||||
// Unfortunately there is no good way to get the number directly in the C
|
||||
// locale. Some platforms provide special functions to do this (e.g.
|
||||
// _sprintf_l() in MSVS or sprintf_l() in BSD systems), but some systems we
|
||||
// still support don't have them and it doesn't seem worth it to have two
|
||||
// different ways to do the same thing. Also, in principle, using the
|
||||
// standard C++ streams should allow us to do it, but some implementations
|
||||
// of them are horribly broken and actually change the global C locale,
|
||||
// thus randomly affecting the results produced in other threads, when
|
||||
// imbue() stream method is called (for the record, the latest libstdc++
|
||||
// version included in OS X does it and so seem to do the versions
|
||||
// currently included in Android NDK and both FreeBSD and OpenBSD), so we
|
||||
// can't do this neither and are reduced to this hack.
|
||||
|
||||
os << val;
|
||||
return os.str();
|
||||
#else // !wxUSE_STD_IOSTREAM
|
||||
// Can't use iostream locale support, fall back to the manual method
|
||||
// instead.
|
||||
wxString s = FromDouble(val, precision);
|
||||
#if wxUSE_INTL
|
||||
wxString sep = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
|
||||
@@ -1879,7 +1880,6 @@ wxString wxString::FromCDouble(double val, int precision)
|
||||
|
||||
s.Replace(sep, ".");
|
||||
return s;
|
||||
#endif // wxUSE_STD_IOSTREAM/!wxUSE_STD_IOSTREAM
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user