From e0ec41683d91148a822c18cd4ad68f65b13e89cf Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 4 Oct 2017 02:45:01 +0100 Subject: [PATCH] Deal with xinclude == xmlbase It's a silly edge case as you can't xinclude directories, but might as well make it a little more sane. --- src/actions.cpp | 2 +- src/include_paths.cpp | 4 ++-- src/include_paths.hpp | 2 +- src/path.cpp | 7 ++++-- src/path.hpp | 2 +- test/unit/path_test.cpp | 35 ++++++++++++++++++++++++++++ test/xinclude/xinclude-1_1-alt.gold | 1 + test/xinclude/xinclude-1_1-alt2.gold | 1 + test/xinclude/xinclude-1_1.gold | 1 + test/xinclude/xinclude-1_1.quickbook | 1 + test/xinclude/xmlbase1-1_6-alt.gold | 1 + test/xinclude/xmlbase1-1_6-alt2.gold | 1 + test/xinclude/xmlbase1-1_6.gold | 1 + test/xinclude/xmlbase1-1_6.quickbook | 1 + test/xinclude/xmlbase2-1_6-alt.gold | 1 + test/xinclude/xmlbase2-1_6-alt2.gold | 1 + test/xinclude/xmlbase2-1_6.gold | 1 + test/xinclude/xmlbase2-1_6.quickbook | 1 + 18 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index df10c19..408f2a1 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -1830,7 +1830,7 @@ namespace quickbook if (x.type == path_parameter::path) { - quickbook_path path = resolve_xinclude_path(x.value, state); + quickbook_path path = resolve_xinclude_path(x.value, state, true); state.out << "\npath.parent_path() / path; // Then calculate relative to the current xinclude_base. - path = path_difference(state.xinclude_base, full_path); + path = path_difference(state.xinclude_base, full_path, is_file); } return quickbook_path(full_path, 0, path); diff --git a/src/include_paths.hpp b/src/include_paths.hpp index 651ff5b..20c39c5 100644 --- a/src/include_paths.hpp +++ b/src/include_paths.hpp @@ -65,7 +65,7 @@ namespace quickbook std::set include_search(path_parameter const&, quickbook::state& state, string_iterator pos); - quickbook_path resolve_xinclude_path(std::string const&, quickbook::state&); + quickbook_path resolve_xinclude_path(std::string const&, quickbook::state&, bool is_file = false); } #endif diff --git a/src/path.cpp b/src/path.cpp index 78db5ea..72337a4 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -51,7 +51,7 @@ namespace quickbook } // The relative path from base to path - fs::path path_difference(fs::path const& base, fs::path const& path) + fs::path path_difference(fs::path const& base, fs::path const& path, bool is_file) { fs::path absolute_base = fs::absolute(base), @@ -97,7 +97,10 @@ namespace quickbook } } - if (base_it == base_end && path_it == path_end) { + if (is_file && path_it == path_end && path_it != path_parts.begin()) { + --path_it; + result = ".."; + } else if (base_it == base_end && path_it == path_end) { result = "."; } diff --git a/src/path.hpp b/src/path.hpp index 3e05e1c..acb22c1 100644 --- a/src/path.hpp +++ b/src/path.hpp @@ -20,7 +20,7 @@ namespace quickbook namespace fs = boost::filesystem; // The relative path from base to path - fs::path path_difference(fs::path const& base, fs::path const& path); + fs::path path_difference(fs::path const& base, fs::path const& path, bool is_file = false); // Convert a Boost.Filesystem path to a URL. std::string file_path_to_url(fs::path const&); diff --git a/test/unit/path_test.cpp b/test/unit/path_test.cpp index 0143c40..a08ad4c 100644 --- a/test/unit/path_test.cpp +++ b/test/unit/path_test.cpp @@ -32,7 +32,9 @@ void path_difference_tests() { using boost::filesystem::path; using quickbook::path_difference; + BOOST_TEST(path(".") == path_difference(path(""), path(""))); BOOST_TEST(path(".") == path_difference(path("a"), path("a"))); + BOOST_TEST(path(".") == path_difference(path("a/../b"), path("b"))); BOOST_TEST(path(".") == path_difference(current_path(), current_path())); BOOST_TEST(path("..") == path_difference(path("a"), path(""))); BOOST_TEST(path("..") == path_difference(current_path()/"a", current_path())); @@ -44,6 +46,39 @@ void path_difference_tests() { BOOST_TEST(path("../a/b") == path_difference(current_path()/"c", current_path()/"a"/"b")); BOOST_TEST(path("..") == path_difference(path(""), path(".."))); BOOST_TEST(path("..") == path_difference(current_path(), current_path().parent_path())); + BOOST_TEST(path("b") == path_difference(path("a/c/.."), path("a/b"))); + BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("a/b"))); + BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("d/f/../../a/b"))); + BOOST_TEST(path("../../x/a/b") == path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b"))); + + // path_difference to a file, try to include the filename in the result, + // although not always possible. Maybe nonsense calls should be an error? + // + // Commented out cases are wrong because path_difference resolves the paths + // to the current working directory. In use this doesn't matter as it's + // always called with the full path, but it'd be nice to get this right. + // Or maybe just add the pre-condition to path_difference? + std::cout << path_difference(path(""), path(""), true) << std::endl; + //BOOST_TEST(path(".") == path_difference(path(""), path(""), true)); + BOOST_TEST(path("../a") == path_difference(path("a"), path("a"), true)); + BOOST_TEST(path("../../a") == path_difference(path("a/b"), path("a"), true)); + BOOST_TEST(path("../b") == path_difference(path("a/../b"), path("b"), true)); + BOOST_TEST(".."/current_path().filename() == path_difference(current_path(), current_path(), true)); + //BOOST_TEST(path("..") == path_difference(path("a"), path(""), true)); + BOOST_TEST("../.."/current_path().filename() == path_difference(current_path()/"a", current_path(), true)); + BOOST_TEST(path("a") == path_difference(path(""), path("a"), true)); + BOOST_TEST(path("a") == path_difference(current_path(), current_path()/"a", true)); + BOOST_TEST(path("b") == path_difference(path("a"), path("a/b"), true)); + BOOST_TEST(path("b") == path_difference(current_path()/"a", current_path()/"a"/"b", true)); + BOOST_TEST(path("../a/b") == path_difference(path("c"), path("a/b"), true)); + BOOST_TEST(path("../a/b") == path_difference(current_path()/"c", current_path()/"a"/"b", true)); + //BOOST_TEST(path("..") == path_difference(path(""), path(".."), true)); + BOOST_TEST("../.."/current_path().parent_path().filename() == + path_difference(current_path(), current_path().parent_path(), true)); + BOOST_TEST(path("b") == path_difference(path("a/c/.."), path("a/b"), true)); + BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("a/b"), true)); + BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("d/f/../../a/b"), true)); + BOOST_TEST(path("../../x/a/b") == path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b"), true)); } int main() { diff --git a/test/xinclude/xinclude-1_1-alt.gold b/test/xinclude/xinclude-1_1-alt.gold index ce7018e..cffe529 100644 --- a/test/xinclude/xinclude-1_1-alt.gold +++ b/test/xinclude/xinclude-1_1-alt.gold @@ -5,4 +5,5 @@ + diff --git a/test/xinclude/xinclude-1_1-alt2.gold b/test/xinclude/xinclude-1_1-alt2.gold index 46b9559..7c2e400 100644 --- a/test/xinclude/xinclude-1_1-alt2.gold +++ b/test/xinclude/xinclude-1_1-alt2.gold @@ -5,4 +5,5 @@ + diff --git a/test/xinclude/xinclude-1_1.gold b/test/xinclude/xinclude-1_1.gold index ee8e86e..0a5707f 100644 --- a/test/xinclude/xinclude-1_1.gold +++ b/test/xinclude/xinclude-1_1.gold @@ -5,4 +5,5 @@ + diff --git a/test/xinclude/xinclude-1_1.quickbook b/test/xinclude/xinclude-1_1.quickbook index 65ccfd7..9405e4e 100644 --- a/test/xinclude/xinclude-1_1.quickbook +++ b/test/xinclude/xinclude-1_1.quickbook @@ -3,3 +3,4 @@ [xinclude ../stub.xml] [xinclude stub.xml] [xinclude sub/stub.xml] +[xinclude ../xinclude] diff --git a/test/xinclude/xmlbase1-1_6-alt.gold b/test/xinclude/xmlbase1-1_6-alt.gold index e20b845..29a84ca 100644 --- a/test/xinclude/xmlbase1-1_6-alt.gold +++ b/test/xinclude/xmlbase1-1_6-alt.gold @@ -6,4 +6,5 @@ + diff --git a/test/xinclude/xmlbase1-1_6-alt2.gold b/test/xinclude/xmlbase1-1_6-alt2.gold index 4d283f9..1c2ccc2 100644 --- a/test/xinclude/xmlbase1-1_6-alt2.gold +++ b/test/xinclude/xmlbase1-1_6-alt2.gold @@ -6,4 +6,5 @@ + diff --git a/test/xinclude/xmlbase1-1_6.gold b/test/xinclude/xmlbase1-1_6.gold index 11f224b..4c97e0d 100644 --- a/test/xinclude/xmlbase1-1_6.gold +++ b/test/xinclude/xmlbase1-1_6.gold @@ -6,4 +6,5 @@ + diff --git a/test/xinclude/xmlbase1-1_6.quickbook b/test/xinclude/xmlbase1-1_6.quickbook index 7851d86..2656c7a 100644 --- a/test/xinclude/xmlbase1-1_6.quickbook +++ b/test/xinclude/xmlbase1-1_6.quickbook @@ -6,3 +6,4 @@ [xinclude ../stub.xml] [xinclude stub.xml] [xinclude sub/stub.xml] +[xinclude ../xinclude] diff --git a/test/xinclude/xmlbase2-1_6-alt.gold b/test/xinclude/xmlbase2-1_6-alt.gold index 12081b4..6cfa197 100644 --- a/test/xinclude/xmlbase2-1_6-alt.gold +++ b/test/xinclude/xmlbase2-1_6-alt.gold @@ -6,4 +6,5 @@ + diff --git a/test/xinclude/xmlbase2-1_6-alt2.gold b/test/xinclude/xmlbase2-1_6-alt2.gold index de47831..e3b2f62 100644 --- a/test/xinclude/xmlbase2-1_6-alt2.gold +++ b/test/xinclude/xmlbase2-1_6-alt2.gold @@ -6,4 +6,5 @@ + diff --git a/test/xinclude/xmlbase2-1_6.gold b/test/xinclude/xmlbase2-1_6.gold index 2bde8d1..f3507d3 100644 --- a/test/xinclude/xmlbase2-1_6.gold +++ b/test/xinclude/xmlbase2-1_6.gold @@ -6,4 +6,5 @@ + diff --git a/test/xinclude/xmlbase2-1_6.quickbook b/test/xinclude/xmlbase2-1_6.quickbook index 73386b1..252bacc 100644 --- a/test/xinclude/xmlbase2-1_6.quickbook +++ b/test/xinclude/xmlbase2-1_6.quickbook @@ -6,3 +6,4 @@ [xinclude ../stub.xml] [xinclude stub.xml] [xinclude sub/stub.xml] +[xinclude ../xinclude]