diff --git a/support/3rd_party/src/utils/path.cpp b/support/3rd_party/src/utils/path.cpp index f62a8a2d..062be08d 100644 --- a/support/3rd_party/src/utils/path.cpp +++ b/support/3rd_party/src/utils/path.cpp @@ -22,6 +22,7 @@ #include "utils/path.hpp" #include "utils/common.hpp" +#include "utils/error.hpp" #include "utils/string.hpp" #include "utils/unix.hpp" @@ -34,44 +35,52 @@ static const std::wstring directory_seperator_str_w{ repertory::utils::path::directory_seperator_w, }; -#if !defined(_WIN32) [[nodiscard]] auto resolve(std::string path) -> std::string { + static constexpr const std::string_view function_name{ + static_cast(__FUNCTION__), + }; + #if defined(HAS_WORDEXP_H) - wordexp_t wt{}; - int ret{}; - if ((ret = wordexp(path.c_str(), &wt, 0)) != 0) { - throw std::runtime_error("'wordexp()' failed|" + std::to_string(ret)); + try { + wordexp_t wt{}; + int ret{}; + if ((ret = wordexp(path.c_str(), &wt, 0)) != 0) { + throw std::runtime_error("'wordexp()' failed|" + std::to_string(ret) + + '|' + path); + } + + path = wt.we_wordv[0U]; + wordfree(&wt); + } catch (const std::exception &e) { + repertory::utils::error::handle_exception(function_name, e); + } catch (...) { + repertory::utils::error::handle_exception(function_name); } - path = wt.we_wordv[0U]; - wordfree(&wt); -#else // !defined(HAS_WORDEXP_H) - utils::string::replace(path, "~", "%USERPROFILE%"); +#else // !defined(HAS_WORDEXP_H) + repertory::utils::string::replace(path, "~", "%USERPROFILE%"); std::string dest; dest.resize(::ExpandEnvironmentStringsA(path.c_str(), nullptr, 0)); ::ExpandEnvironmentStringsA(path.c_str(), dest.data(), static_cast(dest.size())); path = dest.c_str(); - #endif // defined(HAS_WORDEXP_H) return path; } -#endif // !defined(_WIN32) } // namespace namespace repertory::utils::path { auto absolute(std::string_view path) -> std::string { std::string abs_path{path}; -#ifdef _WIN32 +#if defined(_WIN32) if (not abs_path.empty() && ::PathIsRelative(abs_path.c_str())) { std::string temp; temp.resize(MAX_PATH + 1); abs_path = _fullpath(temp.c_str(), abs_path.data(), MAX_PATH); } -#else - abs_path = resolve(abs_path); - +#else // !defined(_WIN32) + abs_path = resolve(finalize(abs_path)); if (not abs_path.empty() && (abs_path.at(0U) != '/')) { auto found{false}; std::string tmp{abs_path}; @@ -88,9 +97,9 @@ auto absolute(std::string_view path) -> std::string { } } while (not found); } -#endif +#endif // defined(_WIN32) - return finalize(abs_path); + return abs_path; } auto absolute(std::wstring_view path) -> std::wstring { diff --git a/support/3rd_party/test/src/utils/path_test.cpp b/support/3rd_party/test/src/utils/path_test.cpp index 4cfb25f1..27f9bce5 100644 --- a/support/3rd_party/test/src/utils/path_test.cpp +++ b/support/3rd_party/test/src/utils/path_test.cpp @@ -21,6 +21,7 @@ */ #include "gtest/gtest.h" +#include "utils/common.hpp" #include "utils/path.hpp" #include "utils/string.hpp" @@ -245,4 +246,19 @@ TEST(utils_path, finalize) { EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); #endif } + +TEST(utils_path, absolute) { + auto dir = utils::path::absolute(std::filesystem::current_path().string()); + auto path = utils::path::absolute("."); + EXPECT_STREQ(dir.c_str(), path.c_str()); + + path = utils::path::absolute("./"); + EXPECT_STREQ(dir.c_str(), path.c_str()); + + auto home = utils::path::absolute(utils::get_environment_variable("HOME")); + path = utils::path::absolute("~"); + EXPECT_STREQ(home.c_str(), path.c_str()); + + // path = utils::path::absolute("~/.local"); +} } // namespace repertory diff --git a/support/3rd_party/test/src/utils/string_test.cpp b/support/3rd_party/test/src/utils/string_test.cpp index 2066c123..41e770c8 100644 --- a/support/3rd_party/test/src/utils/string_test.cpp +++ b/support/3rd_party/test/src/utils/string_test.cpp @@ -82,6 +82,14 @@ TEST(utils_string, replace) { std::wstring str_w3{L"///"}; utils::string::replace(str_w3, '/', '\\'); EXPECT_STREQ(L"\\\\\\", str_w3.c_str()); + + str.clear(); + utils::string::replace(str, '/', '\\'); + EXPECT_STREQ("", str.c_str()); + + str_w.clear(); + utils::string::replace(str_w, '/', '\\'); + EXPECT_STREQ(L"", str_w.c_str()); } TEST(utils_string, replace_string) {