fix(util): add function to handle localized errors on Windows (gh #241)

This commit is contained in:
Marcus Holland-Moritz 2024-11-20 18:10:42 +01:00
parent 711358ac74
commit 81585ea8cd
2 changed files with 37 additions and 0 deletions

View File

@ -52,6 +52,8 @@ size_t utf8_display_width(std::string const& str);
void utf8_truncate(std::string& str, size_t len); void utf8_truncate(std::string& str, size_t len);
void utf8_sanitize(std::string& str); void utf8_sanitize(std::string& str);
std::string error_cp_to_utf8(std::string_view error);
void shorten_path_string(std::string& path, char separator, size_t max_len); void shorten_path_string(std::string& path, char separator, size_t max_len);
std::filesystem::path canonical_path(std::filesystem::path p); std::filesystem::path canonical_path(std::filesystem::path p);

View File

@ -319,6 +319,41 @@ void setup_default_locale() {
} }
} }
std::string error_cp_to_utf8(std::string_view error) {
std::string input(error);
#ifdef _WIN32
UINT cp = GetACP();
// convert from codepage to UTF-16
int wclen = MultiByteToWideChar(cp, 0, input.c_str(), -1, NULL, 0);
if (wclen == 0) {
utf8_sanitize(input);
return input;
}
std::wstring wstr(wclen, L'\0');
MultiByteToWideChar(cp, 0, input.c_str(), -1, &wstr[0], wclen);
// convert from UTF-16 to UTF-8
int utf8len =
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
if (utf8len == 0) {
utf8_sanitize(input);
return input;
}
std::string utf8err(utf8len, '\0');
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &utf8err[0], utf8len, NULL,
NULL);
// remove the null terminator added by WideCharToMultiByte
if (!utf8err.empty() && utf8err.back() == '\0') {
utf8err.pop_back();
}
return utf8err;
#else
return input;
#endif
}
std::string_view basename(std::string_view path) { std::string_view basename(std::string_view path) {
auto pos = path.find_last_of("/\\"); auto pos = path.find_last_of("/\\");
if (pos == std::string_view::npos) { if (pos == std::string_view::npos) {