summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-11-18 23:09:26 +0100
committerCarl Hetherington <cth@carlh.net>2025-11-20 00:15:08 +0100
commit7b8f3de97be7d8799e40a4a60e2ad5d35fb3456d (patch)
tree8d72e9a28bdf7bc2c1e336b5e78c0663af4bbc44
parentc6447ef322e1eb3b01bb25cbe19e116849c3c118 (diff)
Add and test relative_path() method.
-rw-r--r--src/lib/util.cc12
-rw-r--r--src/lib/util.h9
-rw-r--r--test/relative_paths_test.cc17
3 files changed, 38 insertions, 0 deletions
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<boost::filesystem::path> const& paths);
std::function<AVPixelFormat (AVPixelFormat)> 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 <class T>
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 <boost/test/unit_test.hpp>
@@ -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<bool>(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