aboutsummaryrefslogtreecommitdiff
path: root/libbutl/path.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-08-05 18:19:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-08-05 18:19:28 +0200
commit07f657754b0af656ee48c38540805fcec7cee27d (patch)
tree46ee0de36bb9005a6bfc9a53624ad7444e1a0c62 /libbutl/path.hxx
parentc291ac321aa9863c515f84ba0b8b1599c5da2c9a (diff)
Implement path::normalized() predicate
Diffstat (limited to 'libbutl/path.hxx')
-rw-r--r--libbutl/path.hxx48
1 files changed, 48 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.
//