summaryrefslogtreecommitdiff
path: root/src/pathutil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/pathutil.cc')
-rw-r--r--src/pathutil.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/pathutil.cc b/src/pathutil.cc
new file mode 100644
index 0000000..bb2b8e8
--- /dev/null
+++ b/src/pathutil.cc
@@ -0,0 +1,44 @@
+#include "common.hh"
+
+#include "pathutil.hh"
+#include "strutil.hh"
+
+#include <vector>
+
+namespace path {
+
+std::string cleanup(std::string_view path) {
+ auto trimmed_path = str::trim(path);
+ bool trailing = !trimmed_path.empty() && trimmed_path.back() == '/';
+ auto parts = str::split(trimmed_path, '/');
+ auto it = parts.begin();
+ while (it != parts.end()) {
+ if (it->empty() || *it == ".") {
+ if (it + 1 == parts.end())
+ trailing = true;
+ it = parts.erase(it);
+ } else if (*it == "..") {
+ if (it + 1 == parts.end())
+ trailing = true;
+ if (it > parts.begin()) {
+ it = parts.erase(it - 1, it);
+ } else {
+ it = parts.erase(it);
+ }
+ } else {
+ ++it;
+ }
+ }
+ if (parts.empty())
+ return "/";
+ std::string ret;
+ for (auto const& part : parts) {
+ ret.push_back('/');
+ ret.append(part);
+ }
+ if (trailing)
+ ret.push_back('/');
+ return ret;
+}
+
+} // namespace path