# # # patch "legacy.hh" # from [ac212b607bc1c4cf3a77093e0cd540762eeebf3e] # to [73a19d21617f8484dd425f245942a212f9070d98] # # patch "paths.cc" # from [b6d28155242ac7acc36b8f32b83cedb7bd77b7fa] # to [3ef5b269b34464ce341cc7acdb56f8e166690da5] # # patch "paths.hh" # from [c5a8bc83f09a17ab6250ef7dcfdab6317f43e08f] # to [4d95cee5f8bb191423762ac0a7c8c6967b3f44a1] # ============================================================ --- legacy.hh ac212b607bc1c4cf3a77093e0cd540762eeebf3e +++ legacy.hh 73a19d21617f8484dd425f245942a212f9070d98 @@ -15,6 +15,7 @@ #include #include "paths.hh" +#include "vocab.hh" class app_state; ============================================================ --- paths.cc b6d28155242ac7acc36b8f32b83cedb7bd77b7fa +++ paths.cc 3ef5b269b34464ce341cc7acdb56f8e166690da5 @@ -322,28 +322,28 @@ path_component::path_component(utf8 cons // but is not acceptable to bad_component (above) and therefore we have // to open-code most of those checks. path_component::path_component(utf8 const & d) - : data(d) + : data(d()) { MM(data); - I(!has_bad_component_chars(data()) && data() != "." && data() != ".."); + I(!has_bad_component_chars(data) && data != "." && data != ".."); } path_component::path_component(string const & d) : data(d) { MM(data); - I(utf8_validate(data) - && !has_bad_component_chars(data()) - && data() != "." && data() != ".."); + I(utf8_validate(utf8(data)) + && !has_bad_component_chars(data) + && data != "." && data != ".."); } path_component::path_component(char const * d) : data(d) { MM(data); - I(utf8_validate(data) - && !has_bad_component_chars(data()) - && data() != "." && data() != ".."); + I(utf8_validate(utf8(data)) + && !has_bad_component_chars(data) + && data != "." && data != ".."); } std::ostream & operator<<(std::ostream & s, path_component const & pc) @@ -369,20 +369,38 @@ file_path::file_path(file_path::source_t string normalized; normalize_external_path(path, normalized); N(!in_bookkeeping_dir(normalized), - F("path '%s' is in bookkeeping dir") % data); - data = utf8(normalized); + F("path '%s' is in bookkeeping dir") % normalized); + data = normalized; } else - data = utf8(path); + data = path; MM(data); - I(is_valid_internal(data())); + I(is_valid_internal(data)); } +file_path::file_path(file_path::source_type type, utf8 const & path) +{ + MM(path); + I(utf8_validate(path)); + if (type == external) + { + string normalized; + normalize_external_path(path(), normalized); + N(!in_bookkeeping_dir(normalized), + F("path '%s' is in bookkeeping dir") % normalized); + data = normalized; + } + else + data = path(); + MM(data); + I(is_valid_internal(data)); +} + bookkeeping_path::bookkeeping_path(string const & path) { I(fully_normalized_path(path)); I(in_bookkeeping_dir(path)); - data = utf8(path); + data = path; } bool @@ -412,7 +430,7 @@ any_path::basename() const path_component any_path::basename() const { - string const & s = data(); + string const & s = data; string::size_type sep = s.rfind('/'); if (sep == string::npos) return path_component(s, 0); // force use of short circuit @@ -429,7 +447,7 @@ file_path::dirname() const file_path file_path::dirname() const { - string const & s = data(); + string const & s = data; string::size_type sep = s.rfind('/'); if (sep == string::npos) return file_path(); @@ -440,7 +458,7 @@ file_path::dirname_basename(file_path & void file_path::dirname_basename(file_path & dir, path_component & base) const { - string const & s = data(); + string const & s = data; string::size_type sep = s.rfind('/'); if (sep == string::npos) { @@ -459,11 +477,11 @@ file_path::depth() const unsigned int file_path::depth() const { - if (data().empty()) + if (data.empty()) return 0; unsigned int components = 1; - for (string::const_iterator p = data().begin(); p != data().end(); p++) + for (string::const_iterator p = data.begin(); p != data.end(); p++) if (*p == '/') components++; @@ -481,13 +499,13 @@ any_path::as_external() const #ifdef __APPLE__ // on OS X paths for the filesystem/kernel are UTF-8 encoded, regardless of // locale. - return data(); + return data; #else // on normal systems we actually have some work to do, alas. // not much, though, because utf8_to_system_string does all the hard work. // it is carefully optimized. do not screw it up. external out; - utf8_to_system_strict(data, out); + utf8_to_system_strict(utf8(data), out); return out(); #endif } @@ -577,7 +595,7 @@ file_path::operator /(path_component con return file_path(s, 0, string::npos); } else - return file_path(data() + "/" + to_append(), 0, string::npos); + return file_path(data + "/" + to_append(), 0, string::npos); } // similarly, but even less checking is needed. @@ -587,7 +605,7 @@ file_path::operator /(file_path const & I(!to_append.empty()); if (empty()) return to_append; - return file_path(data() + "/" + to_append.as_internal(), 0, string::npos); + return file_path(data + "/" + to_append.as_internal(), 0, string::npos); } // these take strings and do validation themselves. @@ -596,7 +614,7 @@ bookkeeping_path::operator /(string cons { I(!is_absolute_somewhere(to_append)); I(!empty()); - return bookkeeping_path(data() + "/" + to_append); + return bookkeeping_path(data + "/" + to_append); } system_path @@ -604,7 +622,7 @@ system_path::operator /(string const & t { I(!empty()); I(!is_absolute_here(to_append)); - return system_path(data() + "/" + to_append); + return system_path(data + "/" + to_append); } /////////////////////////////////////////////////////////////////////////// @@ -626,7 +644,7 @@ system_path::system_path(any_path const if (is_absolute_here(other.as_internal())) // another system_path. the normalizing isn't really necessary, but it // makes me feel warm and fuzzy. - data = utf8(normalize_out_dots(other.as_internal())); + data = normalize_out_dots(other.as_internal()); else { system_path wr; @@ -634,7 +652,7 @@ system_path::system_path(any_path const wr = working_root.get(); else wr = working_root.get_but_unused(); - data = utf8(normalize_out_dots((wr / other.as_internal()).as_internal())); + data = normalize_out_dots((wr / other.as_internal()).as_internal()); } } @@ -650,12 +668,12 @@ system_path::system_path(string const & system_path::system_path(string const & path) { - data = utf8(const_system_path(utf8(path))); + data = const_system_path(utf8(path)); } system_path::system_path(utf8 const & path) { - data = utf8(const_system_path(utf8(path))); + data = const_system_path(utf8(path)); } /////////////////////////////////////////////////////////////////////////// ============================================================ --- paths.hh c5a8bc83f09a17ab6250ef7dcfdab6317f43e08f +++ paths.hh 4d95cee5f8bb191423762ac0a7c8c6967b3f44a1 @@ -96,12 +96,10 @@ // i.e., nothing fancy necessary, for purposes of F() just treat it like // it were a string - -#include "vocab.hh" - class any_path; class file_path; class roster_t; +class utf8; // A path_component is one component of a path. It is always utf8, may not // contain either kind of slash, and may not be a magic directory entry ("." @@ -117,19 +115,19 @@ public: explicit path_component(std::string const &); explicit path_component(char const *); - std::string const & operator()() const { return data(); } - bool empty() const { return data().empty(); } + std::string const & operator()() const { return data; } + bool empty() const { return data.empty(); } bool operator<(path_component const & other) const - { return data() < other(); } + { return data < other(); } bool operator==(path_component const & other) const - { return data() == other(); } + { return data == other(); } bool operator!=(path_component const & other) const - { return data() != other(); } + { return data != other(); } friend std::ostream & operator<<(std::ostream &, path_component const &); private: - utf8 data; + std::string data; // constructor for use by trusted operations. bypasses validation. path_component(std::string const & path, @@ -156,13 +154,13 @@ public: std::string as_external() const; // leaves as utf8 std::string const & as_internal() const - { return data(); } + { return data; } bool empty() const - { return data().empty(); } + { return data.empty(); } // returns the trailing component of the path path_component basename() const; protected: - utf8 data; + std::string data; any_path() {} any_path(any_path const & other) : data(other.data) {} @@ -202,10 +200,10 @@ public: // see the "ordering" unit test in paths.cc. bool operator <(const file_path & other) const { - std::string::const_iterator p = data().begin(); - std::string::const_iterator plim = data().end(); - std::string::const_iterator q = other.data().begin(); - std::string::const_iterator qlim = other.data().end(); + std::string::const_iterator p = data.begin(); + std::string::const_iterator plim = data.end(); + std::string::const_iterator q = other.data.begin(); + std::string::const_iterator qlim = other.data.end(); while (*p == *q && p != plim && q != qlim) p++, q++; @@ -231,7 +229,7 @@ public: return static_cast(*p) < static_cast(*q); } - void clear() { data = utf8(); } + void clear() { data.clear(); } private: typedef enum { internal, external } source_type; @@ -246,6 +244,7 @@ private: // -- are confirmed to be normalized and relative // -- not to be in _MTN/ file_path(source_type type, std::string const & path); + file_path(source_type type, utf8 const & path); friend file_path file_path_internal(std::string const & path); friend file_path file_path_external(utf8 const & path); @@ -255,7 +254,7 @@ private: std::string::size_type start, std::string::size_type stop = std::string::npos) { - data = utf8(path.substr(start, stop)); + data = path.substr(start, stop); } // roster_t::get_name is allowed to use the private substring constructor. @@ -269,7 +268,7 @@ inline file_path file_path_external(utf8 } inline file_path file_path_external(utf8 const & path) { - return file_path(file_path::external, path()); + return file_path(file_path::external, path); } class bookkeeping_path : public any_path