The unified diff between revisions [850c20aa..] and [a80e1661..] is displayed below. It can also be downloaded as a raw diff.
This diff has been restricted to the following files: 'paths.cc'
#
#
# patch "paths.cc"
# from [3ea54d2be240cc811a52130f6711f3c3ae410763]
# to [b77289a76e8d3c43a1dc2467c7b679c1aa6f9ca9]
#
============================================================
--- paths.cc 3ea54d2be240cc811a52130f6711f3c3ae410763
+++ paths.cc b77289a76e8d3c43a1dc2467c7b679c1aa6f9ca9
@@ -27,6 +27,7 @@ struct access_tracker
void set(T const & val, bool may_be_initialized)
{
I(may_be_initialized || !initialized);
+ I(!very_uninitialized);
I(!used);
initialized = true;
value = val;
@@ -42,14 +43,19 @@ struct access_tracker
I(initialized);
return value;
}
+ void may_not_initialize()
+ {
+ I(!initialized);
+ very_uninitialized = true;
+ }
// for unit tests
void unset()
{
- used = initialized = false;
+ used = initialized = very_uninitialized = false;
}
T value;
- bool initialized, used;
- access_tracker() : initialized(false), used(false) {};
+ bool initialized, used, very_uninitialized;
+ access_tracker() : initialized(false), used(false), very_uninitialized(false) {};
};
// paths to use in interpreting paths from various sources,
@@ -165,12 +171,19 @@ file_path::file_path(file_path::source_t
case internal:
data = path;
break;
- case internal_from_user:
- data = path;
- N(is_valid_internal(path),
- F("path '%s' is invalid") % path);
- break;
case external:
+ if (!initial_rel_path.initialized)
+ {
+ // we are not in a working directory; treat this as an internal
+ // path, and set the access_tracker() into a very uninitialised
+ // state so that we will hit an exception if we do eventually
+ // enter a working directory
+ initial_rel_path.may_not_initialize();
+ data = path;
+ N(is_valid_internal(path),
+ F("path '%s' is invalid") % path);
+ break;
+ }
N(!path.empty(), F("empty path '%s' is invalid") % path);
fs::path out, base, relative;
try
@@ -392,7 +405,11 @@ normalize_out_dots(std::string const & p
static std::string
normalize_out_dots(std::string const & path)
{
+#ifdef WIN32
+ return fs::path(path, fs::native).normalize().string();
+#else
return fs::path(path, fs::native).normalize().native_file_string();
+#endif
}
system_path::system_path(any_path const & other, bool in_true_working_copy)
@@ -530,16 +547,12 @@ static void test_file_path_internal()
for (char const ** c = baddies; *c; ++c)
{
BOOST_CHECK_THROW(file_path_internal(*c), std::logic_error);
- BOOST_CHECK_THROW(file_path_internal_from_user(std::string(*c)),
- informative_failure);
}
initial_rel_path.unset();
initial_rel_path.set(file_path_internal("blah/blah/blah"), true);
for (char const ** c = baddies; *c; ++c)
{
BOOST_CHECK_THROW(file_path_internal(*c), std::logic_error);
- BOOST_CHECK_THROW(file_path_internal_from_user(std::string(*c)),
- informative_failure);
}
BOOST_CHECK(file_path().empty());
@@ -583,8 +596,6 @@ static void test_file_path_internal()
for (std::vector<path_component>::const_iterator i = split_test.begin();
i != split_test.end(); ++i)
BOOST_CHECK(!null_name(*i));
- file_path fp_user = file_path_internal_from_user(std::string(*c));
- BOOST_CHECK(fp == fp_user);
}
}
@@ -649,7 +660,9 @@ static void test_file_path_external_no_p
check_fp_normalizes_to(".foo/bar", ".foo/bar");
check_fp_normalizes_to("..foo/bar", "..foo/bar");
check_fp_normalizes_to(".", "");
+#ifndef WIN32
check_fp_normalizes_to("foo:bar", "foo:bar");
+#endif
check_fp_normalizes_to("foo/with,other+@weird*%#$=stuff/bar",
"foo/with,other+@weird*%#$=stuff/bar");
@@ -698,7 +711,9 @@ static void test_file_path_external_pref
check_fp_normalizes_to(".foo/bar", "a/b/.foo/bar");
check_fp_normalizes_to("..foo/bar", "a/b/..foo/bar");
check_fp_normalizes_to(".", "a/b");
+#ifndef WIN32
check_fp_normalizes_to("foo:bar", "a/b/foo:bar");
+#endif
check_fp_normalizes_to("foo/with,other+@weird*%#$=stuff/bar",
"a/b/foo/with,other+@weird*%#$=stuff/bar");
// why are the tests with // in them commented out? because boost::fs sucks
@@ -845,13 +860,13 @@ static void test_system_path()
#ifdef WIN32
check_system_normalizes_to("c:foo", "c:foo");
check_system_normalizes_to("c:/foo", "c:/foo");
- check_system_normalizes_to("c:\\foo", "c:\\foo");
+ check_system_normalizes_to("c:\\foo", "c:/foo");
#else
check_system_normalizes_to("c:foo", "/a/b/c:foo");
check_system_normalizes_to("c:/foo", "/a/b/c:/foo");
check_system_normalizes_to("c:\\foo", "/a/b/c:\\foo");
+ check_system_normalizes_to("foo:bar", "/a/b/foo:bar");
#endif
- check_system_normalizes_to("foo:bar", "/a/b/foo:bar");
// we require that system_path normalize out ..'s, because of the following
// case:
// /work mkdir newdir
@@ -870,13 +885,17 @@ static void test_system_path()
// can't do particularly interesting checking of tilde expansion, but at
// least we can check that it's doing _something_...
std::string tilde_expanded = system_path("~/foo").as_external();
+#ifdef WIN32
+ BOOST_CHECK(tilde_expanded[1] == ':');
+#else
BOOST_CHECK(tilde_expanded[0] == '/');
+#endif
BOOST_CHECK(tilde_expanded.find('~') == std::string::npos);
// and check for the weird WIN32 version
#ifdef WIN32
std::string tilde_expanded2 = system_path("~this_user_does_not_exist_anywhere").as_external();
BOOST_CHECK(tilde_expanded2[0] = '/');
- BOOST_CHECK(tilde_expanded.find('~') == std::string::npos);
+ BOOST_CHECK(tilde_expanded2.find('~') == std::string::npos);
#else
BOOST_CHECK_THROW(system_path("~this_user_does_not_exist_anywhere"), informative_failure);
#endif
@@ -923,6 +942,13 @@ static void test_access_tracker()
BOOST_CHECK_THROW(a.set(3, false), std::logic_error);
BOOST_CHECK(a.get() == 2);
BOOST_CHECK_THROW(a.set(3, true), std::logic_error);
+ a.unset();
+ a.may_not_initialize();
+ BOOST_CHECK_THROW(a.set(1, false), std::logic_error);
+ BOOST_CHECK_THROW(a.set(2, true), std::logic_error);
+ a.unset();
+ a.set(1, false);
+ BOOST_CHECK_THROW(a.may_not_initialize(), std::logic_error);
}
void add_paths_tests(test_suite * suite)