# # patch "ChangeLog" # from [c73d7f2f3040f470e0397daee99c108e6de69a8c] # to [b7e175d10a92e15e3e360ef589191d5d48c08f5c] # # patch "paths.cc" # from [1b8efd6d58a39573b4530e38ec5c20547eb836c2] # to [02b9bf1f7db2f48dc950e9ec0d8499c9ef0bf50f] # # patch "paths.hh" # from [65fe38f882aa870f80172d5ca3deb33ffa1613a4] # to [14a123196045205e5dc96fe888c6ee081101e271] # ======================================================================== --- ChangeLog c73d7f2f3040f470e0397daee99c108e6de69a8c +++ ChangeLog b7e175d10a92e15e3e360ef589191d5d48c08f5c @@ -1,5 +1,10 @@ 2005-08-24 Nathaniel Smith + * paths.{cc,hh}: Reorganize a bit. Implement file_path and + bookkeeping_path. + +2005-08-24 Nathaniel Smith + * paths.cc (file_path): Implement basic constructor. Misc compile fixes. Add single-character names to tests. ======================================================================== --- paths.cc 1b8efd6d58a39573b4530e38ec5c20547eb836c2 +++ paths.cc 02b9bf1f7db2f48dc950e9ec0d8499c9ef0bf50f @@ -45,73 +45,6 @@ static const bool is_win32 = false; #endif -bool -find_and_go_to_working_copy(system_path const & search_root) -{ - // unimplemented - fs::path root = search_root.as_external(); - fs::path bookdir = bookkeeping_root.as_external(); - fs::path current = fs::initial_path(); - fs::path removed; - fs::path check = current / bookdir; - - L(F("searching for '%s' directory with root '%s'\n") - % bookdir.string() - % root.string()); - - while (current != root - && current.has_branch_path() - && current.has_leaf() - && !fs::exists(check)) - { - L(F("'%s' not found in '%s' with '%s' removed\n") - % bookdir.string() % current.string() % removed.string()); - removed = fs::path(current.leaf(), fs::native) / removed; - current = current.branch_path(); - check = current / bookdir; - } - - L(F("search for '%s' ended at '%s' with '%s' removed\n") - % bookdir.string() % current.string() % removed.string()); - - if (!fs::exists(check)) - { - L(F("'%s' does not exist\n") % check.string()); - return false; - } - - if (!fs::is_directory(check)) - { - L(F("'%s' is not a directory\n") % check.string()); - return false; - } - - // check for MT/. and MT/.. to see if mt dir is readable - if (!fs::exists(check / ".") || !fs::exists(check / "..")) - { - L(F("problems with '%s' (missing '.' or '..')\n") % check.string()); - return false; - } - - working_root = current.native_file_string(); - initial_rel_path = file_path_internal(removed.string()); - - L(F("working root is '%s'") % working_root); - L(F("initial relative path is '%s'") % initial_rel_path); - - change_current_working_dir(working_root); - - return true; -} - -void -go_to_working_copy(system_path const & new_working_copy) -{ - working_root = new_working_copy; - initial_rel_path = file_path(); - change_current_working_dir(new_working_copy); -} - static bool is_absolute(std::string const & path) { @@ -214,6 +147,12 @@ tmp = tmp.normalize(); data = utf8(tmp.string()); } + assert_sane(); +} + +void +file_path::assert_sane() +{ I(fully_normalized_path(data())); I(not_in_bookkeeping_dir(data())); } @@ -327,9 +266,97 @@ static inline std::string operator_slash(any_path const & path, std::string appended) { + I(false); + //FIXME +} + +file_path +file_path::operator /(std::string const & to_append) +{ + return file_path_internal(data() + "/" + to_append); +} + +bookkeeping_path +bookkeeping_path::operator /(std::string const & to_append) +{ + return bookkeeping_path(data() + "/" + to_append); +} + +/////////////////////////////////////////////////////////////////////////// +// working copy (and path roots) handling +/////////////////////////////////////////////////////////////////////////// + +bool +find_and_go_to_working_copy(system_path const & search_root) +{ + // unimplemented + fs::path root = search_root.as_external(); + fs::path bookdir = bookkeeping_root.as_external(); + fs::path current = fs::initial_path(); + fs::path removed; + fs::path check = current / bookdir; + L(F("searching for '%s' directory with root '%s'\n") + % bookdir.string() + % root.string()); + + while (current != root + && current.has_branch_path() + && current.has_leaf() + && !fs::exists(check)) + { + L(F("'%s' not found in '%s' with '%s' removed\n") + % bookdir.string() % current.string() % removed.string()); + removed = fs::path(current.leaf(), fs::native) / removed; + current = current.branch_path(); + check = current / bookdir; + } + + L(F("search for '%s' ended at '%s' with '%s' removed\n") + % bookdir.string() % current.string() % removed.string()); + + if (!fs::exists(check)) + { + L(F("'%s' does not exist\n") % check.string()); + return false; + } + + if (!fs::is_directory(check)) + { + L(F("'%s' is not a directory\n") % check.string()); + return false; + } + + // check for MT/. and MT/.. to see if mt dir is readable + if (!fs::exists(check / ".") || !fs::exists(check / "..")) + { + L(F("problems with '%s' (missing '.' or '..')\n") % check.string()); + return false; + } + + working_root = current.native_file_string(); + initial_rel_path = file_path_internal(removed.string()); + + L(F("working root is '%s'") % working_root); + L(F("initial relative path is '%s'") % initial_rel_path); + + change_current_working_dir(working_root); + + return true; } +void +go_to_working_copy(system_path const & new_working_copy) +{ + working_root = new_working_copy; + initial_rel_path = file_path(); + change_current_working_dir(new_working_copy); +} + +/////////////////////////////////////////////////////////////////////////// +// tests +/////////////////////////////////////////////////////////////////////////// + #ifdef BUILD_UNIT_TESTS #include "unit_tests.hh" ======================================================================== --- paths.hh 65fe38f882aa870f80172d5ca3deb33ffa1613a4 +++ paths.hh 14a123196045205e5dc96fe888c6ee081101e271 @@ -32,6 +32,7 @@ { public: // converts to native charset and path syntax + // this is a path that you can pass to the operating system std::string as_external() const; // leaves as utf8 std::string const & as_internal() const @@ -40,9 +41,11 @@ { return data().empty(); } protected: utf8 data; - any_path(); - any_path(any_path const & other); - any_path & operator=(any_path const & other); + any_path() {} + any_path(any_path const & other) + : data(other.data) {} + any_path & operator=(any_path const & other) + { data = other.data; } }; std::ostream & operator<<(std::ostream & o, any_path const & a); @@ -50,10 +53,11 @@ class file_path : public any_path { public: - file_path(); + file_path() {} // join a file_path out of pieces file_path(std::vector const & pieces); + // this currently doesn't do any normalization or anything. file_path operator /(std::string const & to_append) const; void split(std::vector & pieces) const; @@ -100,14 +104,12 @@ // and _should_ look like an internal path // usually you should just use the / operator as a constructor! bookkeeping_path(std::string const & path); - bookkeeping_path(utf8 const & path); - std::string as_external() const; bookkeeping_path operator /(std::string const & to_append) const; }; extern bookkeeping_path const bookkeeping_root; - // this will always be an absolute path +// this will always be an absolute path class system_path : public any_path { public: