# # patch "ChangeLog" # from [ad6768ee6c369c78a61bd0082ec1a73e8b13d03a] # to [6aae9a37db052ff5ffdb7b1b52548b28a08a5269] # # patch "paths.cc" # from [6a502c6467846bc97bd637101a42571ba84020a1] # to [4e5102ee894c9a36efca874f1566b7f021b01069] # # patch "paths.hh" # from [62c42e07a3d83608626a02cf57f7148c5c66b5a2] # to [6a40d74b6c578436c71a44a123ab7f8553404ba0] # ======================================================================== --- ChangeLog ad6768ee6c369c78a61bd0082ec1a73e8b13d03a +++ ChangeLog 6aae9a37db052ff5ffdb7b1b52548b28a08a5269 @@ -1,3 +1,13 @@ +2005-09-30 Grahame Bowland + + * paths.cc (file_path::file_path): Allow external paths outside of + a working directory, so long as we don't enter a working directory + later. + (access_tracker) add new very_uninitialized state which + prevents subsequent initialization + (test_access_tracker) check the very_uninitialized state works + * paths.hh: correct mention of monotone cat file to new syntax + 2005-09-29 Matthew Gregan * paths.cc: Restore two unit tests on Win32. ======================================================================== --- paths.cc 6a502c6467846bc97bd637101a42571ba84020a1 +++ paths.cc 4e5102ee894c9a36efca874f1566b7f021b01069 @@ -27,6 +27,7 @@ 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 @@ 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, @@ -171,6 +177,18 @@ 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 @@ -935,6 +953,10 @@ 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); } void add_paths_tests(test_suite * suite) ======================================================================== --- paths.hh 62c42e07a3d83608626a02cf57f7148c5c66b5a2 +++ paths.hh 6a40d74b6c578436c71a44a123ab7f8553404ba0 @@ -52,7 +52,7 @@ // file_path_internal_from_user: use this for strings that come from // the user, _but_ are not referring to paths in the working copy, // but rather in some database object directly. for instance, 'cat -// file REV PATH' uses this function. this function is exactly like +// -r REV PATH' uses this function. this function is exactly like // file_path_internal, except that it raises N() errors rather than // I() errors. // file_path's also provide optimized splitting and joining