QString: Make convert to number methods only use C locale

Ensure consistent conversions by not using the system default locale.

Change-Id: I60db9fc4f465c0254f3213419e57d7879aaddd65
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
This commit is contained in:
John Layt 2012-01-22 21:23:50 +00:00 committed by Qt by Nokia
parent 96501b0a18
commit 1e3833bed8
4 changed files with 147 additions and 204 deletions

6
dist/changes-5.0.0 vendored
View File

@ -240,6 +240,12 @@ QtCore
now return an empty QString, QStringRef or QByteArray respectively. now return an empty QString, QStringRef or QByteArray respectively.
in Qt 4 they returned a null QString or a null QStringRef. in Qt 4 they returned a null QString or a null QStringRef.
* QString methods toLongLong(), toULongLong(), toLong(), toULong(), toInt(),
toUInt(), toShort(), toUShort(), toDouble(), and toFloat() no longer use the
default or system locale, they will always use the C locale. This is to
guarantee consistent default conversion of strings. For locale-aware conversions
use the equivalent QLocale methods.
* QDate, QTime, and QDateTime have undergone important behavioural changes: * QDate, QTime, and QDateTime have undergone important behavioural changes:
* QDate only implements the Gregorian calendar, the switch to the Julian * QDate only implements the Gregorian calendar, the switch to the Julian
calendar before 1582 has been removed. This means all QDate methods will calendar before 1582 has been removed. This means all QDate methods will

View File

@ -737,20 +737,15 @@ void Widget::toDoubleFunction()
d = QString( "1234.56e-02" ).toDouble(&ok); // ok == true, d == 12.3456 d = QString( "1234.56e-02" ).toDouble(&ok); // ok == true, d == 12.3456
//! [67] //! [67]
//! [68] //! [69]
QLocale::setDefault(QLocale::C);
d = QString( "1234,56" ).toDouble(&ok); // ok == false
//! [68] //! [68]
d = QString( "1234,56" ).toDouble(&ok); // ok == false
d = QString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 d = QString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56
//! [68]
//! [69] //! [70] //! [69]
QLocale::setDefault(QLocale::German);
d = QString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56
d = QString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56
//! [70]
QLocale::setDefault(QLocale::C);
d = QString( "1,234,567.89" ).toDouble(&ok); // ok == false d = QString( "1,234,567.89" ).toDouble(&ok); // ok == false
d = QString( "1234567.89" ).toDouble(&ok); // ok == true
//! [69]
} }
void Widget::toFloatFunction() void Widget::toFloatFunction()

View File

