From ace1743f7f78bb13f99553d6e97ad1beecf1ba99 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 13 Apr 2015 15:50:17 +0200 Subject: Add separate type to represent directory paths --- build/path.txx | 123 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 56 deletions(-) (limited to 'build/path.txx') diff --git a/build/path.txx b/build/path.txx index a8bf859..67a271d 100644 --- a/build/path.txx +++ b/build/path.txx @@ -6,43 +6,43 @@ namespace build { - template - basic_path basic_path:: + template + basic_path basic_path:: leaf () const { - size_type p (traits::rfind_separator (path_)); + size_type p (traits::rfind_separator (this->path_)); return p != string_type::npos - ? basic_path (path_.c_str () + p + 1, path_.size () - p - 1) + ? basic_path (this->path_.c_str () + p + 1, this->path_.size () - p - 1) : *this; } - template - basic_path basic_path:: + template + typename basic_path::dir_type basic_path:: directory () const { if (root ()) - return basic_path (); + return dir_type (); - size_type p (traits::rfind_separator (path_)); + size_type p (traits::rfind_separator (this->path_)); // Include the trailing slash so that we get correct behavior // if directory is root. // return p != string_type::npos - ? basic_path (path_.c_str (), p + 1) - : basic_path (); + ? dir_type (this->path_.c_str (), p + 1) + : dir_type (); } #ifdef _WIN32 - template - typename basic_path::string_type basic_path:: + template + typename basic_path::string_type basic_path:: posix_string () const { if (absolute ()) - throw invalid_basic_path (path_); + throw invalid_basic_path (this->path_); - string_type r (path_); + string_type r (this->path_); // Translate Windows-style separators to the POSIX ones. // @@ -54,30 +54,29 @@ namespace build } #endif - template - basic_path& basic_path:: - operator/= (basic_path const& r) + template + basic_path& basic_path:: + operator/= (basic_path const& r) { - if (r.absolute () && !path_.empty ()) // Allow ('' / '/foo'). + if (r.absolute () && !this->path_.empty ()) // Allow ('' / '/foo'). throw invalid_basic_path (r.path_); - if (path_.empty () || r.path_.empty ()) + if (this->path_.empty () || r.path_.empty ()) { - path_ += r.path_; + this->path_ += r.path_; return *this; } - if (!traits::is_separator (path_[path_.size () - 1])) - path_ += traits::directory_separator; - - path_ += r.path_; + if (!traits::is_separator (this->path_[this->path_.size () - 1])) + this->path_ += traits::directory_separator; + this->path_ += r.path_; return *this; } - template - basic_path basic_path:: - leaf (basic_path const& d) const + template + basic_path basic_path:: + leaf (basic_path const& d) const { size_type n (d.path_.size ()); @@ -85,9 +84,9 @@ namespace build return *this; if (!sub (d)) - throw invalid_basic_path (path_); + throw invalid_basic_path (this->path_); - size_type m (path_.size ()); + size_type m (this->path_.size ()); if (n != m #ifndef _WIN32 @@ -96,32 +95,32 @@ namespace build ) n++; // Skip the directory separator (unless it is POSIX root). - return basic_path (path_.c_str () + n, m - n); + return basic_path (this->path_.c_str () + n, m - n); } - template - basic_path basic_path:: - directory (basic_path const& l) const + template + typename basic_path::dir_type basic_path:: + directory (basic_path const& l) const { size_type n (l.path_.size ()); if (n == 0) - return *this; + return dir_type (this->path_); if (!sup (l)) - throw invalid_basic_path (path_); + throw invalid_basic_path (this->path_); - size_type m (path_.size ()); + size_type m (this->path_.size ()); if (n != m) n++; // Skip the directory separator. - return basic_path (path_.c_str (), m - n); + return dir_type (this->path_.c_str (), m - n); } - template - basic_path basic_path:: - relative (basic_path d) const + template + basic_path basic_path:: + relative (basic_path d) const { basic_path r; @@ -130,19 +129,19 @@ namespace build if (sub (d)) break; - r /= path (".."); + r /= basic_path (".."); // Roots of the paths do not match. // if (d.root ()) - throw invalid_basic_path (path_); + throw invalid_basic_path (this->path_); } return r / leaf (d); } - template - basic_path& basic_path:: + template + basic_path& basic_path:: normalize () { if (empty ()) @@ -153,11 +152,11 @@ namespace build typedef std::vector paths; paths ps; - for (size_type b (0), e (traits::find_separator (path_)), - n (path_.size ());; - e = traits::find_separator (path_, b)) + for (size_type b (0), e (traits::find_separator (this->path_)), + n (this->path_.size ());; + e = traits::find_separator (this->path_, b)) { - string_type s (path_, b, e == string_type::npos ? e : e - b); + string_type s (this->path_, b, e == string_type::npos ? e : e - b); ps.push_back (s); if (e == string_type::npos) @@ -165,7 +164,7 @@ namespace build ++e; - while (e < n && traits::is_separator (path_[e])) + while (e < n && traits::is_separator (this->path_[e])) ++e; if (e == n) @@ -200,7 +199,7 @@ namespace build // Cannot go past the root directory. // if (abs && r.size () == 1) - throw invalid_basic_path (path_); + throw invalid_basic_path (this->path_); r.pop_back (); continue; @@ -227,19 +226,31 @@ namespace build if (p.empty () && !r.empty ()) p += traits::directory_separator; // Root directory. - path_.swap (p); + this->path_.swap (p); return *this; } - template - void basic_path:: + template + void basic_path:: + current (basic_path const& p) + { + const string_type& s (p.string ()); + + if (s.empty ()) + throw invalid_basic_path (s); + + traits::current (s); + } + + template + void basic_path:: init () { // Strip trailing slashes except for the case where the single // slash represents the root directory. // - size_type n (path_.size ()); - for (; n > 1 && traits::is_separator (path_[n - 1]); --n) ; - path_.resize (n); + size_type n (this->path_.size ()); + for (; n > 1 && traits::is_separator (this->path_[n - 1]); --n) ; + this->path_.resize (n); } } -- cgit v1.1