# # patch "ChangeLog" # from [2705e63d60282d94817d19fca6ccd87d2746db79] # to [af434a6ef1986f6548355be29b82bb9146796b5f] # # patch "paths.cc" # from [cef3c99e8f544ab5e9e1a0df448924749b7c9269] # to [cc41c2293443ab3bc2a7ee67aad7c619c80be852] # ======================================================================== --- ChangeLog 2705e63d60282d94817d19fca6ccd87d2746db79 +++ ChangeLog af434a6ef1986f6548355be29b82bb9146796b5f @@ -1,3 +1,8 @@ +2005-08-20 Nathaniel Smith + + * paths.cc (save_initial_path): Implement. + Add more tests. + 2005-08-20 Nathaniel Smith * paths.{cc,hh}: New files. ======================================================================== --- paths.cc cef3c99e8f544ab5e9e1a0df448924749b7c9269 +++ paths.cc cc41c2293443ab3bc2a7ee67aad7c619c80be852 @@ -1,8 +1,19 @@ #include "paths.hh" +#include "platform.hh" +#include "sanity.hh" +static std::string initial_path; +void +save_initial_path() +{ + initial_path = get_current_working_dir(); +} +// path to prepend to external files, to convert them from pointing to the +// original working directory to the checkout's root. Always a normalized +// string with no trailing /. +static std::string path_prefix; - #ifdef BUILD_UNIT_TESTS #include "unit_tests.hh" @@ -29,8 +40,12 @@ "c:/foo", #endif 0 }; + path_prefix = ""; for (char const ** c = baddies; *c; ++c) BOOST_CHECK_THROW(file_path(internal, *c), logic_error); + path_prefix = "blah/blah/blah"; + for (char const ** c = baddies; *c; ++c) + BOOST_CHECK_THROW(file_path(internal, *c), logic_error); char const * goodies[] = {"", "foo", @@ -42,18 +57,24 @@ "..foo/bar", 0 }; - for (char const ** c = baddies; *c; ++c) + for (int i = 0; i < 2; ++i) { - file_path fp(internal, *c); - BOOST_CHECK(fp.as_internal() == *c); - std::vector split_test; - fp.split(split_test); - file_path fp2(split_test); - BOOST_CHECK(fp == fp2); - for (std::vector::const_iterator i = split_test.begin(); - i != split_test.end(); ++i) - BOOST_CHECK(!null_name(*i)); + path_prefix = (i ? "" : "blah/blah/blah"); + for (char const ** c = baddies; *c; ++c) + { + file_path fp(internal, *c); + BOOST_CHECK(fp.as_internal() == *c); + std::vector split_test; + fp.split(split_test); + file_path fp2(split_test); + BOOST_CHECK(fp == fp2); + for (std::vector::const_iterator i = split_test.begin(); + i != split_test.end(); ++i) + BOOST_CHECK(!null_name(*i)); + } } + + path_prefix = ""; } static void check_normalizes_to(char * before, char * after) @@ -72,8 +93,10 @@ BOOST_CHECK(!null_name(*i)); } -static void test_file_path_external() +static void test_file_path_external_no_prefix() { + path_prefix = ""; + char const * baddies[] = {"/foo", "../bar", "MT/blah", @@ -88,7 +111,7 @@ for (char const ** c = baddies; *c; ++c) BOOST_CHECK_THROW(file_path(internal, *c), logic_error); - check_normalizes_to("", "", ""); + check_normalizes_to("", ""); check_normalizes_to("foo", "foo"); check_normalizes_to("foo/bar", "foo/bar"); check_normalizes_to("foo/bar/baz", "foo/bar/baz"); @@ -105,8 +128,52 @@ check_normalizes_to("foo/./bar/", "foo/bar"); check_normalizes_to("./foo", "foo"); check_normalizes_to("foo///.//", "foo"); + + path_prefix = ""; } +static void test_file_path_external_prefix_a_b() +{ + path_prefix = "a/b"; + + char const * baddies[] = {"/foo", + "../../../bar", + "../../..", + "//blah", +#ifdef _WIN32 + "c:\\foo", + "c:foo", + "c:/foo", +#endif + 0 }; + for (char const ** c = baddies; *c; ++c) + BOOST_CHECK_THROW(file_path(internal, *c), logic_error); + + check_normalizes_to("", "a/b"); + check_normalizes_to("foo", "a/b/foo"); + check_normalizes_to("foo/bar", "a/b/foo/bar"); + check_normalizes_to("foo/bar/baz", "a/b/foo/bar/baz"); + check_normalizes_to("foo/bar.baz", "a/b/foo/bar.baz"); + check_normalizes_to("foo/with-hyphen/bar", "a/b/foo/with-hyphen/bar"); + check_normalizes_to("foo/with_underscore/bar", "a/b/foo/with_underscore/bar"); + check_normalizes_to(".foo/bar", "a/b/.foo/bar"); + check_normalizes_to("..foo/bar", "a/b/..foo/bar"); + check_normalizes_to(".", "a/b"); + + check_normalizes_to("foo//bar", "a/b/foo/bar"); + check_normalizes_to("foo/../bar", "a/b/bar"); + check_normalizes_to("foo/bar/", "a/b/foo/bar"); + check_normalizes_to("foo/./bar/", "a/b/foo/bar"); + check_normalizes_to("./foo", "a/b/foo"); + check_normalizes_to("foo///.//", "a/b/foo"); + check_normalizes_to("../foo", "a/foo"); + check_normalizes_to("..", "a"); + check_normalizes_to("../..", ""); + check_normalizes_to("MT/foo", "a/b/MT/foo"); + + path_prefix = ""; +} + static void test_split_join() { file_path fp1(internal, "foo/bar/baz"); @@ -143,7 +210,9 @@ I(suite); suite->add(BOOST_TEST_CASE(&test_null_name)); suite->add(BOOST_TEST_CASE(&test_file_path_internal)); - suite->add(BOOST_TEST_CASE(&test_file_path_external)); + suite->add(BOOST_TEST_CASE(&test_file_path_external_no_prefix)); + suite->add(BOOST_TEST_CASE(&test_file_path_external_prefix_a_b)); + suite->add(BOOST_TEST_CASE(&test_split_join)); } #endif // BUILD_UNIT_TESTS