Skip to content

Commit bc1ce97

Browse files
authored
Merge pull request xbmc#27530 from CrystalP/fix-langcodeexpander
[i18n] Fix LangCodeExpander Bugs
2 parents b6a12d4 + c786669 commit bc1ce97

File tree

2 files changed

+61
-36
lines changed

2 files changed

+61
-36
lines changed

xbmc/utils/LangCodeExpander.cpp

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,32 @@ bool CLangCodeExpander::ConvertToISO6392B(const std::string& strCharCode,
148148
std::string charCode(strCharCode);
149149
StringUtils::ToLower(charCode);
150150

151-
if (std::ranges::binary_search(LanguageCodesByIso639_2b, charCode, {}, &ISO639::iso639_2b) ||
152-
(checkWin32Locales &&
153-
std::ranges::binary_search(LanguageCodesByWin_Id, charCode, {}, &ISO639::win_id)) ||
154-
CIso3166_1::ContainsAlpha3(charCode))
151+
if (std::ranges::binary_search(LanguageCodesByIso639_2b, charCode, {}, &ISO639::iso639_2b))
152+
{
153+
strISO6392B = charCode;
154+
return true;
155+
}
156+
157+
if (const auto bCode{CIso639_2::TCodeToBCode(charCode)}; bCode.has_value())
158+
{
159+
strISO6392B = bCode.value();
160+
return true;
161+
}
162+
163+
if (checkWin32Locales)
164+
{
165+
const auto it =
166+
std::ranges::lower_bound(LanguageCodesByWin_Id, charCode, {}, &ISO639::win_id);
167+
if (it != LanguageCodesByWin_Id.end() && it->win_id == charCode)
168+
{
169+
strISO6392B = it->iso639_2b;
170+
return true;
171+
}
172+
}
173+
174+
// Match against country last to avoid stealing possible matches from previous conditions
175+
//! @todo what's this legacy logic for?
176+
if (CIso3166_1::ContainsAlpha3(charCode))
155177
{
156178
strISO6392B = charCode;
157179
return true;
@@ -173,9 +195,12 @@ bool CLangCodeExpander::ConvertToISO6392B(const std::string& strCharCode,
173195
}
174196

175197
// Try search on language addons
176-
strISO6392B = g_langInfo.ConvertEnglishNameToAddonLocale(strCharCode);
177-
if (!strISO6392B.empty())
198+
if (const std::string addonLang = g_langInfo.ConvertEnglishNameToAddonLocale(strCharCode);
199+
!addonLang.empty())
200+
{
201+
strISO6392B = addonLang;
178202
return true;
203+
}
179204
}
180205
return false;
181206
}
@@ -360,29 +385,25 @@ bool CLangCodeExpander::ReverseLookup(const std::string& desc, std::string& code
360385
}
361386
}
362387

363-
std::string_view name = descTmp;
388+
if (const auto ret = CIso639_1::LookupByName(descTmp); ret.has_value())
364389
{
365-
auto ret = CIso639_1::LookupByName(name);
366-
if (ret)
367-
{
368-
code = *ret;
369-
return true;
370-
}
390+
code = *ret;
391+
return true;
371392
}
393+
394+
if (const auto ret = CIso639_2::LookupByName(descTmp); ret.has_value())
372395
{
373-
auto ret = CIso639_2::LookupByName(name);
374-
if (ret)
375-
{
376-
code = *ret;
377-
return true;
378-
}
396+
code = *ret;
397+
return true;
379398
}
380399

381400
// Find on language addons
382-
code = g_langInfo.ConvertEnglishNameToAddonLocale(descTmp);
383-
if (!code.empty())
401+
if (const std::string addonLang = g_langInfo.ConvertEnglishNameToAddonLocale(descTmp);
402+
!addonLang.empty())
403+
{
404+
code = addonLang;
384405
return true;
385-
406+
}
386407
return false;
387408
}
388409

xbmc/utils/test/TestLangCodeExpander.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,36 @@ TEST(TestLangCodeExpander, ConvertToISO6392B)
5151
std::string refstr;
5252
std::string varstr;
5353

54+
// ISO 639-2 with identical B and T forms
5455
refstr = "eng";
5556
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("en", varstr));
5657
EXPECT_EQ(refstr, varstr);
5758

5859
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("eng", varstr));
5960
EXPECT_EQ(refstr, varstr);
6061

62+
// ISO 639-2/B
63+
refstr = "fre";
64+
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("fre", varstr));
65+
EXPECT_EQ(refstr, varstr);
66+
67+
// ISO 639-2/T
68+
refstr = "cze";
69+
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("ces", varstr));
70+
EXPECT_EQ(refstr, varstr);
71+
6172
// win_id != iso639_2b
62-
refstr = "fra";
73+
refstr = "fre";
6374
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("fra", varstr, true));
6475
EXPECT_EQ(refstr, varstr);
6576

77+
//! \todo analyze, v.suspicious. What old situation required matching languages with regions?
6678
// Region code
6779
refstr = "bol";
6880
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("bol", varstr));
6981
EXPECT_EQ(refstr, varstr);
7082

71-
// non existent
83+
// non-existent or non-convertible
7284
refstr = "invalid";
7385
varstr = "invalid";
7486
EXPECT_FALSE(g_LangCodeExpander.ConvertToISO6392B("ac", varstr));
@@ -77,6 +89,9 @@ TEST(TestLangCodeExpander, ConvertToISO6392B)
7789
EXPECT_FALSE(g_LangCodeExpander.ConvertToISO6392B("aaa", varstr));
7890
EXPECT_EQ(refstr, varstr);
7991

92+
EXPECT_FALSE(g_LangCodeExpander.ConvertToISO6392B("en-US", varstr));
93+
EXPECT_EQ(refstr, varstr);
94+
8095
// Full english name, case insensitive
8196
refstr = "eng";
8297
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("English", varstr, true));
@@ -85,11 +100,6 @@ TEST(TestLangCodeExpander, ConvertToISO6392B)
85100
refstr = "eng";
86101
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("english", varstr, true));
87102
EXPECT_EQ(refstr, varstr);
88-
89-
// Existing bug
90-
//refstr = "ger";
91-
//EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392B("deu", varstr));
92-
//EXPECT_EQ(refstr, varstr);
93103
}
94104

95105
TEST(TestLangCodeExpander, ConvertToISO6391)
@@ -166,13 +176,7 @@ TEST(TestLangCodeExpander, ConvertToISO6392T)
166176
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392T("deu", varstr, true));
167177
EXPECT_EQ(refstr, varstr);
168178

169-
// Should return deu instead of failing. Side effect of failure in Convert but maybe happens for historical reasons and something
170-
// relies on that.
171-
// For some reason, the function allows the language code to match with the region 'deu',
172-
// but since it's not a valid ISO639-2/B code, it cannot be translated to its ISO-639-2/T code
173-
refstr = "invalid";
174-
varstr = "invalid";
175-
EXPECT_FALSE(g_LangCodeExpander.ConvertToISO6392T("deu", varstr));
179+
EXPECT_TRUE(g_LangCodeExpander.ConvertToISO6392T("deu", varstr));
176180
EXPECT_EQ(refstr, varstr);
177181
}
178182

0 commit comments

Comments
 (0)