Add split(path) -> vector

master
Charles Aylward 2015-02-28 12:04:21 -08:00
parent 38932e8dd3
commit 7df436b8d1
2 changed files with 49 additions and 1 deletions

View File

@ -19,7 +19,6 @@
#include <string>
#include <vector>
#include <sys/stat.h>
namespace pathname {
@ -55,6 +54,37 @@ inline std::string join(const std::string& first, const std::string& second, con
}
inline std::string join(const std::vector<std::string>& entries) {
if (entries.empty()) return "";
if (entries.size() == 1) return entries[0];
if (entries.size() == 2) return join(entries[0], entries[1]);
std::vector<std::string> next{join(entries[0], entries[1])};
next.insert(next.end(), entries.begin() + 2, entries.end());
return join(next);
}
inline std::vector<std::string> split(const std::string& path) {
if (path == "/") return { path };
std::vector<std::string> entries;
size_t last = 0;
size_t next = 0;
std::string trimmed = trim_trailing_slash(path);
if (trimmed.empty()) return { "/" };
for (auto c : trimmed) {
next++;
if (c == separator) {
if (next == 1) entries.push_back("/");
else entries.push_back(trimmed.substr(last, next - last - 1));
last = next;
}
}
entries.push_back(trimmed.substr(last));
return entries;
}
inline std::string base(const std::string& path) {
if (path.length() == 1 && path[0] == separator) return path;
if (*path.crbegin() == separator) return ".";

View File

@ -29,6 +29,24 @@ TEST(pathname, join) {
}
TEST(pathname, split) {
using V = std::vector<std::string>;
ASSERT_EQ(V({"/"}), pathname::split("/"));
ASSERT_EQ(V({"/"}), pathname::split("//"));
ASSERT_EQ(V({"one"}), pathname::split("one"));
ASSERT_EQ(V({"/", "one"}), pathname::split("/one"));
ASSERT_EQ(V({"one", "two"}), pathname::split("one/two"));
ASSERT_EQ(V({"/", "one", "two"}), pathname::split("/one/two"));
ASSERT_EQ(V({"/", "one", "two", "three"}), pathname::split("/one/two/three"));
ASSERT_EQ(V({"/", "one", "two", "three"}), pathname::split("/one/two/three/"));
}
TEST(pathname, split_join_inverse) {
ASSERT_EQ("/one/two/three", pathname::join(pathname::split("/one/two/three/")));
}
TEST(pathname, base) {
ASSERT_EQ(".", pathname::base("/one/two/three/"));
ASSERT_EQ("three", pathname::base("/one/two/three"));