summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlocale.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qlocale.cpp')
-rw-r--r--src/corelib/tools/qlocale.cpp121
1 files changed, 76 insertions, 45 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 89896cdc60..b285e58779 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -83,7 +83,6 @@ public:
};
Q_GLOBAL_STATIC(QSystemLocaleSingleton, QSystemLocale_globalSystemLocale)
-static QLocaleData *system_data = 0;
static QLocaleData globalLocaleData;
#endif
@@ -233,14 +232,6 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
if (addLikelySubtags(id))
return id;
}
- // language_script
- if (country_id) {
- QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
- if (addLikelySubtags(id)) {
- id.country_id = country_id;
- return id;
- }
- }
// language_region
if (script_id) {
QLocaleId id = QLocaleId::fromIds(language_id, 0, country_id);
@@ -249,6 +240,14 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
return id;
}
}
+ // language_script
+ if (country_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.country_id = country_id;
+ return id;
+ }
+ }
// language
if (script_id && country_id) {
QLocaleId id = QLocaleId::fromIds(language_id, 0, 0);
@@ -258,6 +257,14 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
return id;
}
}
+ // und_script
+ if (language_id) {
+ QLocaleId id = QLocaleId::fromIds(0, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.language_id = language_id;
+ return id;
+ }
+ }
return *this;
}
@@ -382,6 +389,13 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca
QList<QLocaleId> tried;
tried.push_back(likelyId);
+ // No match; try again with raw data:
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+
// No match; try again with likely country
if (country != QLocale::AnyCountry
&& (language != QLocale::AnyLanguage || script != QLocale::AnyScript)) {
@@ -614,8 +628,7 @@ QSystemLocale::QSystemLocale()
{
_systemLocale = this;
- if (system_data)
- system_data->m_language_id = 0;
+ globalLocaleData.m_language_id = 0;
}
/*!
@@ -632,8 +645,7 @@ QSystemLocale::~QSystemLocale()
if (_systemLocale == this) {
_systemLocale = 0;
- if (system_data)
- system_data->m_language_id = 0;
+ globalLocaleData.m_language_id = 0;
}
}
@@ -646,48 +658,47 @@ static const QSystemLocale *systemLocale()
void QLocalePrivate::updateSystemPrivate()
{
+ // this function is NOT thread-safe!
const QSystemLocale *sys_locale = systemLocale();
- if (!system_data)
- system_data = &globalLocaleData;
// tell the object that the system locale has changed.
sys_locale->query(QSystemLocale::LocaleChanged, QVariant());
- *system_data = *sys_locale->fallbackUiLocale().d->m_data;
+ globalLocaleData = *sys_locale->fallbackUiLocale().d->m_data;
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull()) {
- system_data->m_language_id = res.toInt();
- system_data->m_script_id = QLocale::AnyScript; // default for compatibility
+ globalLocaleData.m_language_id = res.toInt();
+ globalLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
}
res = sys_locale->query(QSystemLocale::CountryId, QVariant());
if (!res.isNull()) {
- system_data->m_country_id = res.toInt();
- system_data->m_script_id = QLocale::AnyScript; // default for compatibility
+ globalLocaleData.m_country_id = res.toInt();
+ globalLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
}
res = sys_locale->query(QSystemLocale::ScriptId, QVariant());
if (!res.isNull())
- system_data->m_script_id = res.toInt();
+ globalLocaleData.m_script_id = res.toInt();
res = sys_locale->query(QSystemLocale::DecimalPoint, QVariant());
if (!res.isNull())
- system_data->m_decimal = res.toString().at(0).unicode();
+ globalLocaleData.m_decimal = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::GroupSeparator, QVariant());
if (!res.isNull())
- system_data->m_group = res.toString().at(0).unicode();
+ globalLocaleData.m_group = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant());
if (!res.isNull())
- system_data->m_zero = res.toString().at(0).unicode();
+ globalLocaleData.m_zero = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::NegativeSign, QVariant());
if (!res.isNull())
- system_data->m_minus = res.toString().at(0).unicode();
+ globalLocaleData.m_minus = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::PositiveSign, QVariant());
if (!res.isNull())
- system_data->m_plus = res.toString().at(0).unicode();
+ globalLocaleData.m_plus = res.toString().at(0).unicode();
}
#endif // !QT_NO_SYSTEMLOCALE
@@ -703,12 +714,12 @@ static const QLocaleData *systemData()
{
static QBasicMutex systemDataMutex;
systemDataMutex.lock();
- if (!system_data || system_data->m_language_id == 0)
+ if (globalLocaleData.m_language_id == 0)
QLocalePrivate::updateSystemPrivate();
systemDataMutex.unlock();
}
- return system_data;
+ return &globalLocaleData;
#else
return locale_data;
#endif
@@ -770,6 +781,8 @@ static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1;
Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePrivate,
(QLocalePrivate::create(defaultData(), default_number_options)))
+Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, systemLocalePrivate,
+ (QLocalePrivate::create(systemData())))
static QLocalePrivate *localePrivateByName(const QString &name)
{
@@ -1174,7 +1187,7 @@ T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok)
// we select the right overload by the last, unused parameter
Int64 val = toIntegral_helper(d->m_data, str, ok, d->m_numberOptions, Int64());
if (T(val) != val) {
- if (ok)
+ if (ok != nullptr)
*ok = false;
val = 0;
}
@@ -2340,7 +2353,9 @@ QString QLocale::toString(double i, char f, int prec) const
QLocale QLocale::system()
{
- return QLocale(*QLocalePrivate::create(systemData()));
+ // this function is NOT thread-safe!
+ QT_PREPEND_NAMESPACE(systemData)(); // trigger updating of the system data if necessary
+ return QLocale(*systemLocalePrivate->data());
}
@@ -3069,7 +3084,7 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q
QVarLengthArray<char> buf(bufSize);
int length;
- doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
+ qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
if (qstrncmp(buf.data(), "inf", 3) == 0 || qstrncmp(buf.data(), "nan", 3) == 0) {
num_str = QString::fromLatin1(buf.data(), length);
@@ -3573,14 +3588,14 @@ double QLocaleData::stringToDouble(QStringView str, bool *ok,
{
CharBuff buff;
if (!numberToCLocale(str, number_options, &buff)) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0.0;
}
int processed = 0;
bool nonNullOk = false;
- double d = asciiToDouble(buff.constData(), buff.length() - 1, nonNullOk, processed);
- if (ok)
+ double d = qt_asciiToDouble(buff.constData(), buff.length() - 1, nonNullOk, processed);
+ if (ok != nullptr)
*ok = nonNullOk;
return d;
}
@@ -3590,7 +3605,7 @@ qlonglong QLocaleData::stringToLongLong(QStringView str, int base, bool *ok,
{
CharBuff buff;
if (!numberToCLocale(str, number_options, &buff)) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
@@ -3603,7 +3618,7 @@ qulonglong QLocaleData::stringToUnsLongLong(QStringView str, int base, bool *ok,
{
CharBuff buff;
if (!numberToCLocale(str, number_options, &buff)) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
@@ -3617,8 +3632,8 @@ double QLocaleData::bytearrayToDouble(const char *num, bool *ok)
int len = static_cast<int>(strlen(num));
Q_ASSERT(len >= 0);
int processed = 0;
- double d = asciiToDouble(num, len, nonNullOk, processed);
- if (ok)
+ double d = qt_asciiToDouble(num, len, nonNullOk, processed);
+ if (ok != nullptr)
*ok = nonNullOk;
return d;
}
@@ -3629,7 +3644,7 @@ qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
const char *endptr;
if (*num == '\0') {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
@@ -3637,19 +3652,24 @@ qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
qlonglong l = qstrtoll(num, &endptr, base, &_ok);
if (!_ok) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
if (*endptr != '\0') {
+ while (ascii_isspace(*endptr))
+ ++endptr;
+ }
+
+ if (*endptr != '\0') {
// we stopped at a non-digit character after converting some digits
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
- if (ok != 0)
+ if (ok != nullptr)
*ok = true;
return l;
}
@@ -3660,13 +3680,24 @@ qulonglong QLocaleData::bytearrayToUnsLongLong(const char *num, int base, bool *
const char *endptr;
qulonglong l = qstrtoull(num, &endptr, base, &_ok);
- if (!_ok || *endptr != '\0') {
- if (ok != 0)
+ if (!_ok) {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ if (*endptr != '\0') {
+ while (ascii_isspace(*endptr))
+ ++endptr;
+ }
+
+ if (*endptr != '\0') {
+ if (ok != nullptr)
*ok = false;
return 0;
}
- if (ok != 0)
+ if (ok != nullptr)
*ok = true;
return l;
}