| 108 | } |
| 109 | |
| 110 | void CLocalizationDatabase::SelectDefaultLanguage(IConsole *pConsole, char *pFilename, size_t Length) const |
| 111 | { |
| 112 | if(Languages().empty()) |
| 113 | return; |
| 114 | if(Languages().size() == 1) |
| 115 | { |
| 116 | str_copy(pFilename, Languages()[0].m_Filename.c_str(), Length); |
| 117 | return; |
| 118 | } |
| 119 | |
| 120 | char aLocaleStr[128]; |
| 121 | os_locale_str(aLocaleStr, sizeof(aLocaleStr)); |
| 122 | |
| 123 | log_info("localization", "Choosing default language based on user locale '%s'", aLocaleStr); |
| 124 | |
| 125 | while(true) |
| 126 | { |
| 127 | const CLanguage *pPrefixMatch = nullptr; |
| 128 | for(const auto &Language : Languages()) |
| 129 | { |
| 130 | for(const auto &LanguageCode : Language.m_vLanguageCodes) |
| 131 | { |
| 132 | if(LanguageCode == aLocaleStr) |
| 133 | { |
| 134 | // Exact match found, use it immediately |
| 135 | str_copy(pFilename, Language.m_Filename.c_str(), Length); |
| 136 | return; |
| 137 | } |
| 138 | else if(LanguageCode.starts_with(aLocaleStr)) |
| 139 | { |
| 140 | // Locale is prefix of language code, e.g. locale is "en" and current language is "en-US" |
| 141 | pPrefixMatch = &Language; |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | // Use prefix match if no exact match was found |
| 146 | if(pPrefixMatch) |
| 147 | { |
| 148 | str_copy(pFilename, pPrefixMatch->m_Filename.c_str(), Length); |
| 149 | return; |
| 150 | } |
| 151 | |
| 152 | // Remove last segment of locale string and try again with more generic locale, e.g. "en-US" -> "en" |
| 153 | int i = str_length(aLocaleStr) - 1; |
| 154 | for(; i >= 0; --i) |
| 155 | { |
| 156 | if(aLocaleStr[i] == '-') |
| 157 | { |
| 158 | aLocaleStr[i] = '\0'; |
| 159 | break; |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | // Stop if no more locale segments are left |
| 164 | if(i <= 0) |
| 165 | break; |
| 166 | } |
| 167 | } |
no test coverage detected