From 7b8f3de97be7d8799e40a4a60e2ad5d35fb3456d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 18 Nov 2025 23:09:26 +0100 Subject: Add and test relative_path() method. --- src/lib/util.cc | 12 ++++++++++++ src/lib/util.h | 9 +++++++++ test/relative_paths_test.cc | 17 +++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/lib/util.cc b/src/lib/util.cc index 8628ee3e0..ef12e63ad 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -1180,3 +1180,15 @@ force(AVPixelFormat format) return [format](AVPixelFormat) { return format; }; } + +boost::filesystem::path +relative_path(boost::filesystem::path const& path, boost::filesystem::path const& base) +{ + auto relative = boost::filesystem::relative(path, base); + if (relative == boost::filesystem::path()) { + return path; + } + + return relative; +} + diff --git a/src/lib/util.h b/src/lib/util.h index 846059e1a..f6c8e573f 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -103,6 +103,15 @@ extern std::string rfc_2822_date(time_t time); bool paths_exist(std::vector const& paths); std::function force(AVPixelFormat format); +/** @param path Some path. + * @param base Some base path. + * @return path relative to base, if possible, otherwise path. + * + * This wraps boost::filesystem::path which returns an empty path if you try to get an impossible + * relative path on Windows (e.g. X:\foo relative to C:\bar). + */ +boost::filesystem::path relative_path(boost::filesystem::path const& path, boost::filesystem::path const& base); + template T diff --git a/test/relative_paths_test.cc b/test/relative_paths_test.cc index 6028c1435..4a90c9ad7 100644 --- a/test/relative_paths_test.cc +++ b/test/relative_paths_test.cc @@ -23,6 +23,7 @@ #include "lib/content_factory.h" #include "lib/config.h" #include "lib/film.h" +#include "lib/util.h" #include "test.h" #include @@ -42,3 +43,19 @@ BOOST_AUTO_TEST_CASE(relative_paths_test) BOOST_REQUIRE(paths_exist(film2->content()[0]->paths())); } + +#ifdef DCPOMATIC_WINDOWS +BOOST_AUTO_TEST_CASE(relative_paths_test_windows_other_drive) +{ + /* Assumes we're on C: */ + + ConfigRestorer cr; + Config::instance()->set_relative_paths(true); + + auto film = new_test_film("relative_paths_test_windows_other_drive"); + + BOOST_REQUIRE(static_cast(film->directory())); + BOOST_CHECK(relative_path("C:\\foo\\bar", *film->directory()).is_relative()); + BOOST_CHECK(relative_path("X:\\foo\\bar.png", *film->directory()) == boost::filesystem::path("X:\\foo\\bar.png")); +} +#endif -- cgit v1.2.3