From 7f9ee43de783105d8de0a0b614751eec639131f8 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 9 Jan 2025 19:03:02 +0100 Subject: [PATCH] Include more pruned likely-equivalent entries in QLocale::uiLanguages We were including, for each entry we got from CLDR or the system, minimal and maximal additions from CLDR's likely-subtag rules, plus versions with script omitted and possibly also territory added, when likely-equivalent to the original. Include also the converse, with territory omitted and possibly also script added when likely-equivalent, so as to control order when these entries also show up by truncation of others. Pick-to: 6.9 Task-number: QTBUG-131894 Change-Id: I363bfe31867be43807fe3b4942dafa186b8d2e94 Reviewed-by: Thiago Macieira --- src/corelib/text/qlocale.cpp | 35 ++++++++++++-- .../auto/corelib/text/qlocale/tst_qlocale.cpp | 46 ++++++++++--------- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index d979d37259c..2bc012a8160 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -5082,19 +5082,48 @@ QStringList QLocale::uiLanguages(TagSeparator separator) const else if (!isSystem && min == id) --j; // Put more specific forms *before* minimal entry. + // Include various stripped-down versions when likely-equivalent and distinct: if (id.script_id) { - // Include scriptless version if likely-equivalent and distinct: + if (const ushort land = id.territory_id) { + // Keep script, omit territory: + id.territory_id = 0; + if (id != min && id.withLikelySubtagsAdded() == max) { + if (const QByteArray name = id.name(sep); name != prior) + uiLanguages.insert(j, QString::fromLatin1(name)); + } + id.territory_id = land; + } + // Omit script (keep territory if present): id.script_id = 0; - if (id != min && id.withLikelySubtagsAdded() == max) { + // Belongs before script-without-territory, even if it duplicates min: + if (id.withLikelySubtagsAdded() == max) { if (const QByteArray name = id.name(sep); name != prior) uiLanguages.insert(j, QString::fromLatin1(name)); } + } else { + id.script_id = max.script_id; + if (const ushort land = id.territory_id) { + // Supply script and omit territory: + id.territory_id = 0; + if (id != min && id.withLikelySubtagsAdded() == max) { + if (const QByteArray name = id.name(sep); name != prior) + uiLanguages.insert(j, QString::fromLatin1(name)); + } + id.territory_id = land; + } + // Supply script (keep territory, if present): + if (id != max && id.withLikelySubtagsAdded() == max) { + if (const QByteArray name = id.name(sep); name != prior) + uiLanguages.insert(j, QString::fromLatin1(name)); + } + // Restore to clear: + id.script_id = 0; } if (!id.territory_id) { + // Supply territory, omit script: Q_ASSERT(!min.territory_id); Q_ASSERT(!id.script_id); // because we just cleared it. - // Include version with territory if likely-equivalent and distinct: id.territory_id = max.territory_id; if (id != max && id.withLikelySubtagsAdded() == max) { if (const QByteArray name = id.name(sep); name != prior) diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 6b540a562fd..a964134b0c8 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -3688,10 +3688,10 @@ void tst_QLocale::uiLanguages_data() QTest::newRow("C") << QLocale::c() << QStringList{u"C"_s}; QTest::newRow("en_US") - << QLocale("en_US") << QStringList{u"en-Latn-US"_s, u"en-US"_s, u"en"_s, u"en-Latn"_s}; + << QLocale("en_US") << QStringList{u"en-Latn-US"_s, u"en-US"_s, u"en-Latn"_s, u"en"_s}; QTest::newRow("en_Latn_US") << QLocale("en_Latn_US") // Specifying the default script makes no difference - << QStringList{u"en-Latn-US"_s, u"en-US"_s, u"en"_s, u"en-Latn"_s}; + << QStringList{u"en-Latn-US"_s, u"en-US"_s, u"en-Latn"_s, u"en"_s}; QTest::newRow("en_GB") << QLocale("en_GB") << QStringList{u"en-Latn-GB"_s, u"en-GB"_s, u"en-Latn"_s, u"en"_s}; @@ -3699,7 +3699,7 @@ void tst_QLocale::uiLanguages_data() << QLocale("en_Dsrt_US") << QStringList{u"en-Dsrt-US"_s, u"en-Dsrt"_s, u"en"_s}; QTest::newRow("ru_RU") - << QLocale("ru_RU") << QStringList{u"ru-Cyrl-RU"_s, u"ru-RU"_s, u"ru"_s, u"ru-Cyrl"_s}; + << QLocale("ru_RU") << QStringList{u"ru-Cyrl-RU"_s, u"ru-RU"_s, u"ru-Cyrl"_s, u"ru"_s}; QTest::newRow("zh_Hant") << QLocale("zh_Hant") @@ -3710,13 +3710,13 @@ void tst_QLocale::uiLanguages_data() QTest::newRow("zh_Hans_CN") << QLocale(QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China) - << QStringList{u"zh-Hans-CN"_s, u"zh-CN"_s, u"zh"_s, u"zh-Hans"_s}; + << QStringList{u"zh-Hans-CN"_s, u"zh-CN"_s, u"zh-Hans"_s, u"zh"_s}; // GB has no native Punjabi locales, so is eliminated by likely subtag rules: QTest::newRow("pa_IN") - << QLocale("pa_IN") << QStringList{u"pa-Guru-IN"_s, u"pa-IN"_s, u"pa"_s, u"pa-Guru"_s}; + << QLocale("pa_IN") << QStringList{u"pa-Guru-IN"_s, u"pa-IN"_s, u"pa-Guru"_s, u"pa"_s}; QTest::newRow("pa_GB") - << QLocale("pa_GB") << QStringList{u"pa-Guru-IN"_s, u"pa-IN"_s, u"pa"_s, u"pa-Guru"_s}; + << QLocale("pa_GB") << QStringList{u"pa-Guru-IN"_s, u"pa-IN"_s, u"pa-Guru"_s, u"pa"_s}; QTest::newRow("pa_PK") << QLocale("pa_PK") << QStringList{u"pa-Arab-PK"_s, u"pa-PK"_s, u"pa-Arab"_s, u"pa"_s}; QTest::newRow("pa_Arab_GB") @@ -4150,11 +4150,12 @@ void tst_QLocale::mySystemLocale_data() QTest::addRow("empty") << u"no-US"_s << QLocale::NorwegianBokmal << QStringList{u"nb-US"_s, u"nb-Latn-US"_s, - u"nb-Latn-NO"_s, u"nb-NO"_s, u"nb"_s, u"nb-Latn"_s}; + u"nb-Latn-NO"_s, u"nb-NO"_s, u"nb-Latn"_s, u"nb"_s}; QTest::addRow("no") // QTBUG-131127 << u"no"_s << QLocale::NorwegianBokmal - << QStringList{u"no"_s, u"nb-Latn-NO"_s, u"nb-NO"_s, u"en-US"_s, u"en-Latn-US"_s, u"en"_s, - u"nb"_s, u"nb-Latn"_s, u"en-Latn"_s}; + << QStringList{u"no"_s, u"nb-Latn-NO"_s, u"nb-NO"_s, u"nb-Latn"_s, + u"en-US"_s, u"en-Latn-US"_s, u"en-Latn"_s, u"en"_s, + u"nb"_s}; QTest::addRow("en-Latn") // Android crash << u"en-Latn"_s << QLocale::English << QStringList{u"en-Latn"_s, u"en-Latn-US"_s, u"en-US"_s, u"en"_s, @@ -4163,16 +4164,15 @@ void tst_QLocale::mySystemLocale_data() QTest::addRow("anglo-dutch-GB") << u"en-NL-GB"_s << QLocale::English << QStringList{u"en-NL"_s, u"en-Latn-NL"_s, - u"nl-NL"_s, u"nl-Latn-NL"_s, u"nl"_s, - u"en-GB"_s, u"en-Latn-GB"_s, - u"en-Latn"_s, u"en"_s, u"nl-Latn"_s}; + u"nl-NL"_s, u"nl-Latn-NL"_s, u"nl-Latn"_s, u"nl"_s, + u"en-GB"_s, u"en-Latn-GB"_s, u"en-Latn"_s, u"en"_s}; QTest::addRow("catalan") << u"ca"_s << QLocale::Catalan << QStringList{u"ca"_s, u"ca-Latn-ES"_s, u"ca-ES"_s, u"ca-Latn"_s}; QTest::addRow("catalan-spain") << u"ca-ES"_s << QLocale::Catalan - << QStringList{u"ca-ES"_s, u"ca-Latn-ES"_s, u"ca"_s, u"ca-Latn"_s}; + << QStringList{u"ca-ES"_s, u"ca-Latn-ES"_s, u"ca-Latn"_s, u"ca"_s}; QTest::addRow("catalan-latin") << u"ca-Latn"_s << QLocale::Catalan << QStringList{u"ca-Latn"_s, u"ca-Latn-ES"_s, u"ca-ES"_s, u"ca"_s}; @@ -4185,9 +4185,9 @@ void tst_QLocale::mySystemLocale_data() // First two were missed out before fix to QTBUG-104930: << QStringList{u"en-DE"_s, u"en-Latn-DE"_s, u"en-GB"_s, u"en-Latn-GB"_s, - u"de-DE"_s, u"de-Latn-DE"_s, u"de"_s, - // Fallbacks implied by those: - u"en-Latn"_s, u"en"_s, u"de-Latn"_s}; + u"de-DE"_s, u"de-Latn-DE"_s, u"de-Latn"_s, u"de"_s, + // Fallbacks implied by those: + u"en-Latn"_s, u"en"_s}; QTest::addRow("german") << u"de"_s << QLocale::German @@ -4200,7 +4200,7 @@ void tst_QLocale::mySystemLocale_data() << QStringList{u"zh"_s, u"zh-Hans-CN"_s, u"zh-CN"_s, u"zh-Hans"_s}; QTest::addRow("chinese-full") << u"zh-Hans-CN"_s << QLocale::Chinese - << QStringList{u"zh-Hans-CN"_s, u"zh-CN"_s, u"zh"_s, u"zh-Hans"_s}; + << QStringList{u"zh-Hans-CN"_s, u"zh-CN"_s, u"zh-Hans"_s, u"zh"_s}; QTest::addRow("chinese-taiwan") << u"zh-TW"_s << QLocale::Chinese << QStringList{u"zh-TW"_s, u"zh-Hant-TW"_s, u"zh-Hant"_s, u"zh"_s}; @@ -4225,17 +4225,19 @@ void tst_QLocale::mySystemLocale_data() << u"en-FO"_s << QLocale::English << QStringList{u"en-FO"_s, u"en-Latn-FO"_s, u"en-DK"_s, u"en-Latn-DK"_s, u"en-GB"_s, u"en-Latn-GB"_s, - u"fo-FO"_s, u"fo-Latn-FO"_s, u"fo"_s, - u"da-FO"_s, u"da-Latn-FO"_s, u"da-DK"_s, u"da-Latn-DK"_s, u"da"_s, + u"fo-FO"_s, u"fo-Latn-FO"_s, u"fo-Latn"_s, u"fo"_s, + u"da-FO"_s, u"da-Latn-FO"_s, + u"da-DK"_s, u"da-Latn-DK"_s, u"da-Latn"_s, u"da"_s, // Fallbacks implied by those: - u"en-Latn"_s, u"en"_s, u"fo-Latn"_s, u"da-Latn"_s}; + u"en-Latn"_s, u"en"_s}; QTest::newRow("polylingual-CA") << u"de-CA"_s << QLocale::German << QStringList{u"de-CA"_s, u"de-Latn-CA"_s, u"en-CA"_s, u"en-Latn-CA"_s, u"fr-CA"_s, u"fr-Latn-CA"_s, u"de-AT"_s, u"de-Latn-AT"_s, - u"en-GB"_s, u"en-Latn-GB"_s, u"fr-FR"_s, u"fr-Latn-FR"_s, u"fr"_s, + u"en-GB"_s, u"en-Latn-GB"_s, + u"fr-FR"_s, u"fr-Latn-FR"_s, u"fr-Latn"_s, u"fr"_s, // Fallbacks: - u"de-Latn"_s, u"de"_s, u"en-Latn"_s, u"en"_s, u"fr-Latn"_s}; + u"de-Latn"_s, u"de"_s, u"en-Latn"_s, u"en"_s}; QTest::newRow("und-US") << u"und-US"_s << QLocale::C