diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2019-06-06 12:22:33 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2019-06-06 12:22:33 +0200 |
commit | d115cc49a5f91c9c547a7a4d27323f6ccc959da3 (patch) | |
tree | 29ae85b9b04779302b8be45aba81741f83155855 /libbutl/path.ixx | |
parent | c03300fe14e5caffbee87565b76a64febfc4313a (diff) |
Add path::abnormalities(), note on normalization and symlinks
Diffstat (limited to 'libbutl/path.ixx')
-rw-r--r-- | libbutl/path.ixx | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/libbutl/path.ixx b/libbutl/path.ixx index 9622a81..7786fbc 100644 --- a/libbutl/path.ixx +++ b/libbutl/path.ixx @@ -4,6 +4,120 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. { + // path_abnormality + // + + inline path_abnormality + operator& (path_abnormality x, path_abnormality y) + { + return x &= y; + } + + inline path_abnormality + operator| (path_abnormality x, path_abnormality y) + { + return x |= y; + } + + inline path_abnormality + operator&= (path_abnormality& x, path_abnormality y) + { + return x = static_cast<path_abnormality> ( + static_cast<std::uint16_t> (x) & + static_cast<std::uint16_t> (y)); + } + + inline path_abnormality + operator|= (path_abnormality& x, path_abnormality y) + { + return x = static_cast<path_abnormality> ( + static_cast<std::uint16_t> (x) | + static_cast<std::uint16_t> (y)); + } + + // path_traits + // + template <typename C> + inline bool path_traits<C>:: + normalized (const C* s, size_type n, bool sep) + { + // An early-return version of abnormalities(). + // + 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 (parent (p, m) || current (p, m)) + return false; + } + } + + // Last component. + // + const char* p (s + j); + size_t m (n - j); + + return !(parent (p, m) || current (p, m)); + } + + template <typename C> + inline path_abnormality path_traits<C>:: + abnormalities (const C* s, size_type n) + { + path_abnormality r (path_abnormality::none); + + 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 (c != directory_separator) + r |= path_abnormality::separator; + + const char* p (s + j); + size_t m (i - j); + j = i + 1; + + if (j != n && is_separator (s[j])) + r |= path_abnormality::separator; + + if (parent (p, m)) + r |= path_abnormality::parent; + else if (current (p, m)) + r |= path_abnormality::current; + } + } + + // Last component. + // + const char* p (s + j); + size_t m (n - j); + + if (parent (p, m)) + r |= path_abnormality::parent; + else if (current (p, m)) + r |= path_abnormality::current; + + return r; + } + #ifdef _WIN32 template <> inline char path_traits<char>:: @@ -20,6 +134,9 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. } #endif + // path + // + template <class C, class K1, class K2> inline basic_path<C, K1> path_cast_impl (const basic_path<C, K2>& p, basic_path<C, K1>*) @@ -92,6 +209,18 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. } template <typename C, typename K> + inline path_abnormality basic_path<C, K>:: + abnormalities () const + { + path_abnormality r (traits_type::abnormalities (this->path_)); + + if (this->tsep_ > 1) + r |= path_abnormality::separator; + + return r; + } + + template <typename C, typename K> inline bool basic_path<C, K>:: root () const { |