diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-08-05 18:19:28 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-08-05 18:19:28 +0200 |
commit | 07f657754b0af656ee48c38540805fcec7cee27d (patch) | |
tree | 46ee0de36bb9005a6bfc9a53624ad7444e1a0c62 | |
parent | c291ac321aa9863c515f84ba0b8b1599c5da2c9a (diff) |
Implement path::normalized() predicate
-rw-r--r-- | libbutl/path.hxx | 48 | ||||
-rw-r--r-- | libbutl/path.ixx | 8 |
2 files changed, 56 insertions, 0 deletions
diff --git a/libbutl/path.hxx b/libbutl/path.hxx index 26b076f..342a188 100644 --- a/libbutl/path.hxx +++ b/libbutl/path.hxx @@ -146,6 +146,46 @@ namespace butl } static bool + normalized (const string_type& s, bool sep) + { + return normalized (s.c_str (), s.size (), sep); + } + + static bool + normalized (const C* s, size_type n, bool sep) + { + size_t j (0); // Beginning of path component. + + for (size_t i (0); i != n; ++i) + { + char c (s[i]); + + if (is_separator (c)) + { + if (sep && c != directory_separator) + return false; + + const char* p (s + j); + size_t m (i - j); + j = i + 1; + + if (j != n && is_separator (s[j])) + return false; + + if (current (p, m) || parent (p, m)) + return false; + } + } + + // Last component. + // + const char* p (s + j); + size_t m (n - j); + + return !(current (p, m) || parent (p, m)); + } + + static bool root (const string_type& s) { return root (s.c_str (), s.size ()); @@ -657,6 +697,14 @@ namespace butl bool parent () const; + // Return true if the path is normalized, that is, does not contain any + // current or parent directory components or multiple consecutive and, + // unless sep is false, non-canonical directory separators. Empty path + // is considered normalized. + // + bool + normalized (bool sep = true) const; + // Test, based on the presence/absence of the trailing separator, if the // path is to a directory. // diff --git a/libbutl/path.ixx b/libbutl/path.ixx index c140d1e..7227b72 100644 --- a/libbutl/path.ixx +++ b/libbutl/path.ixx @@ -102,6 +102,14 @@ namespace butl template <typename C, typename K> inline bool basic_path<C, K>:: + normalized (bool sep) const + { + return (!sep || this->tsep_ <= 1) && + traits::normalized (this->path_, sep); + } + + template <typename C, typename K> + inline bool basic_path<C, K>:: root () const { return traits::root (this->path_); |