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 <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2025-01-09 19:03:02 +01:00
parent 2c39365aad
commit 7f9ee43de7
2 changed files with 56 additions and 25 deletions

View File

@ -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:
id.script_id = 0;
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;
// 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)

View File

@ -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,
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, u"de-Latn"_s};
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