13# define pclose _pclose
15#elif defined(__APPLE__) || defined(__linux__)
19using namespace std::string_literals;
27bool has_plugin_dir(
const fs::path& libmim_path) {
28 std::error_code ignore;
29 return fs::is_directory(libmim_path.parent_path() /
"mim", ignore) && !ignore;
32fs::path adjust_libmim_path(
const fs::path& libmim_path) {
33 if (has_plugin_dir(libmim_path))
return libmim_path;
35 auto dir = libmim_path.parent_path();
36 auto lib_name = libmim_path.filename();
37 while (!dir.empty()) {
38 if (dir == dir.root_path())
break;
40 std::error_code ignore;
42 if (fs::is_directory(candidate, ignore) && !ignore)
return candidate.parent_path() / lib_name;
44 dir = dir.parent_path();
54 HMODULE mod =
nullptr;
55 auto flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
56 if (!GetModuleHandleExW(flags,
reinterpret_cast<LPCWSTR
>(&
mim_lib_anchor), &mod))
return {};
61 DWORD len = GetModuleFileNameW(mod, buf.data(), (DWORD)buf.size());
62 if (len == 0)
return {};
64 if (len < buf.size() - 1) {
69 buf.resize(buf.size() * 2);
72 return adjust_libmim_path(fs::weakly_canonical(fs::path(buf)));
73#elif defined(__APPLE__) || defined(__linux__)
76 return adjust_libmim_path(fs::weakly_canonical(info.dli_fname));
83std::string
exec(std::string cmd) {
84 using PipeCloser =
int (*)(FILE*);
85 if (
auto pipe = std::unique_ptr<FILE, PipeCloser>(popen(cmd.c_str(),
"r"), pclose)) {
86 std::array<char, 128> buffer;
88 while (fgets(buffer.data(), buffer.size(), pipe.get()) !=
nullptr)
89 result += buffer.data();
92 error(
"popen() failed!");
97 if (
auto it = out.find(
'\n'); it != std::string::npos) out.erase(it);
102 std::cout << cmd << std::endl;
103 int status = std::system(cmd.c_str());
104 return WEXITSTATUS(status);
107int run(std::string cmd, std::string args ) {
116std::string
escape(
const std::filesystem::path& path) {
118 for (
char c : path.string()) {
119 if (isspace(c)) str +=
'\\';
int run(std::string cmd, std::string args={})
Wraps sys::system and puts .exe at the back (Windows) and ./ at the front (otherwise) of cmd.
int system(std::string)
Wraps std::system and makes the return value usable.
std::string escape(const std::filesystem::path &path)
Returns the path as std::string and escapes all whitespaces with backslash.
std::string find_cmd(std::string)
std::optional< fs::path > path_to_libmim()
Yields std::nullopt if an error occurred.
std::string exec(std::string cmd)
Executes command cmd.
void error(std::format_string< Args... > fmt, Args &&... args)
Wraps std::format to throw T with a formatted message.