39 std::vector<wchar_t> buffer(MAX_PATH);
40 HMODULE hModule = GetModuleHandle(NULL);
43 DWORD size = GetModuleFileNameW(hModule, buffer.data(), buffer.size());
46 while (size == buffer.size() && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
47 buffer.resize(buffer.size() * 2);
48 size = GetModuleFileNameW(hModule, buffer.data(), buffer.size());
52 throw std::runtime_error(
"Failed to get executable path.");
55 std::wstring exe_path(buffer.begin(), buffer.begin() + size);
58 size_t pos = exe_path.find_last_of(L
"\\/");
59 if (pos != std::wstring::npos) {
60 exe_path = exe_path.substr(0, pos);
64 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
65 return converter.to_bytes(exe_path);
67 char result[PATH_MAX];
68 ssize_t count = readlink(
"/proc/self/exe", result, PATH_MAX);
71 throw std::runtime_error(
"Failed to get executable path.");
74 std::string exe_path(result, count);
77 size_t pos = exe_path.find_last_of(
"\\/");
78 if (pos != std::string::npos) {
79 exe_path = exe_path.substr(0, pos);
90 std::vector<std::string> list_files;
91 std::string search_path = path;
94 if (search_path.empty()) {
96 char buffer[MAX_PATH];
97 GetCurrentDirectoryA(MAX_PATH, buffer);
100 char buffer[PATH_MAX];
101 if (getcwd(buffer, PATH_MAX)) {
102 search_path = buffer;
109 char path_separator =
'\\';
111 char path_separator =
'/';
114 if (search_path.back() !=
'/' && search_path.back() !=
'\\') {
115 search_path += path_separator;
119 std::string pattern = search_path +
"*";
121 HANDLE hFind = FindFirstFileA(pattern.c_str(), &fd);
123 if (hFind != INVALID_HANDLE_VALUE) {
125 std::string file_name = fd.cFileName;
127 if (file_name ==
"." || file_name ==
"..") {
131 std::string full_path = search_path + file_name;
133 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
136 list_files.insert(list_files.end(), sub_files.begin(), sub_files.end());
139 list_files.push_back(full_path);
141 }
while (FindNextFileA(hFind, &fd));
145 DIR* dir = opendir(search_path.c_str());
147 struct dirent* entry;
148 while ((entry = readdir(dir)) !=
nullptr) {
149 std::string file_name = entry->d_name;
151 if (file_name ==
"." || file_name ==
"..") {
155 std::string full_path = search_path + file_name;
158 if (stat(full_path.c_str(), &statbuf) == 0) {
159 if (S_ISDIR(statbuf.st_mode)) {
162 list_files.insert(list_files.end(), sub_files.begin(), sub_files.end());
163 }
else if (S_ISREG(statbuf.st_mode)) {
165 list_files.push_back(full_path);
273 std::string
make_relative(
const std::string& file_path,
const std::string& base_path) {
274 if (base_path.empty())
return file_path;
284 size_t common_size = 0;
285 while (common_size < file_pc.
components.size() &&
292 std::vector<std::string> relative_components;
295 for (
size_t i = common_size; i < base_pc.
components.size(); ++i) {
296 relative_components.push_back(
"..");
300 for (
size_t i = common_size; i < file_pc.
components.size(); ++i) {
301 relative_components.push_back(file_pc.
components[i]);
305 std::string relative_path;
306 if (relative_components.empty()) {
309 for (
size_t i = 0; i < relative_components.size(); ++i) {
312 relative_path +=
'\\';
314 relative_path +=
'/';
317 relative_path += relative_components[i];
321 return relative_path;
337 if (path.empty())
return;
340 size_t components_size = components.size();
348 std::string current_path = path_pc.
root;
349 for (
size_t i = 0; i < components_size; ++i) {
350 if (!current_path.empty() && current_path.back() !=
'/' && current_path.back() !=
'\\') {
353 current_path += components[i];
367 if (components[i] ==
".." ||
368 components[i] ==
"/" ||
369 components[i] ==
"~/")
continue;
371 int ret = _mkdir(current_path.c_str());
373 int ret = mkdir(current_path.c_str(), 0755);
376 if (ret != 0 && errnum != EEXIST) {
377 throw std::runtime_error(
"Failed to create directory: " + current_path);