Skip to content

Commit

Permalink
Refactor windows_encoding_to_utf8
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoinePrv committed Oct 26, 2023
1 parent 47700d6 commit 4e02bb0
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 84 deletions.
6 changes: 0 additions & 6 deletions libmamba/include/mamba/core/util_os.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ namespace mamba
void init_console();
void reset_console();

#ifdef _WIN32
std::string to_utf8(const wchar_t* windows_unicode_text, size_t size);
std::string to_utf8(const wchar_t* windows_unicode_text);
std::string to_utf8(const std::wstring& windows_unicode_text);
#endif

/* Test whether a given `std::ostream` object refers to a terminal. */
bool is_atty(const std::ostream& stream);

Expand Down
6 changes: 4 additions & 2 deletions libmamba/include/mamba/util/os_win.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ namespace mamba::util
RoamingAppData,
};

auto get_windows_known_user_folder(WindowsKnowUserFolder dir) -> fs::u8path;
[[nodiscard]] auto get_windows_known_user_folder(WindowsKnowUserFolder dir) -> fs::u8path;

auto utf8_to_windows_encoding(const std::string_view utf8_text) -> std::wstring;
[[nodiscard]] auto utf8_to_windows_encoding(const std::string_view utf8_text) -> std::wstring;

[[nodiscard]] auto windows_encoding_to_utf8(std::wstring_view) -> std::string;
}
#endif
2 changes: 1 addition & 1 deletion libmamba/src/core/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ namespace mamba::env
{
value.pop_back(); // Remove the `\0` that was written in, otherwise any future
// concatenation will fail.
return mamba::to_utf8(value);
return util::windows_encoding_to_utf8(value);
}
else
{
Expand Down
10 changes: 6 additions & 4 deletions libmamba/src/core/shell_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include <reproc++/run.hpp>
#ifdef _WIN32
#include <WinReg.hpp>

#include "mamba/util/os_win.hpp"
#endif

#include "mamba/core/activation.hpp"
Expand All @@ -33,14 +35,14 @@ namespace mamba
{
namespace
{
static std::regex const MAMBA_INITIALIZE_RE_BLOCK("\n?# >>> mamba initialize >>>(?:\n|\r\n)?"
static const std::regex MAMBA_INITIALIZE_RE_BLOCK("\n?# >>> mamba initialize >>>(?:\n|\r\n)?"
"([\\s\\S]*?)"
"# <<< mamba initialize <<<(?:\n|\r\n)?");

static std::regex const MAMBA_INITIALIZE_PS_RE_BLOCK("\n?#region mamba initialize(?:\n|\r\n)?"
static const std::regex MAMBA_INITIALIZE_PS_RE_BLOCK("\n?#region mamba initialize(?:\n|\r\n)?"
"([\\s\\S]*?)"
"#endregion(?:\n|\r\n)?");
static std::wregex const
static const std::wregex
MAMBA_CMDEXE_HOOK_REGEX(L"(\"[^\"]*?mamba[-_]hook\\.bat\")", std::regex_constants::icase);

}
Expand Down Expand Up @@ -126,7 +128,7 @@ namespace mamba
fmt::print(
out,
"Setting cmd.exe AUTORUN to: {}",
fmt::styled(to_utf8(value), graphics.palette.success)
fmt::styled(util::windows_encoding_to_utf8(value), graphics.palette.success)
);

winreg::RegKey key{ HKEY_CURRENT_USER, reg_path };
Expand Down
54 changes: 0 additions & 54 deletions libmamba/src/core/util_os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,60 +486,6 @@ namespace mamba
#endif
}

#ifdef _WIN32
std::string to_utf8(const wchar_t* w, size_t s)
{
std::string output;
if (s != 0)
{
assert(s <= INT_MAX);
const int size = WideCharToMultiByte(
CP_UTF8,
0,
w,
static_cast<int>(s),
nullptr,
0,
nullptr,
nullptr
);
if (size <= 0)
{
unsigned long last_error = ::GetLastError();
LOG_ERROR << "Failed to convert string to UTF-8 "
<< std::system_category().message(static_cast<int>(last_error));
throw std::runtime_error("Failed to convert string to UTF-8");
}

output.resize(size);
int res_size = WideCharToMultiByte(
CP_UTF8,
0,
w,
static_cast<int>(s),
output.data(),
static_cast<int>(size),
nullptr,
nullptr
);
assert(res_size == size);
}

return output;
}

std::string to_utf8(const wchar_t* w)
{
return to_utf8(w, wcslen(w));
}

std::string to_utf8(const std::wstring& s)
{
return to_utf8(s.data(), s.size());
}

#endif

/* From https://github.com/ikalnytskyi/termcolor
*
* copyright: (c) 2013 by Ihor Kalnytskyi.
Expand Down
49 changes: 48 additions & 1 deletion libmamba/src/util/os_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace mamba::util
if (size <= 0)
{
throw std::runtime_error(fmt::format(
R"(Failed to convert UTF-8 string "{}" to UTF-16: )",
R"(Failed to convert UTF-8 string "{}" to UTF-16: {})",
utf8_text,
std::system_category().message(static_cast<int>(::GetLastError()))
));
Expand All @@ -100,6 +100,48 @@ namespace mamba::util
assert(res_size == size);
return output;
}

auto windows_encoding_to_utf8(std::wstring_view str) -> std::string
{
if (str.empty())
{
return {};
}

assert(str.size() <= std::numeric_limits<int>::max());
const int size = ::WideCharToMultiByte(
CP_UTF8,
0,
str.data(),
static_cast<int>(str.size()),
nullptr,
0,
nullptr,
nullptr
);
if (size <= 0)
{
throw std::runtime_error(fmt::format(
R"(Failed to convert UTF-16 string to UTF-8: {})",
std::system_category().message(static_cast<int>(::GetLastError()))
));
}

auto output = std::string(static_cast<std::size_t>(size), char(0));
[[maybe_unused]] const int res_size = ::WideCharToMultiByte(
CP_UTF8,
0,
str.data(),
static_cast<int>(str.size()),
output.data(),
static_cast<int>(size),
nullptr,
nullptr
);
assert(res_size == size);

return output;
}
}

#else // #ifdef _WIN32
Expand Down Expand Up @@ -130,6 +172,11 @@ namespace mamba::util
{
throw_not_implemented("utf8_to_windows_unicode");
}

auto windows_encoding_to_utf8(std::wstring_view) -> std::string
{
throw_not_implemented("windows_encoding_to_utf8");
}
}

#endif // #ifdef _WIN32
15 changes: 0 additions & 15 deletions libmamba/tests/src/core/test_util_os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,6 @@

#ifdef _WIN32

namespace
{
const std::wstring text_utf16 = L"Hello, I am Joël. 私のにほんごわへたです";
const std::string text_utf8 = u8"Hello, I am Joël. 私のにほんごわへたです";
}

TEST_SUITE("basic_unicode_conversion")
{
TEST_CASE("to_utf8")
{
auto result = mamba::to_utf8(text_utf16);
CHECK_EQ(text_utf8, result);
}
}

TEST_SUITE("windows_path")
{
TEST_CASE("fix_win_path")
Expand Down
7 changes: 7 additions & 0 deletions libmamba/tests/src/util/test_os_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ TEST_SUITE("uti::os_win")

SUBCASE("utf8_to_windows_encoding")
{
CHECK_EQ(utf8_to_windows_encoding(""), L"");
CHECK_EQ(utf8_to_windows_encoding(text_utf8), text_utf16);
}

TEST_CASE("windows_encoding_to_utf8")
{
CHECK_EQ(windows_encoding_to_utf8(L""), "");
CHECK_EQ(windows_encoding_to_utf8(text_utf16), text_utf8);
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion micromamba/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <windows.h>
// Incomplete header included last
#include <shellapi.h>

#include "mamba/util/os_win.hpp"
#endif

#include <CLI/CLI.hpp>
Expand Down Expand Up @@ -56,7 +58,7 @@ main(int argc, char** argv)
std::vector<char*> utf8CharArgs;
for (int i = 0; i < argc; i++)
{
utf8Args.push_back(to_utf8(wargv[i]));
utf8Args.push_back(util::windows_encoding_to_utf8(wargv[i]));
}
for (int i = 0; i < argc; ++i)
{
Expand Down

0 comments on commit 4e02bb0

Please sign in to comment.