From b33042507bbccacc0b31be4415613a124e18d9ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Thu, 8 Aug 2019 10:15:55 +0200 Subject: Translation: Fix logic bug finding match for regional locales The match test was inverted. The rest of the changes are documentation and cleanup. Fixes #26346 and fixes #31192. --- core/translation.cpp | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'core') diff --git a/core/translation.cpp b/core/translation.cpp index 0b55badc61..a3ff971f45 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -1044,6 +1044,13 @@ StringName TranslationServer::translate(const StringName &p_message) const { if (!enabled) return p_message; + // Locale can be of the form 'll_CC', i.e. language code and regional code, + // e.g. 'en_US', 'en_GB', etc. It might also be simply 'll', e.g. 'en'. + // To find the relevant translation, we look for those with locale starting + // with the language code, and then if any is an exact match for the long + // form. If not found, we fall back to a near match (another locale with + // same language code). + StringName res; bool near_match = false; const CharType *lptr = &locale[0]; @@ -1053,13 +1060,11 @@ StringName TranslationServer::translate(const StringName &p_message) const { const Ref &t = E->get(); String l = t->get_locale(); if (lptr[0] != l[0] || lptr[1] != l[1]) - continue; // locale not match - - //near match - bool match = (l != locale); + continue; // Language code does not match. - if (near_match && !match) - continue; //only near-match once + bool exact_match = (l == locale); + if (!exact_match && near_match) + continue; // Only near-match once, but keep looking for exact matches. StringName r = t->get_message(p_message); @@ -1068,43 +1073,38 @@ StringName TranslationServer::translate(const StringName &p_message) const { res = r; - if (match) + if (exact_match) break; else near_match = true; } - if (!res) { - //try again with fallback - if (fallback.length() >= 2) { - - const CharType *fptr = &fallback[0]; - near_match = false; - for (const Set >::Element *E = translations.front(); E; E = E->next()) { + if (!res && fallback.length() >= 2) { + // Try again with the fallback locale. + const CharType *fptr = &fallback[0]; + near_match = false; + for (const Set >::Element *E = translations.front(); E; E = E->next()) { - const Ref &t = E->get(); - String l = t->get_locale(); - if (fptr[0] != l[0] || fptr[1] != l[1]) - continue; // locale not match + const Ref &t = E->get(); + String l = t->get_locale(); + if (fptr[0] != l[0] || fptr[1] != l[1]) + continue; // Language code does not match. - //near match - bool match = (l != fallback); + bool exact_match = (l == fallback); + if (!exact_match && near_match) + continue; // Only near-match once, but keep looking for exact matches. - if (near_match && !match) - continue; //only near-match once + StringName r = t->get_message(p_message); - StringName r = t->get_message(p_message); + if (!r) + continue; - if (!r) - continue; + res = r; - res = r; - - if (match) - break; - else - near_match = true; - } + if (exact_match) + break; + else + near_match = true; } } -- cgit v1.2.3