aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike FABIAN <mike.fabian@basyskom.de>2010-12-09 16:01:17 +0100
committerMike FABIAN <mike.fabian@basyskom.de>2010-12-13 09:35:53 +0100
commita224ad495f958d538ed48df7c4c33bd7d8207608 (patch)
tree43fa9f3ae34797c4fb8564ab659660dc7b95e3ea
parentff71b254bfa1c3b8a211d764576cb78dac16a52f (diff)
Changes: make parsing of exponentioal symbols case insensitive
RevBy: John Tapsell, Abhijit Apte Details: see NB#206085 comment#24: Which exponential symbol is used depends on the locale “×10^” sv_SE, Swedisch in Sweden, and is_IS, Icelandic in Iceland, and lt_LT, Lithuanian in Lithuania. “اس” all Arabic locales, e.g. ar_SA, ar_EG, ... “×۱۰^” all Farsi locales (i.e. fa_AF and fa_IR) and ps_AF (Pashto in Afghanistan) “e” el_GR, Greek in Greece, and sl_SI, Slovene in Slovenia “E” *all* other locales. The difference between “e” and “E” seems artificial, parsing was case insensitive in libicu 4.4.1 and suddenly changed to case sensitive in 4.4.2. Make it case insensitive again in MLocale::toDouble() and MLocale::toFloat().
-rw-r--r--src/corelib/i18n/mlocale.cpp28
-rw-r--r--tests/ft_numbers/ft_numbers.cpp167
2 files changed, 181 insertions, 14 deletions
diff --git a/src/corelib/i18n/mlocale.cpp b/src/corelib/i18n/mlocale.cpp
index 5b245795..6d9cb882 100644
--- a/src/corelib/i18n/mlocale.cpp
+++ b/src/corelib/i18n/mlocale.cpp
@@ -1895,12 +1895,20 @@ double MLocale::toDouble(const QString &s, bool *ok) const
}
#ifdef HAVE_ICU
Q_D(const MLocale);
- icu::UnicodeString str = MIcuConversions::qStringToUnicodeString(s);
+ icu::DecimalFormat *decimalFormat
+ = static_cast<icu::DecimalFormat *>(d->_numberFormat);
+ const icu::DecimalFormatSymbols *decimalFormatSymbols
+ = decimalFormat->getDecimalFormatSymbols();
+ QString exponentialSymbol
+ = MIcuConversions::unicodeStringToQString(
+ decimalFormatSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol));
+ QString parseInput = s;
+ // parse the exponential symbol in the input case insensitive:
+ parseInput.replace(exponentialSymbol, exponentialSymbol, Qt::CaseInsensitive);
+ icu::UnicodeString str = MIcuConversions::qStringToUnicodeString(parseInput);
icu::Formattable formattable;
icu::ParsePosition parsePosition;
double result;
- icu::DecimalFormat *decimalFormat
- = static_cast<icu::DecimalFormat *>(d->_numberFormat);
if (decimalFormat->isParseIntegerOnly()) {
decimalFormat->setParseIntegerOnly(false);
decimalFormat->parse(str, formattable, parsePosition);
@@ -1956,12 +1964,20 @@ float MLocale::toFloat(const QString &s, bool *ok) const
}
#ifdef HAVE_ICU
Q_D(const MLocale);
- icu::UnicodeString str = MIcuConversions::qStringToUnicodeString(s);
+ icu::DecimalFormat *decimalFormat
+ = static_cast<icu::DecimalFormat *>(d->_numberFormat);
+ const icu::DecimalFormatSymbols *decimalFormatSymbols
+ = decimalFormat->getDecimalFormatSymbols();
+ QString exponentialSymbol
+ = MIcuConversions::unicodeStringToQString(
+ decimalFormatSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol));
+ QString parseInput = s;
+ // parse the exponential symbol in the input case insensitive:
+ parseInput.replace(exponentialSymbol, exponentialSymbol, Qt::CaseInsensitive);
+ icu::UnicodeString str = MIcuConversions::qStringToUnicodeString(parseInput);
icu::Formattable formattable;
icu::ParsePosition parsePosition;
double result;
- icu::DecimalFormat *decimalFormat
- = static_cast<icu::DecimalFormat *>(d->_numberFormat);
if (decimalFormat->isParseIntegerOnly()) {
decimalFormat->setParseIntegerOnly(false);
decimalFormat->parse(str, formattable, parsePosition);
diff --git a/tests/ft_numbers/ft_numbers.cpp b/tests/ft_numbers/ft_numbers.cpp
index d0487252..9a286f40 100644
--- a/tests/ft_numbers/ft_numbers.cpp
+++ b/tests/ft_numbers/ft_numbers.cpp
@@ -1192,6 +1192,157 @@ void Ft_Numbers::testToDouble_data()
<< true
<< double(1234567.1234567)
<< QString("1,234,567.1234567");
+ QTest::newRow("en_GB f4")
+ << QString("en_GB")
+ << QString("f4")
+ << false
+ << double(0)
+ << QString("0");
+
+ QTest::newRow("en_GB 4f")
+ << QString("en_GB")
+ << QString("4f")
+ << false
+ << double(0)
+ << QString("0");
+
+ QTest::newRow("en_GB 1E+9")
+ << QString("en_GB")
+ << QString("1E+9")
+ << true
+ << double(1.0E+9)
+ << QString("1,000,000,000");
+
+ if (icuPackageVersion < "4.4.2-0maemo3") {
+ qDebug() << "NB#206085 not yet fixed, some exponents parsed wrong.";
+ QTest::newRow("en_GB 1E+10")
+ << QString("en_GB")
+ << QString("1E+10")
+ << true
+ << double(0)
+ << QString("0");
+ }
+ else {
+ qDebug() << "NB#206085 fixed, exponent parsing corrected.";
+ QTest::newRow("en_GB 1E+10")
+ << QString("en_GB")
+ << QString("1E+10")
+ << true
+ << double(1.0E+10)
+ << QString("10,000,000,000");
+
+ QTest::newRow("en_GB 1E+10")
+ << QString("en_GB")
+ << QString("1E+10")
+ << true // exponential symbol is case insensitive now.
+ << double(1E+10)
+ << QString("10,000,000,000");
+
+ QTest::newRow("en_GB 1e+10")
+ << QString("en_GB")
+ << QString("1e+10")
+ << true // exponential symbol is case insensitive now.
+ << double(1e+10)
+ << QString("10,000,000,000");
+
+ QTest::newRow("el_GR 1E+10")
+ << QString("el_GR")
+ << QString("1E+10")
+ << true // exponential symbol is case insensitive now.
+ << double(1e+10)
+ << QString("10.000.000.000");
+
+ QTest::newRow("el_GR 1e+10")
+ << QString("el_GR")
+ << QString("1e+10")
+ << true // exponential symbol is case insensitive now.
+ << double(1E+10)
+ << QString("10.000.000.000");
+
+ QTest::newRow("sv_SE 1E+10")
+ << QString("sv_SE")
+ << QString("1E+10")
+ << false // OK not to parse this in Swedish?
+ << double(0)
+ << QString("0");
+
+ QTest::newRow("sv_SE 1e+10")
+ << QString("sv_SE")
+ << QString("1e+10")
+ << false // OK not to parse this in Swedish?
+ << double(0)
+ << QString("0");
+
+ QTest::newRow("sv_SE 1×10^10")
+ << QString("sv_SE")
+ << QString("1×10^10")
+ << true
+ << double(1E+10)
+ << QString("10 000 000 000");
+
+ QTest::newRow("ar_SA ١اس+١٠") // ar_SA does not use thousands separators
+ << QString("ar_SA")
+ << QString("١اس+١٠")
+ << true
+ << double(1E+10)
+ << QString("١٠٠٠٠٠٠٠٠٠٠");
+
+ QTest::newRow("ar_SA ١٠٠٠") // ar_SA does not use thousands separators
+ << QString("ar_SA")
+ << QString("١٠٠٠")
+ << true
+ << double(1000.0)
+ << QString("١٠٠٠");
+
+ QTest::newRow("ar_SA ١٬٠٠٠") // ar_SA does not use thousands separators
+ << QString("ar_SA")
+ << QString("١٬٠٠٠")
+ << false
+ << double(0.0)
+ << QString("٠");
+
+ QTest::newRow("ar_EG ١اس+١٠") // ar_EG does not use thousands separators
+ << QString("ar_EG")
+ << QString("١اس+١٠")
+ << true
+ << double(1E+10)
+ << QString("١٠٬٠٠٠٬٠٠٠٬٠٠٠");
+
+ QTest::newRow("ar_EG ١٠٠٠") // ar_EG does not use thousands separators
+ << QString("ar_EG")
+ << QString("١٠٠٠")
+ << true
+ << double(1000.0)
+ << QString("١٬٠٠٠");
+
+ QTest::newRow("ar_EG ١٬٠٠٠") // ar_EG does not use thousands separators
+ << QString("ar_EG")
+ << QString("١٬٠٠٠")
+ << true
+ << double(1000.0)
+ << QString("١٬٠٠٠");
+
+ QTest::newRow("fa_IR ١×۱۰^١۰")
+ << QString("fa_IR")
+ << QString("۱×۱۰^۱۰")
+ << true
+ << double(1E+10)
+ << QString("۱۰٬۰۰۰٬۰۰۰٬۰۰۰");
+
+ QTest::newRow("fa_IR ۱۰۰۰")
+ << QString("fa_IR")
+ << QString("۱۰۰۰")
+ << true
+ << double(1000.0)
+ << QString("۱٬۰۰۰");
+
+ QTest::newRow("fa_IR ۱٬۰۰۰")
+ << QString("fa_IR")
+ << QString("۱٬۰۰۰")
+ << true
+ << double(1000.0)
+ << QString("۱٬۰۰۰");
+ }
QTest::newRow("de_DE 1234.56")
<< QString("de_DE")
@@ -1652,28 +1803,28 @@ void Ft_Numbers::testToFloat_data()
QTest::newRow("en_GB 1E+10")
<< QString("en_GB")
<< QString("1E+10")
- << true // should this really be case sensitive??
+ << true // exponential symbol is case insensitive now.
<< float(1E+10)
<< QString("10,000,000,000");
QTest::newRow("en_GB 1e+10")
<< QString("en_GB")
<< QString("1e+10")
- << false // should this really be case sensitive??
- << float(0)
- << QString("0");
+ << true // exponential symbol is case insensitive now.
+ << float(1e+10)
+ << QString("10,000,000,000");
QTest::newRow("el_GR 1E+10")
<< QString("el_GR")
<< QString("1E+10")
- << false // should this really be case sensitive??
- << float(0)
- << QString("0");
+ << true // exponential symbol is case insensitive now.
+ << float(1e+10)
+ << QString("10.000.000.000");
QTest::newRow("el_GR 1e+10")
<< QString("el_GR")
<< QString("1e+10")
- << true // should this really be case sensitive??
+ << true // exponential symbol is case insensitive now.
<< float(1E+10)
<< QString("10.000.000.000");