@ -5433,11 +5433,14 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toLongLong()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 74 \snippet doc/src/snippets/qstring/main.cpp 74
\sa number(), toULongLong(), toInt() \sa number(), toULongLong(), toInt(), QLocale::toLongLong()
*/ */
qint64 QString::toLongLong(bool *ok, int base) const qint64 QString::toLongLong(bool *ok, int base) const
@ -5449,15 +5452,6 @@ qint64 QString::toLongLong(bool *ok, int base) const
} }
#endif #endif
bool my_ok;
QLocale def_locale;
qint64 result = def_locale.d()->stringToLongLong(*this, base, &my_ok, QLocalePrivate::FailOnGroupSeparators);
if (my_ok) {
if (ok != 0)
*ok = true;
return result;
}
QLocale c_locale(QLocale::C); QLocale c_locale(QLocale::C);
return c_locale.d()->stringToLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators); return c_locale.d()->stringToLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
} }
@ -5474,11 +5468,14 @@ qint64 QString::toLongLong(bool *ok, int base) const
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toULongLong()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 79 \snippet doc/src/snippets/qstring/main.cpp 79
\sa number(), toLongLong() \sa number(), toLongLong(), QLocale::toULongLong()
*/ */
quint64 QString::toULongLong(bool *ok, int base) const quint64 QString::toULongLong(bool *ok, int base) const
@ -5490,15 +5487,6 @@ quint64 QString::toULongLong(bool *ok, int base) const
} }
#endif #endif
bool my_ok;
QLocale def_locale;
quint64 result = def_locale.d()->stringToUnsLongLong(*this, base, &my_ok, QLocalePrivate::FailOnGroupSeparators);
if (my_ok) {
if (ok != 0)
*ok = true;
return result;
}
QLocale c_locale(QLocale::C); QLocale c_locale(QLocale::C);
return c_locale.d()->stringToUnsLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators); return c_locale.d()->stringToUnsLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
} }
@ -5517,11 +5505,14 @@ quint64 QString::toULongLong(bool *ok, int base) const
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toLong()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 73 \snippet doc/src/snippets/qstring/main.cpp 73
\sa number(), toULong(), toInt() \sa number(), toULong(), toInt(), QLocale::toLong()
*/ */
long QString::toLong(bool *ok, int base) const long QString::toLong(bool *ok, int base) const
@ -5549,11 +5540,14 @@ long QString::toLong(bool *ok, int base) const
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toULong()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 78 \snippet doc/src/snippets/qstring/main.cpp 78
\sa number() \sa number(), QLocale::toULong()
*/ */
ulong QString::toULong(bool *ok, int base) const ulong QString::toULong(bool *ok, int base) const
@ -5580,11 +5574,14 @@ ulong QString::toULong(bool *ok, int base) const
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toInt()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 72 \snippet doc/src/snippets/qstring/main.cpp 72
\sa number(), toUInt(), toDouble() \sa number(), toUInt(), toDouble(), QLocale::toInt()
*/ */
int QString::toInt(bool *ok, int base) const int QString::toInt(bool *ok, int base) const
@ -5610,11 +5607,14 @@ int QString::toInt(bool *ok, int base) const
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toUInt()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 77 \snippet doc/src/snippets/qstring/main.cpp 77
\sa number(), toInt() \sa number(), toInt(), QLocale::toUInt()
*/ */
uint QString::toUInt(bool *ok, int base) const uint QString::toUInt(bool *ok, int base) const
@ -5640,11 +5640,14 @@ uint QString::toUInt(bool *ok, int base) const
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toShort()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 76 \snippet doc/src/snippets/qstring/main.cpp 76
\sa number(), toUShort(), toInt() \sa number(), toUShort(), toInt(), QLocale::toShort()
*/ */
short QString::toShort(bool *ok, int base) const short QString::toShort(bool *ok, int base) const
@ -5670,11 +5673,14 @@ short QString::toShort(bool *ok, int base) const
begins with "0x", base 16 is used; if the string begins with "0", begins with "0x", base 16 is used; if the string begins with "0",
base 8 is used; otherwise, base 10 is used. base 8 is used; otherwise, base 10 is used.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toUShort()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 80 \snippet doc/src/snippets/qstring/main.cpp 80
\sa number(), toShort() \sa number(), toShort(), QLocale::toUShort()
*/ */
ushort QString::toUShort(bool *ok, int base) const ushort QString::toUShort(bool *ok, int base) const
@ -5704,37 +5710,22 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet doc/src/snippets/qstring/main.cpp 67 \snippet doc/src/snippets/qstring/main.cpp 67
This function tries to interpret the string according to the The string conversion will always happen in the 'C' locale. For locale
current locale. The current locale is determined from the dependent conversion use QLocale::toDouble()
system at application startup and can be changed by calling
QLocale::setDefault(). If the string cannot be interpreted
according to the current locale, this function falls back
on the "C" locale.
\snippet doc/src/snippets/qstring/main.cpp 69
\snippet doc/src/snippets/qstring/main.cpp 70
Due to the ambiguity between the decimal point and thousands group
separator in various locales, this function does not handle
thousands group separators. If you need to convert such numbers,
see QLocale::toDouble().
\snippet doc/src/snippets/qstring/main.cpp 68 \snippet doc/src/snippets/qstring/main.cpp 68
For historic reasons, this function does not handle
thousands group separators. If you need to convert such numbers,
use QLocale::toDouble().
\snippet doc/src/snippets/qstring/main.cpp 69
\sa number() QLocale::setDefault() QLocale::toDouble() trimmed() \sa number() QLocale::setDefault() QLocale::toDouble() trimmed()
*/ */
double QString::toDouble(bool *ok) const double QString::toDouble(bool *ok) const
{ {
bool my_ok;
QLocale def_locale;
double result = def_locale.d()->stringToDouble(*this, &my_ok, QLocalePrivate::FailOnGroupSeparators);
if (my_ok) {
if (ok != 0)
*ok = true;
return result;
}
QLocale c_locale(QLocale::C); QLocale c_locale(QLocale::C);
return c_locale.d()->stringToDouble(*this, ok, QLocalePrivate::FailOnGroupSeparators); return c_locale.d()->stringToDouble(*this, ok, QLocalePrivate::FailOnGroupSeparators);
} }
@ -5745,11 +5736,14 @@ double QString::toDouble(bool *ok) const
If a conversion error occurs, *\a{ok} is set to false; otherwise If a conversion error occurs, *\a{ok} is set to false; otherwise
*\a{ok} is set to true. Returns 0.0 if the conversion fails. *\a{ok} is set to true. Returns 0.0 if the conversion fails.
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toFloat()
Example: Example:
\snippet doc/src/snippets/qstring/main.cpp 71 \snippet doc/src/snippets/qstring/main.cpp 71
\sa number(), toDouble(), toInt() \sa number(), toDouble(), toInt(), QLocale::toFloat()
*/ */
#define QT_MAX_FLOAT 3.4028234663852886e+38 #define QT_MAX_FLOAT 3.4028234663852886e+38
@ -5851,8 +5845,9 @@ QString &QString::setNum(qulonglong n, int base)
The \a format can be 'f', 'F', 'e', 'E', 'g' or 'G' (see the The \a format can be 'f', 'F', 'e', 'E', 'g' or 'G' (see the
arg() function documentation for an explanation of the formats). arg() function documentation for an explanation of the formats).
Unlike QLocale::toString(), this function doesn't honor the The formatting always uses QLocale::C, i.e., English/UnitedStates.
user's locale settings. To get a localized string representation of a number, use
QLocale::toString() with the appropriate locale.
*/ */
QString &QString::setNum(double n, char f, int prec) QString &QString::setNum(double n, char f, int prec)
@ -5893,6 +5888,10 @@ QString &QString::setNum(double n, char f, int prec)
Sets the string to the printed value of \a n, formatted according Sets the string to the printed value of \a n, formatted according
to the given \a format and \a precision, and returns a reference to the given \a format and \a precision, and returns a reference
to the string. to the string.
The formatting always uses QLocale::C, i.e., English/UnitedStates.
To get a localized string representation of a number, use
QLocale::toString() with the appropriate locale.
*/ */
@ -5906,6 +5905,10 @@ QString &QString::setNum(double n, char f, int prec)
and 36. For bases other than 10, \a n is treated as an and 36. For bases other than 10, \a n is treated as an
unsigned integer. unsigned integer.
The formatting always uses QLocale::C, i.e., English/UnitedStates.
To get a localized string representation of a number, use
QLocale::toString() with the appropriate locale.
\snippet doc/src/snippets/qstring/main.cpp 35 \snippet doc/src/snippets/qstring/main.cpp 35
\sa setNum() \sa setNum()

