From d037dbb42a0a3912cc15870b83626d2876e135f8 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 3 May 2025 11:44:53 +0200 Subject: [PATCH] Codechange: use std::string_view for locales --- src/os/macosx/macos.mm | 2 +- src/os/unix/unix.cpp | 21 +++++++++++---------- src/os/windows/win32.cpp | 2 +- src/strings.cpp | 31 +++++++++++++++---------------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/os/macosx/macos.mm b/src/os/macosx/macos.mm index 7366cc3e5c..052357b8d2 100644 --- a/src/os/macosx/macos.mm +++ b/src/os/macosx/macos.mm @@ -151,7 +151,7 @@ void OSOpenBrowser(const std::string &url) /** * Determine and return the current user's locale. */ -const char *GetCurrentLocale(const char *) +std::optional GetCurrentLocale(const char *) { static char retbuf[32] = { '\0' }; NSUserDefaults *defs = [ NSUserDefaults standardUserDefaults ]; diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 7a6ea11d9d..369bc3c211 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -89,7 +89,7 @@ bool FiosIsHiddenFile(const std::filesystem::path &path) #include "../../debug.h" #include "../../string_func.h" -const char *GetCurrentLocale(const char *param); +std::optional GetCurrentLocale(const char *param); #define INTERNALCODE "UTF-8" @@ -98,16 +98,17 @@ const char *GetCurrentLocale(const char *param); * variables. MacOSX is hardcoded, other OS's are dynamic. If no suitable * locale can be found, don't do any conversion "" */ -static const char *GetLocalCode() +static std::string_view GetLocalCode() { #if defined(__APPLE__) return "UTF-8-MAC"; #else /* Strip locale (eg en_US.UTF-8) to only have UTF-8 */ - const char *locale = GetCurrentLocale("LC_CTYPE"); - if (locale != nullptr) locale = strchr(locale, '.'); - - return (locale == nullptr) ? "" : locale + 1; + auto locale = GetCurrentLocale("LC_CTYPE"); + if (!locale.has_value()) return ""; + auto pos = locale->find('.'); + if (pos == std::string_view::npos) return ""; + return locale->substr(pos + 1); #endif } @@ -151,8 +152,8 @@ std::string OTTD2FS(std::string_view name) { static iconv_t convd = (iconv_t)(-1); if (convd == (iconv_t)(-1)) { - const char *env = GetLocalCode(); - convd = iconv_open(env, INTERNALCODE); + std::string env{GetLocalCode()}; + convd = iconv_open(env.c_str(), INTERNALCODE); if (convd == (iconv_t)(-1)) { Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", INTERNALCODE, env); return std::string{name}; @@ -171,8 +172,8 @@ std::string FS2OTTD(std::string_view name) { static iconv_t convd = (iconv_t)(-1); if (convd == (iconv_t)(-1)) { - const char *env = GetLocalCode(); - convd = iconv_open(INTERNALCODE, env); + std::string env{GetLocalCode()}; + convd = iconv_open(INTERNALCODE, env.c_str()); if (convd == (iconv_t)(-1)) { Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", env, INTERNALCODE); return std::string{name}; diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 82892d7490..27e9f4943f 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -395,7 +395,7 @@ wchar_t *convert_to_fs(std::string_view src, std::span dst_buf) } /** Determine the current user's locale. */ -const char *GetCurrentLocale(const char *) +std::optional GetCurrentLocale(const char *) { const LANGID userUiLang = GetUserDefaultUILanguage(); const LCID userUiLocale = MAKELCID(userUiLang, SORT_DEFAULT); diff --git a/src/strings.cpp b/src/strings.cpp index e31ac8821b..2b9346d930 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -2083,25 +2083,23 @@ bool ReadLanguagePack(const LanguageMetadata *lang) * set. Pass nullptr if you don't want additional checks. * @return return string containing current charset, or nullptr if not-determinable */ -const char *GetCurrentLocale(const char *param) +std::optional GetCurrentLocale(const char *param) { - const char *env; + auto env = GetEnv("LANGUAGE"); + if (env.has_value()) return env; - env = std::getenv("LANGUAGE"); - if (env != nullptr) return env; - - env = std::getenv("LC_ALL"); - if (env != nullptr) return env; + env = GetEnv("LC_ALL"); + if (env.has_value()) return env; if (param != nullptr) { - env = std::getenv(param); - if (env != nullptr) return env; + env = GetEnv(param); + if (env.has_value()) return env; } - return std::getenv("LANG"); + return GetEnv("LANG"); } #else -const char *GetCurrentLocale(const char *param); +std::optional GetCurrentLocale(const char *param); #endif /* !(defined(_WIN32) || defined(__APPLE__)) */ /** @@ -2182,8 +2180,8 @@ void InitializeLanguagePacks() if (_languages.empty()) UserError("No available language packs (invalid versions?)"); /* Acquire the locale of the current system */ - const char *lang = GetCurrentLocale("LC_MESSAGES"); - if (lang == nullptr) lang = "en_GB"; + auto lang = GetCurrentLocale("LC_MESSAGES"); + if (!lang.has_value()) lang = "en_GB"; const LanguageMetadata *chosen_language = nullptr; ///< Matching the language in the configuration file or the current locale const LanguageMetadata *language_fallback = nullptr; ///< Using pt_PT for pt_BR locale when pt_BR is not available @@ -2199,13 +2197,14 @@ void InitializeLanguagePacks() break; } - if (strcmp (lng.isocode, "en_GB") == 0) en_GB_fallback = &lng; + std::string_view iso_code = lng.isocode; + if (iso_code == "en_GB") en_GB_fallback = &lng; /* Only auto-pick finished translations */ if (!lng.IsReasonablyFinished()) continue; - if (strncmp(lng.isocode, lang, 5) == 0) chosen_language = &lng; - if (strncmp(lng.isocode, lang, 2) == 0) language_fallback = &lng; + if (iso_code.starts_with(lang->substr(0, 5))) chosen_language = &lng; + if (iso_code.starts_with(lang->substr(0, 2))) language_fallback = &lng; } /* We haven't found the language in the config nor the one in the locale.