From cc2ebb61376e4b405986dc778b426f6654a7ca78 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Mon, 25 Jul 2011 13:40:05 -0500 Subject: [PATCH] Work around QString::toDouble() problem in Qt4.7 under gcc4.6 and i386 This manifests as an incorrect conversion of "3.3" to a double value greater than 3.3, as detected by the check for "too recent" version in ./tools/designer/uic/main.cpp Nokia really needs to get some quality control people checking their code! --- tqtinterface/qt4/src/tools/tqstring.cpp | 143 ++++++++++++++++++++++++ tqtinterface/qt4/src/tools/tqstring.h | 3 + 2 files changed, 146 insertions(+) diff --git a/tqtinterface/qt4/src/tools/tqstring.cpp b/tqtinterface/qt4/src/tools/tqstring.cpp index 5c731b3..9c31fcc 100644 --- a/tqtinterface/qt4/src/tools/tqstring.cpp +++ b/tqtinterface/qt4/src/tools/tqstring.cpp @@ -1209,6 +1209,149 @@ TQString TQString::setUnicodeCodes( const ushort* tqunicode_as_ushorts, uint len return TQString(setUnicode((const TQChar*)tqunicode_as_ushorts, len)); } +/*! + Returns the string converted to a \c double value. + + If \a ok is not 0: if a conversion error occurs, \a *ok is set to + FALSE; otherwise \a *ok is set to TRUE. + + \code + TQString string( "1234.56" ); + double a = string.toDouble(); // a == 1234.56 + \endcode + + The string-to-number functions: + \list + \i toShort() + \i toUShort() + \i toInt() + \i toUInt() + \i toLong() + \i toULong() + \i toLongLong() + \i toULongLong() + \i toFloat() + \i toDouble() + \endlist + can handle numbers + represented in various locales. These representations may use different + characters for the decimal point, thousands group sepearator + and even individual digits. TQString's functions try to interpret + the string according to the current locale. The current locale is + determined from the system at application startup and can be changed + by calling TQLocale::setDefault(). If the string cannot be interpreted + according to the current locale, this function falls back + on the "C" locale. + + \code + bool ok; + double d; + + TQLocale::setDefault(TQLocale::C); + d = TQString( "1234,56" ).toDouble(&ok); // ok == false + d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + + TQLocale::setDefault(TQLocale::German); + d = TQString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56 + d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + \endcode + + Due to the ambiguity between the decimal point and thousands group + separator in various locales, these functions do not handle + thousands group separators. If you need to convert such numbers, + use the corresponding function in TQLocale. + + \code + bool ok; + TQLocale::setDefault(TQLocale::C); + double d = TQString( "1,234,567.89" ).toDouble(&ok); // ok == false + \endcode + + \warning If the string tqcontains trailing whitespace this function + will fail, and set \a *ok to false if \a ok is not 0. Leading + whitespace is ignored. + + \sa number() TQLocale::setDefault() TQLocale::toDouble() stripWhiteSpace() +*/ + +double TQString::toDouble( bool *ok ) const +{ + // If there is trailing whitespace, set ok to false but return the correct + // result anyway to preserve behavour of pervious versions of TQt + if (length() > 0 && tqunicode()[length() - 1].isSpace()) { + TQString tmp = stripWhiteSpace(); + if (ok != 0) + *ok = FALSE; + return tmp.toDouble(); + } + + // Try the default locale + bool my_ok; + TQLocale def_locale; + double result = def_locale.d->stringToDouble(*this, &my_ok, TQLocalePrivate::FailOnGroupSeparators); + if (my_ok) { + if (ok != 0) + *ok = TRUE; + return result; + } + + // If the default was not "C", try the "C" locale + if (def_locale.language() == TQLocale::C) { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + + TQLocale c_locale(TQLocale::C); + return c_locale.d->stringToDouble(*this, ok, TQLocalePrivate::FailOnGroupSeparators); +} + +/*! + Returns the string converted to a \c float value. + + Returns 0.0 if the conversion fails. + + If \a ok is not 0: if a conversion error occurs, \a *ok is set to + FALSE; otherwise \a *ok is set to TRUE. + + For information on how string-to-number functions in TQString handle + localized input, see toDouble(). + + \warning If the string tqcontains trailing whitespace this function + will fail, settings \a *ok to false if \a ok is not 0. + Leading whitespace is ignored. + + \sa number() +*/ + +#define TQT_MAX_FLOAT 3.4028234663852886e+38 + +float TQString::toFloat( bool *ok ) const +{ + bool myOk; + double d = toDouble(&myOk); + if (!myOk || d > TQT_MAX_FLOAT || d < -TQT_MAX_FLOAT) { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + if (ok != 0) + *ok = TRUE; + return (float) d; +} + +/*! + Sets the string to the printed value of \a n in base \a base and + returns a reference to the string. The returned string is in "C" locale. + + The base is 10 by default and must be between 2 and 36. + + \code + TQString string; + string = string.setNum( 1234 ); // string == "1234" + \endcode +*/ + #else // USE_QT4 static int ucstrcmp( const TQString &as, const TQString &bs ) diff --git a/tqtinterface/qt4/src/tools/tqstring.h b/tqtinterface/qt4/src/tools/tqstring.h index 71bc563..91ceb9d 100644 --- a/tqtinterface/qt4/src/tools/tqstring.h +++ b/tqtinterface/qt4/src/tools/tqstring.h @@ -305,6 +305,9 @@ public: inline static TQString number( uint n, int base=10) { return TQString(QString::number(n, base)); } inline static TQString number( double n, char f='g', int prec=6 ) { return TQString(QString::number(n, f, prec)); } + float toFloat( bool *ok=0 ) const; + double toDouble( bool *ok=0 ) const; + TQString &setAscii( const char*, int len=-1 ); TQString &setLatin1( const char *ch, int len=-1 );