diff options
Diffstat (limited to 'src/corelib/tools/qlocale.cpp')
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 121 |
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; } |