From 5cbb86ab1d4d10371fb765f4e283af47298fec34 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 30 Nov 2016 17:34:37 +0200 Subject: Implement path canonicalize() --- butl/buildfile | 4 ++-- butl/path | 27 ++++++++++++++++++++++++++- butl/path.ixx | 12 ++++++++++++ butl/process.cxx | 2 +- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/butl/buildfile b/butl/buildfile index 1607e7d..5c5aae3 100644 --- a/butl/buildfile +++ b/butl/buildfile @@ -53,11 +53,11 @@ if $abi_prerelease else lib{butl}: bin.lib.version = @-$abi_major.$abi_minor -cxx.poptions =+ -I$src_root +cxx.poptions =+ "-I$src_root" obja{*}: cxx.poptions += -DLIBBUTL_STATIC_BUILD objs{*}: cxx.poptions += -DLIBBUTL_SHARED_BUILD -lib{butl}: cxx.export.poptions = -I$src_root +lib{butl}: cxx.export.poptions = "-I$src_root" liba{butl}: cxx.export.poptions += -DLIBBUTL_STATIC libs{butl}: cxx.export.poptions += -DLIBBUTL_SHARED diff --git a/butl/path b/butl/path index d60938f..2a32c70 100644 --- a/butl/path +++ b/butl/path @@ -254,6 +254,24 @@ namespace butl return ln < rn ? -1 : (ln > rn ? 1 : 0); } + static void + canonicalize (string_type& s) + { + //canonicalize (s.data (), s.size ()); // C++17 + + for (size_t i (0), n (s.size ()); i != n; ++i) + if (is_separator (s[i]) && s[i] != directory_separator) + s[i] = directory_separator; + } + + static void + canonicalize (C* s, size_type n) + { + for (const C* e (s + n); s != e; ++s) + if (is_separator (*s) && *s != directory_separator) + *s = directory_separator; + } + // Get/set current working directory. Throw std::system_error to report // the underlying OS errors. // @@ -780,7 +798,14 @@ namespace butl reverse_iterator rend () const {return reverse_iterator (begin ());} public: - // Normalize the path and return*this. Normalization involves collapsing + // Canonicalize the path and return *this. Canonicalization involves + // converting all directory separators to the canonical form. Note that + // multiple directory separators are not collapsed. + // + basic_path& + canonicalize (); + + // Normalize the path and return *this. Normalization involves collapsing // the '.' and '..' directories if possible, collapsing multiple // directory separators, and converting all directory separators to the // canonical form. diff --git a/butl/path.ixx b/butl/path.ixx index 8004821..c87a376 100644 --- a/butl/path.ixx +++ b/butl/path.ixx @@ -217,6 +217,18 @@ namespace butl template inline basic_path& basic_path:: + canonicalize () + { + traits::canonicalize (this->path_); + + if (this->tsep_ > 1) // Non-canonical trailing separator. + this->tsep_ = 1; + + return *this; + } + + template + inline basic_path& basic_path:: complete () { if (relative ()) diff --git a/butl/process.cxx b/butl/process.cxx index 1a83481..c75cfbd 100644 --- a/butl/process.cxx +++ b/butl/process.cxx @@ -171,7 +171,7 @@ namespace butl ep = path (move (s)); // Move back into result. if (norm) - ep.normalize (); + ep.normalize (); //@@ NORM return exists (ep.string ().c_str ()); }; -- cgit v1.1