aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-08-27 10:19:38 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-08-27 10:19:38 +0200
commit584e8fce074286cbf1a5bf0c79265f789c050c59 (patch)
tree1e1d774ea0f916d7e1880442bee9b7a270876eda
parent5d7f4abad8b452490f19db16bed031392dc4d1fd (diff)
Add ability to pass alternative dir separator to path::canonicalize()
This, for example, can be used to make paths with forward slashes on Windows.
-rw-r--r--libbutl/path.ixx16
-rw-r--r--libbutl/path.mxx29
2 files changed, 32 insertions, 13 deletions
diff --git a/libbutl/path.ixx b/libbutl/path.ixx
index 8512286..9c96cfc 100644
--- a/libbutl/path.ixx
+++ b/libbutl/path.ixx
@@ -396,12 +396,20 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
template <typename C, typename K>
inline basic_path<C, K>& basic_path<C, K>::
- canonicalize ()
+ canonicalize (char ds)
{
- traits_type::canonicalize (this->path_);
+ traits_type::canonicalize (this->path_, ds);
- if (this->tsep_ > 1) // Non-canonical trailing separator.
- this->tsep_ = 1;
+ // Canonicalize the trailing separator if any.
+ //
+ if (this->tsep_ > 0)
+ {
+ auto dss (traits_type::directory_separators);
+ difference_type i (ds == '\0' ? 1 : strchr (dss, ds) - dss + 1);
+
+ if (this->tsep_ != i)
+ this->tsep_ = i;
+ }
return *this;
}
diff --git a/libbutl/path.mxx b/libbutl/path.mxx
index 1ee2a66..12479ce 100644
--- a/libbutl/path.mxx
+++ b/libbutl/path.mxx
@@ -12,6 +12,7 @@
#include <ostream>
#include <cstddef> // ptrdiff_t
#include <cstdint> // uint16_t
+#include <cstring> // str*()
#include <utility> // move(), swap()
#include <iterator>
#include <stdexcept> // invalid_argument
@@ -427,21 +428,27 @@ LIBBUTL_MODEXPORT namespace butl
}
static void
- canonicalize (string_type& s)
+ canonicalize (string_type& s, char ds = '\0')
{
//canonicalize (s.data (), s.size ()); // C++17
+ if (ds == '\0')
+ ds = directory_separator;
+
for (size_t i (0), n (s.size ()); i != n; ++i)
- if (is_separator (s[i]) && s[i] != directory_separator)
- s[i] = directory_separator;
+ if (is_separator (s[i]) && s[i] != ds)
+ s[i] = ds;
}
static void
- canonicalize (C* s, size_type n)
+ canonicalize (C* s, size_type n, char ds = '\0')
{
+ if (ds == '\0')
+ ds = directory_separator;
+
for (const C* e (s + n); s != e; ++s)
- if (is_separator (*s) && *s != directory_separator)
- *s = directory_separator;
+ if (is_separator (*s) && *s != ds)
+ *s = ds;
}
// Get/set current working directory. Throw std::system_error to report
@@ -1091,11 +1098,15 @@ LIBBUTL_MODEXPORT namespace butl
public:
// Canonicalize the path and return *this. Canonicalization involves
- // converting all directory separators to the canonical form. Note that
- // multiple directory separators are not collapsed.
+ // converting all directory separators to the canonical form (or to the
+ // alternative separator if specified). Note that multiple directory
+ // separators are not collapsed.
+ //
+ // Note that the alternative separator must be listed in path_trait::
+ // directory_separators.
//
basic_path&
- canonicalize ();
+ canonicalize (char dir_sep = '\0');
// Normalize the path and return *this. Normalization involves collapsing
// the '.' and '..' directories if possible, collapsing multiple