diff --git a/src/io/fix-broken-links.cpp b/src/io/fix-broken-links.cpp index bcd96b7abe81df96835b8724998e1931a89bbba9..9c0f7d2eea62bc8fa57b3714aafd75c62da7799e 100644 --- a/src/io/fix-broken-links.cpp +++ b/src/io/fix-broken-links.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "fix-broken-links.h" @@ -31,26 +32,37 @@ namespace Inkscape { -std::vector splitPath( std::string const &path ) +std::vector splitPath(std::string path) { - std::vector parts; - - std::string prior; - std::string tmp = path; - while ( !tmp.empty() && (tmp != prior) ) { - prior = tmp; - - parts.push_back( Glib::path_get_basename(tmp) ); - tmp = Glib::path_get_dirname(tmp); +#ifdef _WIN32 + constexpr auto separator = '\\'; +#else + constexpr auto separator = '/'; +#endif + +#ifdef _WIN32 + std::replace(path.begin(), path.end(), '/', '\\'); +#endif + + std::vector result; + + for (auto part : Glib::Regex::split_simple(std::string{separator}.c_str(), path.c_str())) { + if (!part.empty() && part != ".") { + result.emplace_back(part.release()); + } } - if ( !parts.empty() ) { - std::reverse(parts.begin(), parts.end()); - if ( (parts[0] == ".") && (path[0] != '.') ) { - parts.erase(parts.begin()); + + // Todo: (C++20) When macOS supports it. + /* + for (auto part : path | std::views::split(separator)) { + auto view = std::string_view{part.begin(), part.end()}; + if (!view.empty() && view != ".") { + result.emplace_back(view); } } + */ - return parts; + return result; } /** diff --git a/src/io/fix-broken-links.h b/src/io/fix-broken-links.h index e443b5833205531dee855f195a324660dccbd305..5fa63a3b3d35d7ee936847273b91fecdfc33bcfa 100644 --- a/src/io/fix-broken-links.h +++ b/src/io/fix-broken-links.h @@ -14,7 +14,7 @@ class SPDocument; namespace Inkscape { -std::vector splitPath( std::string const &path ); +std::vector splitPath(std::string path); std::string optimizePath(std::string const &path, std::string const &base, unsigned int parents = 2); bool fixBrokenLinks(SPDocument *doc); diff --git a/testfiles/CMakeLists.txt b/testfiles/CMakeLists.txt index 9764424c702d35ebac6fab6db92c4cd78841bdda..7550e0335634dd108cbfd2943160019dcd97355f 100644 --- a/testfiles/CMakeLists.txt +++ b/testfiles/CMakeLists.txt @@ -95,6 +95,7 @@ set(TEST_SOURCES util-uri-test drag-and-drop-svgz drawing-pattern-test + fix-broken-links-test poppler-utils-test attributes-test dir-util-test diff --git a/testfiles/src/fix-broken-links-test.cpp b/testfiles/src/fix-broken-links-test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..07ecd41c43a833a90b2f282f2e43217ebdc1481b --- /dev/null +++ b/testfiles/src/fix-broken-links-test.cpp @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "io/fix-broken-links.h" + +#include + +namespace Inkscape { + +TEST(FixBrokenLinksTest, SplitPath) +{ +#ifdef _WIN32 + EXPECT_EQ(splitPath("C:\\images\\\\.\\file.svg"), (std::vector{"C:", "images", "file.svg"})); +#else + EXPECT_EQ(splitPath("/home/user//./file.svg"), (std::vector{"home", "user", "file.svg"})); +#endif +} + +} // namespace Inkscape