| 244 | } |
| 245 | |
| 246 | uint16_t GetLocaleLanguage() |
| 247 | { |
| 248 | const char* langString = setlocale(LC_MESSAGES, ""); |
| 249 | if (langString != nullptr) |
| 250 | { |
| 251 | // The locale has the following form: |
| 252 | // language[_territory[.codeset]][@modifier] |
| 253 | // (see https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html) |
| 254 | // longest on my system is 29 with codeset and modifier, so 32 for the pattern should be more than enough |
| 255 | char pattern[32]; |
| 256 | // strip the codeset and modifier part |
| 257 | int32_t length = strlen(langString); |
| 258 | { |
| 259 | for (int32_t i = 0; i < length; ++i) |
| 260 | { |
| 261 | if (langString[i] == '.' || langString[i] == '@') |
| 262 | { |
| 263 | length = i; |
| 264 | break; |
| 265 | } |
| 266 | } |
| 267 | } // end strip |
| 268 | std::memcpy(pattern, langString, length); // copy all until first '.' or '@' |
| 269 | pattern[length] = '\0'; |
| 270 | // find _ if present |
| 271 | const char* strip = strchr(pattern, '_'); |
| 272 | if (strip != nullptr) |
| 273 | { |
| 274 | // could also use '-', but '?' is more flexible. Maybe LanguagesDescriptors will change. |
| 275 | // pattern is now "language?territory" |
| 276 | pattern[strip - pattern] = '?'; |
| 277 | } |
| 278 | |
| 279 | // Iterate through all available languages |
| 280 | for (int32_t i = 1; i < LANGUAGE_COUNT; ++i) |
| 281 | { |
| 282 | if (!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)) |
| 283 | { |
| 284 | return i; |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | // special case |
| 289 | if (fnmatch(pattern, "en_CA", 0) == 0) |
| 290 | { |
| 291 | return LANGUAGE_ENGLISH_US; |
| 292 | } |
| 293 | |
| 294 | // no exact match found trying only language part |
| 295 | if (strip != nullptr) |
| 296 | { |
| 297 | pattern[strip - pattern] = '*'; |
| 298 | pattern[strip - pattern + 1] = '\0'; // pattern is now "language*" |
| 299 | for (int32_t i = 1; i < LANGUAGE_COUNT; ++i) |
| 300 | { |
| 301 | if (!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)) |
| 302 | { |
| 303 | return i; |