Implement weakly_canonical for boost versions without it (e.g. the one on Ubuntu...
authorCarl Hetherington <cth@carlh.net>
Mon, 9 Oct 2023 22:40:00 +0000 (00:40 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 10 Oct 2023 08:58:39 +0000 (10:58 +0200)
src/filesystem.cc
test/filesystem_test.cc
wscript

index 0ebe7cf71681badc22aedbeda8132a4f8497d87b..428bb0298b881502eded019302193deb4dc06ef0 100644 (file)
@@ -144,7 +144,26 @@ dcp::filesystem::canonical(boost::filesystem::path const& path)
 boost::filesystem::path
 dcp::filesystem::weakly_canonical(boost::filesystem::path const& path)
 {
+#ifdef DCPOMATIC_HAVE_WEAKLY_CANONICAL
        return dcp::filesystem::unfix_long_path(boost::filesystem::weakly_canonical(dcp::filesystem::fix_long_path(path)));
+#else
+       boost::filesystem::path complete(boost::filesystem::system_complete(dcp::filesystem::fix_long_path(path)));
+       boost::filesystem::path result;
+       for (auto part: complete) {
+               if (part == "..") {
+                       boost::system::error_code ec;
+                       if (boost::filesystem::is_symlink(result, ec) || result.filename() == "..") {
+                               result /= part;
+                       } else {
+                               result = result.parent_path();
+                       }
+               } else if (part != ".") {
+                       result /= part;
+               }
+       }
+
+       return dcp::filesystem::unfix_long_path(result.make_preferred());
+#endif
 }
 
 
index fc13db99272ba915e32f47cc830d071c1a9866f1..90b7761ea0762947379da2ca02dda215293a778b 100644 (file)
@@ -95,3 +95,18 @@ BOOST_AUTO_TEST_CASE (windows_long_filename_test)
 }
 #endif
 
+
+BOOST_AUTO_TEST_CASE(weakly_canonical_test)
+{
+#ifdef LIBDCP_WINDOWS
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("c:\\a\\b\\c") == boost::filesystem::path("c:\\a\\b\\c"));
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("c:\\a\\b\\..\\c") == boost::filesystem::path("c:\\a\\c"));
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("c:\\a\\b\\..\\c\\.\\d") == boost::filesystem::path("c:\\a\\c\\d"));
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("c:\\a\\..\\b\\..\\c") == boost::filesystem::path("c:\\c"));
+#else
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("/a/b/c") == boost::filesystem::path("/a/b/c"));
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("/a/b/../c") == boost::filesystem::path("/a/c"));
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("/a/b/../c/./d") == boost::filesystem::path("/a/c/d"));
+       BOOST_CHECK(dcp::filesystem::weakly_canonical("/a/../b/../c") == boost::filesystem::path("/c"));
+#endif
+}
diff --git a/wscript b/wscript
index 458d61321f9ba48b85036b68e9bbcbe0db8f5fa5..d813c536b42560f4acc0f4bc9c847f0d7a51bab1 100644 (file)
--- a/wscript
+++ b/wscript
@@ -213,6 +213,15 @@ def configure(conf):
                    lib=['boost_filesystem%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix],
                    uselib_store='BOOST_FILESYSTEM')
 
+    conf.check_cxx(fragment="""
+                   #include <boost/filesystem.hpp>\n
+                   int main() { boost::filesystem::weakly_canonical("a/b/c"); }\n
+                   """,
+                   mandatory=False,
+                   msg='Checking for boost::filesystem::weakly_canonical',
+                   uselib='BOOST_FILESYSTEM',
+                   define_name='LIBDCP_HAVE_WEAKLY_CANONICAL')
+
     conf.check_cxx(fragment="""
                            #include <boost/signals2.hpp>\n
                            int main() { boost::signals2::signal<void (int)> x; }\n