View File

@ -3989,107 +3989,83 @@ void tst_QString::operator_smaller()
void tst_QString::integer_conversion_data() void tst_QString::integer_conversion_data()
{ {
QTest::addColumn<QString>("locale_name");
QTest::addColumn<QString>("num_str"); QTest::addColumn<QString>("num_str");
QTest::addColumn<int>("base"); QTest::addColumn<int>("base");
QTest::addColumn<bool>("good"); QTest::addColumn<bool>("good");
QTest::addColumn<qlonglong>("num"); QTest::addColumn<qlonglong>("num");
QTest::newRow("C empty 0") << QString("C") << QString("") << 0 << false << (qlonglong)0; QTest::newRow("C empty 0") << QString("") << 0 << false << (qlonglong)0;
QTest::newRow("C empty 8") << QString("C") << QString("") << 8 << false << (qlonglong)0; QTest::newRow("C empty 8") << QString("") << 8 << false << (qlonglong)0;
QTest::newRow("C empty 10") << QString("C") << QString("") << 10 << false << (qlonglong)0; QTest::newRow("C empty 10") << QString("") << 10 << false << (qlonglong)0;
QTest::newRow("C empty 16") << QString("C") << QString("") << 16 << false << (qlonglong)0; QTest::newRow("C empty 16") << QString("") << 16 << false << (qlonglong)0;
QTest::newRow("C null 0") << QString("C") << QString() << 0 << false << (qlonglong)0; QTest::newRow("C null 0") << QString() << 0 << false << (qlonglong)0;
QTest::newRow("C null 8") << QString("C") << QString() << 8 << false << (qlonglong)0; QTest::newRow("C null 8") << QString() << 8 << false << (qlonglong)0;
QTest::newRow("C null 10") << QString("C") << QString() << 10 << false << (qlonglong)0; QTest::newRow("C null 10") << QString() << 10 << false << (qlonglong)0;
QTest::newRow("C null 16") << QString("C") << QString() << 16 << false << (qlonglong)0; QTest::newRow("C null 16") << QString() << 16 << false << (qlonglong)0;
QTest::newRow("C -0xf 0") << QString("C") << QString(" -0xf") << 0 << true << (qlonglong)-15; QTest::newRow("C -0xf 0") << QString(" -0xf") << 0 << true << (qlonglong)-15;
QTest::newRow("C -0xf 0") << QString("C") << QString("-0xf ") << 0 << true << (qlonglong)-15; QTest::newRow("C -0xf 0") << QString("-0xf ") << 0 << true << (qlonglong)-15;
QTest::newRow("C \t0xf\t 0") << QString("C") << QString("\t0xf\t") << 0 << true << (qlonglong)15; QTest::newRow("C \t0xf\t 0") << QString("\t0xf\t") << 0 << true << (qlonglong)15;
QTest::newRow("C -010 0") << QString("C") << QString(" -010") << 0 << true << (qlonglong)-8; QTest::newRow("C -010 0") << QString(" -010") << 0 << true << (qlonglong)-8;
QTest::newRow("C 010 0") << QString("C") << QString("010 ") << 0 << true << (qlonglong)8; QTest::newRow("C 010 0") << QString("010 ") << 0 << true << (qlonglong)8;
QTest::newRow("C \t-010\t 0") << QString("C") << QString("\t-010\t") << 0 << true << (qlonglong)-8; QTest::newRow("C \t-010\t 0") << QString("\t-010\t") << 0 << true << (qlonglong)-8;
QTest::newRow("C 123 10") << QString("C") << QString(" 123") << 10 << true << (qlonglong)123; QTest::newRow("C 123 10") << QString(" 123") << 10 << true << (qlonglong)123;
QTest::newRow("C 123 10") << QString("C") << QString("123 ") << 10 << true << (qlonglong)123; QTest::newRow("C 123 10") << QString("123 ") << 10 << true << (qlonglong)123;
QTest::newRow("C \t123\t 10") << QString("C") << QString("\t123\t") << 10 << true << (qlonglong)123; QTest::newRow("C \t123\t 10") << QString("\t123\t") << 10 << true << (qlonglong)123;
QTest::newRow("C -0xf 16") << QString("C") << QString(" -0xf") << 16 << true << (qlonglong)-15; QTest::newRow("C -0xf 16") << QString(" -0xf") << 16 << true << (qlonglong)-15;
QTest::newRow("C -0xf 16") << QString("C") << QString("-0xf ") << 16 << true << (qlonglong)-15; QTest::newRow("C -0xf 16") << QString("-0xf ") << 16 << true << (qlonglong)-15;
QTest::newRow("C \t0xf\t 16") << QString("C") << QString("\t0xf\t") << 16 << true << (qlonglong)15; QTest::newRow("C \t0xf\t 16") << QString("\t0xf\t") << 16 << true << (qlonglong)15;
QTest::newRow("C -0 0") << QString("C") << QString("-0") << 0 << true << (qlonglong)0; QTest::newRow("C -0 0") << QString("-0") << 0 << true << (qlonglong)0;
QTest::newRow("C -0 8") << QString("C") << QString("-0") << 8 << true << (qlonglong)0; QTest::newRow("C -0 8") << QString("-0") << 8 << true << (qlonglong)0;
QTest::newRow("C -0 10") << QString("C") << QString("-0") << 10 << true << (qlonglong)0; QTest::newRow("C -0 10") << QString("-0") << 10 << true << (qlonglong)0;
QTest::newRow("C -0 16") << QString("C") << QString("-0") << 16 << true << (qlonglong)0; QTest::newRow("C -0 16") << QString("-0") << 16 << true << (qlonglong)0;
QTest::newRow("C 1.234 10") << QString("C") << QString("1.234") << 10 << false << (qlonglong)0; QTest::newRow("C 1.234 10") << QString("1.234") << 10 << false << (qlonglong)0;
QTest::newRow("C 1,234 10") << QString("C") << QString("1,234") << 10 << false << (qlonglong)0; QTest::newRow("C 1,234 10") << QString("1,234") << 10 << false << (qlonglong)0;
QTest::newRow("de_DE 1.234 10") << QString("de_DE") << QString("1.234") << 10 << false << (qlonglong)0;
QTest::newRow("de_DE 1,234 10") << QString("de_DE") << QString("1,234") << 10 << false << (qlonglong)0;
QTest::newRow("C 0x 0") << QString("C") << QString("0x") << 0 << false << (qlonglong)0; QTest::newRow("C 0x 0") << QString("0x") << 0 << false << (qlonglong)0;
QTest::newRow("C 0x 16") << QString("C") << QString("0x") << 16 << false << (qlonglong)0; QTest::newRow("C 0x 16") << QString("0x") << 16 << false << (qlonglong)0;
QTest::newRow("C 10 0") << QString("C") << QString("10") << 0 << true << (qlonglong)10; QTest::newRow("C 10 0") << QString("10") << 0 << true << (qlonglong)10;
QTest::newRow("C 010 0") << QString("C") << QString("010") << 0 << true << (qlonglong)8; QTest::newRow("C 010 0") << QString("010") << 0 << true << (qlonglong)8;
QTest::newRow("C 0x10 0") << QString("C") << QString("0x10") << 0 << true << (qlonglong)16; QTest::newRow("C 0x10 0") << QString("0x10") << 0 << true << (qlonglong)16;
QTest::newRow("C 10 8") << QString("C") << QString("10") << 8 << true << (qlonglong)8; QTest::newRow("C 10 8") << QString("10") << 8 << true << (qlonglong)8;
QTest::newRow("C 010 8") << QString("C") << QString("010") << 8 << true << (qlonglong)8; QTest::newRow("C 010 8") << QString("010") << 8 << true << (qlonglong)8;
QTest::newRow("C 0x10 8") << QString("C") << QString("0x10") << 8 << false << (qlonglong)0; QTest::newRow("C 0x10 8") << QString("0x10") << 8 << false << (qlonglong)0;
QTest::newRow("C 10 10") << QString("C") << QString("10") << 10 << true << (qlonglong)10; QTest::newRow("C 10 10") << QString("10") << 10 << true << (qlonglong)10;
QTest::newRow("C 010 10") << QString("C") << QString("010") << 10 << true << (qlonglong)10; QTest::newRow("C 010 10") << QString("010") << 10 << true << (qlonglong)10;
QTest::newRow("C 0x10 10") << QString("C") << QString("0x10") << 10 << false << (qlonglong)0; QTest::newRow("C 0x10 10") << QString("0x10") << 10 << false << (qlonglong)0;
QTest::newRow("C 10 16") << QString("C") << QString("10") << 16 << true << (qlonglong)16; QTest::newRow("C 10 16") << QString("10") << 16 << true << (qlonglong)16;
QTest::newRow("C 010 16") << QString("C") << QString("010") << 16 << true << (qlonglong)16; QTest::newRow("C 010 16") << QString("010") << 16 << true << (qlonglong)16;
QTest::newRow("C 0x10 16") << QString("C") << QString("0x10") << 16 << true << (qlonglong)16; QTest::newRow("C 0x10 16") << QString("0x10") << 16 << true << (qlonglong)16;
QTest::newRow("de_DE 10 0") << QString("de_DE") << QString("10") << 0 << true << (qlonglong)10; QTest::newRow("C -10 0") << QString("-10") << 0 << true << (qlonglong)-10;
QTest::newRow("de_DE 010 0") << QString("de_DE") << QString("010") << 0 << true << (qlonglong)8; QTest::newRow("C -010 0") << QString("-010") << 0 << true << (qlonglong)-8;
QTest::newRow("de_DE 0x10 0") << QString("de_DE") << QString("0x10") << 0 << true << (qlonglong)16; QTest::newRow("C -0x10 0") << QString("-0x10") << 0 << true << (qlonglong)-16;
QTest::newRow("de_DE 10 8") << QString("de_DE") << QString("10") << 8 << true << (qlonglong)8; QTest::newRow("C -10 8") << QString("-10") << 8 << true << (qlonglong)-8;
QTest::newRow("de_DE 010 8") << QString("de_DE") << QString("010") << 8 << true << (qlonglong)8; QTest::newRow("C -010 8") << QString("-010") << 8 << true << (qlonglong)-8;
QTest::newRow("de_DE 0x10 8") << QString("de_DE") << QString("0x10") << 8 << false << (qlonglong)0; QTest::newRow("C -0x10 8") << QString("-0x10") << 8 << false << (qlonglong)0;
QTest::newRow("de_DE 10 10") << QString("de_DE") << QString("10") << 10 << true << (qlonglong)10; QTest::newRow("C -10 10") << QString("-10") << 10 << true << (qlonglong)-10;
QTest::newRow("de_DE 010 10") << QString("de_DE") << QString("010") << 10 << true << (qlonglong)10; QTest::newRow("C -010 10") << QString("-010") << 10 << true << (qlonglong)-10;
QTest::newRow("de_DE 0x10 10") << QString("de_DE") << QString("0x10") << 10 << false << (qlonglong)0; QTest::newRow("C -0x10 10") << QString("-0x10") << 10 << false << (qlonglong)0;
QTest::newRow("de_DE 10 16") << QString("de_DE") << QString("10") << 16 << true << (qlonglong)16; QTest::newRow("C -10 16") << QString("-10") << 16 << true << (qlonglong)-16;
QTest::newRow("de_DE 010 16") << QString("de_DE") << QString("010") << 16 << true << (qlonglong)16; QTest::newRow("C -010 16") << QString("-010") << 16 << true << (qlonglong)-16;
QTest::newRow("de_DE 0x10 16") << QString("de_DE") << QString("0x10") << 16 << true << (qlonglong)16; QTest::newRow("C -0x10 16") << QString("-0x10") << 16 << true << (qlonglong)-16;
QTest::newRow("C -10 0") << QString("C") << QString("-10") << 0 << true << (qlonglong)-10;
QTest::newRow("C -010 0") << QString("C") << QString("-010") << 0 << true << (qlonglong)-8;
QTest::newRow("C -0x10 0") << QString("C") << QString("-0x10") << 0 << true << (qlonglong)-16;
QTest::newRow("C -10 8") << QString("C") << QString("-10") << 8 << true << (qlonglong)-8;
QTest::newRow("C -010 8") << QString("C") << QString("-010") << 8 << true << (qlonglong)-8;
QTest::newRow("C -0x10 8") << QString("C") << QString("-0x10") << 8 << false << (qlonglong)0;
QTest::newRow("C -10 10") << QString("C") << QString("-10") << 10 << true << (qlonglong)-10;
QTest::newRow("C -010 10") << QString("C") << QString("-010") << 10 << true << (qlonglong)-10;
QTest::newRow("C -0x10 10") << QString("C") << QString("-0x10") << 10 << false << (qlonglong)0;
QTest::newRow("C -10 16") << QString("C") << QString("-10") << 16 << true << (qlonglong)-16;
QTest::newRow("C -010 16") << QString("C") << QString("-010") << 16 << true << (qlonglong)-16;
QTest::newRow("C -0x10 16") << QString("C") << QString("-0x10") << 16 << true << (qlonglong)-16;
// Let's try some Arabic // Let's try some Arabic
const quint16 arabic_str[] = { 0x0661, 0x0662, 0x0663, 0x0664, 0x0000 }; // "1234" const quint16 arabic_str[] = { 0x0661, 0x0662, 0x0663, 0x0664, 0x0000 }; // "1234"
QTest::newRow("ar_SA 1234 0") << QString("ar_SA") << QString::fromUtf16(arabic_str) << 0 << true << (qlonglong)1234; QTest::newRow("ar_SA 1234 0") << QString::fromUtf16(arabic_str) << 0 << false << (qlonglong)0;
QTest::newRow("ar_SA 1234 8") << QString("ar_SA") << QString::fromUtf16(arabic_str) << 8 << true << (qlonglong)668;
QTest::newRow("ar_SA 1234 10") << QString("ar_SA") << QString::fromUtf16(arabic_str) << 10 << true << (qlonglong)1234;
QTest::newRow("ar_SA 1234 16") << QString("ar_SA") << QString::fromUtf16(arabic_str) << 16 << true << (qlonglong)4660;
} }
void tst_QString::integer_conversion() void tst_QString::integer_conversion()
{ {
QFETCH(QString, locale_name);
QFETCH(QString, num_str); QFETCH(QString, num_str);
QFETCH(int, base); QFETCH(int, base);
QFETCH(bool, good); QFETCH(bool, good);
QFETCH(qlonglong, num); QFETCH(qlonglong, num);
QLocale::setDefault(locale_name);
QCOMPARE(QLocale().name(), locale_name);
bool ok; bool ok;
qlonglong d = num_str.toLongLong(&ok, base); qlonglong d = num_str.toLongLong(&ok, base);
QCOMPARE(ok, good); QCOMPARE(ok, good);
@ -4097,100 +4073,65 @@ void tst_QString::integer_conversion()
if (ok) { if (ok) {
QCOMPARE(d, num); QCOMPARE(d, num);
} }
QLocale::setDefault(QLocale::C);
} }
void tst_QString::double_conversion_data() void tst_QString::double_conversion_data()
{ {
QTest::addColumn<QString>("locale_name");
QTest::addColumn<QString>("num_str"); QTest::addColumn<QString>("num_str");
QTest::addColumn<bool>("good"); QTest::addColumn<bool>("good");
QTest::addColumn<double>("num"); QTest::addColumn<double>("num");
// The good... // The good...
QTest::newRow("C 1") << QString("C") << QString("1") << true << 1.0; QTest::newRow("C 1") << QString("1") << true << 1.0;
QTest::newRow("C 1.0") << QString("C") << QString("1.0") << true << 1.0; QTest::newRow("C 1.0") << QString("1.0") << true << 1.0;
QTest::newRow("C 1.234") << QString("C") << QString("1.234") << true << 1.234; QTest::newRow("C 1.234") << QString("1.234") << true << 1.234;
QTest::newRow("C 1.234e-10") << QString("C") << QString("1.234e-10") << true << 1.234e-10; QTest::newRow("C 1.234e-10") << QString("1.234e-10") << true << 1.234e-10;
QTest::newRow("C 1.234E10") << QString("C") << QString("1.234E10") << true << 1.234e10; QTest::newRow("C 1.234E10") << QString("1.234E10") << true << 1.234e10;
QTest::newRow("C 1e10") << QString("C") << QString("1e10") << true << 1.0e10; QTest::newRow("C 1e10") << QString("1e10") << true << 1.0e10;
// The bad... // The bad...
QTest::newRow("C empty") << QString("C") << QString("") << false << 0.0; QTest::newRow("C empty") << QString("") << false << 0.0;
QTest::newRow("C null") << QString("C") << QString() << false << 0.0; QTest::newRow("C null") << QString() << false << 0.0;
QTest::newRow("C .") << QString("C") << QString(".") << false << 0.0; QTest::newRow("C .") << QString(".") << false << 0.0;
QTest::newRow("C 1e") << QString("C") << QString("1e") << false << 0.0; QTest::newRow("C 1e") << QString("1e") << false << 0.0;
QTest::newRow("C 1,") << QString("C") << QString("1,") << false << 0.0; QTest::newRow("C 1,") << QString("1,") << false << 0.0;
QTest::newRow("C 1,0") << QString("C") << QString("1,0") << false << 0.0; QTest::newRow("C 1,0") << QString("1,0") << false << 0.0;
QTest::newRow("C 1,000") << QString("C") << QString("1,000") << false << 0.0; QTest::newRow("C 1,000") << QString("1,000") << false << 0.0;
QTest::newRow("C 1e1.0") << QString("C") << QString("1e1.0") << false << 0.0; QTest::newRow("C 1e1.0") << QString("1e1.0") << false << 0.0;
QTest::newRow("C 1e+") << QString("C") << QString("1e+") << false << 0.0; QTest::newRow("C 1e+") << QString("1e+") << false << 0.0;
QTest::newRow("C 1e-") << QString("C") << QString("1e-") << false << 0.0; QTest::newRow("C 1e-") << QString("1e-") << false << 0.0;
QTest::newRow("de_DE 1,0") << QString("1,0") << false << 0.0;
QTest::newRow("de_DE 1,234") << QString("1,234") << false << 0.0;
QTest::newRow("de_DE 1,234e-10") << QString("1,234e-10") << false << 0.0;
QTest::newRow("de_DE 1,234E10") << QString("1,234E10") << false << 0.0;
// And the ugly... // And the ugly...
QTest::newRow("C .1") << QString("C") << QString(".1") << true << 0.1; QTest::newRow("C .1") << QString(".1") << true << 0.1;
QTest::newRow("C -.1") << QString("C") << QString("-.1") << true << -0.1; QTest::newRow("C -.1") << QString("-.1") << true << -0.1;
QTest::newRow("C 1.") << QString("C") << QString("1.") << true << 1.0; QTest::newRow("C 1.") << QString("1.") << true << 1.0;
QTest::newRow("C 1.E10") << QString("C") << QString("1.E10") << true << 1.0e10; QTest::newRow("C 1.E10") << QString("1.E10") << true << 1.0e10;
QTest::newRow("C 1e+10") << QString("C") << QString("1e+10") << true << 1.0e+10; QTest::newRow("C 1e+10") << QString("1e+10") << true << 1.0e+10;
QTest::newRow("C 1") << QString(" 1") << true << 1.0;
QTest::newRow("de_DE 1") << QString("de_DE") << QString("1") << true << 1.0; QTest::newRow("C 1 ") << QString("1 ") << true << 1.0;
QTest::newRow("de_DE 1.0") << QString("de_DE") << QString("1.0") << true << 1.0;
QTest::newRow("de_DE 1.234") << QString("de_DE") << QString("1.234") << true << 1.234;
QTest::newRow("de_DE 1.234e-10") << QString("de_DE") << QString("1.234e-10") << true << 1.234e-10;
QTest::newRow("de_DE 1.234E10") << QString("de_DE") << QString("1.234E10") << true << 1.234e10;
QTest::newRow("de_DE 1e10") << QString("de_DE") << QString("1e10") << true << 1.0e10;
QTest::newRow("de_DE .1") << QString("de_DE") << QString(".1") << true << 0.1;
QTest::newRow("de_DE -.1") << QString("de_DE") << QString("-.1") << true << -0.1;
QTest::newRow("de_DE 1.") << QString("de_DE") << QString("1.") << true << 1.0;
QTest::newRow("de_DE 1.E10") << QString("de_DE") << QString("1.E10") << true << 1.0e10;
QTest::newRow("de_DE 1e+10") << QString("de_DE") << QString("1e+10") << true << 1.0e+10;
QTest::newRow("de_DE 1,0") << QString("de_DE") << QString("1,0") << true << 1.0;
QTest::newRow("de_DE 1,234") << QString("de_DE") << QString("1,234") << true << 1.234;
QTest::newRow("de_DE 1,234e-10") << QString("de_DE") << QString("1,234e-10") << true << 1.234e-10;
QTest::newRow("de_DE 1,234E10") << QString("de_DE") << QString("1,234E10") << true << 1.234e10;
QTest::newRow("de_DE ,1") << QString("de_DE") << QString(",1") << true << 0.1;
QTest::newRow("de_DE -,1") << QString("de_DE") << QString("-,1") << true << -0.1;
QTest::newRow("de_DE 1,") << QString("de_DE") << QString("1,") << true << 1.0;
QTest::newRow("de_DE 1,E10") << QString("de_DE") << QString("1,E10") << true << 1.0e10;
QTest::newRow("de_DE empty") << QString("de_DE") << QString("") << false << 0.0;
QTest::newRow("de_DE null") << QString("de_DE") << QString() << false << 0.0;
QTest::newRow("de_DE .") << QString("de_DE") << QString(".") << false << 0.0;
QTest::newRow("de_DE 1e") << QString("de_DE") << QString("1e") << false << 0.0;
QTest::newRow("de_DE 1e1.0") << QString("de_DE") << QString("1e1.0") << false << 0.0;
QTest::newRow("de_DE 1e+") << QString("de_DE") << QString("1e+") << false << 0.0;
QTest::newRow("de_DE 1e-") << QString("de_DE") << QString("1e-") << false << 0.0;
QTest::newRow("C 1") << QString("C") << QString(" 1") << true << 1.0;
QTest::newRow("C 1 ") << QString("C") << QString("1 ") << true << 1.0;
QTest::newRow("de_DE 1") << QString("de_DE") << QString(" 1") << true << 1.0;
QTest::newRow("de_DE 1 ") << QString("de_DE") << QString("1 ") << true << 1.0;
// Let's try some Arabic // Let's try some Arabic
const quint16 arabic_str[] = { 0x0660, 0x066B, 0x0661, 0x0662, const quint16 arabic_str[] = { 0x0660, 0x066B, 0x0661, 0x0662,
0x0663, 0x0664, 0x0065, 0x0662, 0x0663, 0x0664, 0x0065, 0x0662,
0x0000 }; // "0.1234e2" 0x0000 }; // "0.1234e2"
QTest::newRow("ar_SA") << QString("ar_SA") << QString::fromUtf16(arabic_str) << true << 0.1234e2; QTest::newRow("ar_SA") << QString::fromUtf16(arabic_str) << false << 0.0;
} }
void tst_QString::double_conversion() void tst_QString::double_conversion()
{ {
#define MY_DOUBLE_EPSILON (2.22045e-16) #define MY_DOUBLE_EPSILON (2.22045e-16)
QFETCH(QString, locale_name);
QFETCH(QString, num_str); QFETCH(QString, num_str);
QFETCH(bool, good); QFETCH(bool, good);
QFETCH(double, num); QFETCH(double, num);
QLocale::setDefault(locale_name);
QCOMPARE(QLocale().name(), locale_name);
bool ok; bool ok;
double d = num_str.toDouble(&ok); double d = num_str.toDouble(&ok);
QCOMPARE(ok, good); QCOMPARE(ok, good);
@ -4201,8 +4142,6 @@ void tst_QString::double_conversion()
diff = -diff; diff = -diff;
QVERIFY(diff <= MY_DOUBLE_EPSILON); QVERIFY(diff <= MY_DOUBLE_EPSILON);
} }
QLocale::setDefault(QLocale::C);
} }
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN