diff --git a/support/3rd_party/include/utils/path.hpp b/support/3rd_party/include/utils/path.hpp index b4f9aa3d..c4165bc4 100644 --- a/support/3rd_party/include/utils/path.hpp +++ b/support/3rd_party/include/utils/path.hpp @@ -269,27 +269,35 @@ combine(std::wstring path, template [[nodiscard]] inline auto create_api_path_t( std::basic_string_view path) -> string_t { - static auto backslash_t = get_backslash(); - static auto dot_slash_t = get_dot_slash(); - static auto dot_t = get_dot(); - static auto slash_t = get_slash(); + auto backslash_t = get_backslash(); + auto dot_t = get_dot(); + auto dot_slash_t = get_dot_slash(); + auto slash_t = get_slash(); - if (path.empty() || (path == dot_t) || (path == slash_t)) { + if (path.empty() || path == backslash_t || path == dot_t || + path == dot_slash_t || path == slash_t) { return string_t{slash_t}; } string_t api_path{path}; +#if defined(_WIN32) + if ((api_path.size() >= 2U) && (api_path.at(1U) == ':')) { + api_path = api_path.substr(2U); + } +#endif // defined(_WIN32) + + while (utils::string::begins_with(api_path, dot_slash_t)) { + api_path = api_path.substr(dot_slash_t.size()); + } + + while (utils::string::begins_with(api_path, dot_t)) { + api_path = api_path.substr(dot_t.size()); + } + format_path(api_path, slash_t, backslash_t); - if (api_path.find(dot_slash_t) == 0) { - api_path = api_path.substr(1U); - } - if (api_path.at(0U) != '/') { - api_path = string_t{slash_t} + api_path; - } - - if ((api_path != slash_t) && utils::string::ends_with(api_path, slash_t)) { - utils::string::right_trim(api_path, '/'); + if (api_path.at(0U) != slash_t.at(0U)) { + return string_t{slash_t} + api_path; } return api_path; @@ -347,14 +355,6 @@ template format_path(fmt_path, get_directory_seperator(), get_not_directory_seperator()); - -#if defined(_WIN32) - if ((fmt_path.size() >= 2U) && (fmt_path.at(1U) == ':')) { - fmt_path[0U] = - utils::string::to_lower(string_t{1U, fmt_path.at(0U)}).at(0U); - } -#endif // defined(_WIN32) - return fmt_path; } @@ -374,11 +374,21 @@ format_path(string_t &path, -> string_t & { utils::string::replace(path, not_sep, sep); - string_t double_sep{2U, sep.at(0U)}; + string_t double_sep(2U, sep.at(0U)); while (utils::string::contains(path, double_sep)) { utils::string::replace(path, double_sep, sep); } + if (path != sep) { + utils::string::right_trim(path, sep.at(0U)); + } + +#if defined(_WIN32) + if ((path.size() >= 2U) && (path.at(1U) == ':')) { + path[0U] = utils::string::to_lower(string_t{1U, path.at(0U)}).at(0U); + } +#endif // defined(_WIN32) + return path; } @@ -396,6 +406,7 @@ template if (ret == slash_t) { return ret; } + return utils::string::right_trim(ret, '/'); } diff --git a/support/3rd_party/test/src/utils/path_test.cpp b/support/3rd_party/test/src/utils/path_test.cpp index 438ea0d7..44b1caae 100644 --- a/support/3rd_party/test/src/utils/path_test.cpp +++ b/support/3rd_party/test/src/utils/path_test.cpp @@ -119,6 +119,47 @@ TEST(utils_path, combine) { #endif } +TEST(utils_path, format_path) { + std::string path{"\\"}; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); + + path = "\\\\"; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); + + path = "\\\\\\"; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); + + path = "\\\\\\\\"; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); + + path = "/"; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); + path = "//"; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); + + path = "///"; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); + + path = "////"; + utils::path::format_path(path, utils::path::directory_seperator, + utils::path::not_directory_seperator); + EXPECT_STREQ("/", path.c_str()); +} + TEST(utils_path, create_api_path) { auto s = utils::path::create_api_path(""); EXPECT_STREQ("/", s.c_str()); @@ -132,6 +173,9 @@ TEST(utils_path, create_api_path) { s = utils::path::create_api_path("."); EXPECT_STREQ("/", s.c_str()); + s = utils::path::create_api_path("./"); + EXPECT_STREQ("/", s.c_str()); + s = utils::path::create_api_path(R"(\\)"); EXPECT_STREQ("/", s.c_str());