Repository: mesos Updated Branches: refs/heads/master ca30a421c -> 8bc1893f2
Added Path::dirname() and Path::basename(). Introducing Path::dirname() and Path::basename() as a thread safe replacement of the respective system functions. Also contains new tests covering corner cases. Review: https://reviews.apache.org/r/34256 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4c75b1a9 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4c75b1a9 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4c75b1a9 Branch: refs/heads/master Commit: 4c75b1a919e2ffaa9ab97973edfd8df335f5f911 Parents: ca30a42 Author: Till Toenshoff <[email protected]> Authored: Wed Jun 24 19:50:57 2015 +0200 Committer: Till Toenshoff <[email protected]> Committed: Wed Jun 24 19:50:58 2015 +0200 ---------------------------------------------------------------------- .../3rdparty/stout/include/stout/path.hpp | 73 +++++++++++++++++++- .../3rdparty/stout/tests/path_tests.cpp | 70 +++++++++++++++++++ 2 files changed, 142 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/4c75b1a9/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp index 59595c9..aa0d127 100644 --- a/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp +++ b/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp @@ -27,7 +27,78 @@ public: : value(strings::remove(path, "file://", strings::PREFIX)) {} // TODO(cmaloney): Add more useful operations such as 'absolute()' - // and 'basename', and 'dirname', etc. + // etc. + + // Like the standard '::basename()' except it is thread safe. + inline std::string basename() + { + if (value.empty()) { + return std::string("."); + } + + size_t end = value.size() - 1; + + // Remove trailing slashes. + if (value[end] == '/') { + end = value.find_last_not_of('/', end); + + // Paths containing only slashes result into "/". + if (end == std::string::npos) { + return std::string("/"); + } + } + + // 'start' should point towards the character after the last slash + // that is non trailing. + size_t start = value.find_last_of('/', end); + + if (start == std::string::npos) { + start = 0; + } else { + start++; + } + + return value.substr(start, end + 1 - start); + } + + // Like the standard '::dirname()' except it is thread safe. + inline std::string dirname() + { + if (value.empty()) { + return std::string("."); + } + + size_t end = value.size() - 1; + + // Remove trailing slashes. + if (value[end] == '/') { + end = value.find_last_not_of('/', end); + } + + // Remove anything trailing the last slash. + end = value.find_last_of('/', end); + + // Paths containing no slashes result in ".". + if (end == std::string::npos) { + return std::string("."); + } + + // Paths containing only slashes result in "/". + if (end == 0) { + return std::string("/"); + } + + // 'end' should point towards the last non slash character + // preceding the last slash. + end = value.find_last_not_of('/', end); + + // Paths containing no non slash characters result in "/". + if (end == std::string::npos) { + return std::string("/"); + } + + return value.substr(0, end + 1); + } const std::string value; }; http://git-wip-us.apache.org/repos/asf/mesos/blob/4c75b1a9/3rdparty/libprocess/3rdparty/stout/tests/path_tests.cpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/3rdparty/stout/tests/path_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/path_tests.cpp index 7dd2664..3007c2a 100644 --- a/3rdparty/libprocess/3rdparty/stout/tests/path_tests.cpp +++ b/3rdparty/libprocess/3rdparty/stout/tests/path_tests.cpp @@ -22,6 +22,76 @@ using std::string; using std::vector; +// Test many corner cases of Path::basename. +TEST(PathTest, Basename) +{ + // Empty path check. + EXPECT_EQ(".", Path("").basename()); + + // Check common path patterns. + EXPECT_EQ("/", Path("/").basename()); + EXPECT_EQ(".", Path(".").basename()); + EXPECT_EQ("..", Path("..").basename()); + + EXPECT_EQ("a", Path("a").basename()); + EXPECT_EQ("b", Path("a/b").basename()); + EXPECT_EQ("c", Path("a/b/c").basename()); + + // Check leading slashes get cleaned up properly. + EXPECT_EQ("a", Path("/a").basename()); + EXPECT_EQ("a", Path("//a").basename()); + EXPECT_EQ("a", Path("/a/").basename()); + EXPECT_EQ("c", Path("/a/b/c").basename()); + EXPECT_EQ("b", Path("/a/b").basename()); + EXPECT_EQ("b", Path("//a//b").basename()); + + // Check trailing slashes get cleaned up properly. + EXPECT_EQ("a", Path("a/").basename()); + EXPECT_EQ("c", Path("/a/b/c//").basename()); + EXPECT_EQ("c", Path("/a/b/c///").basename()); + EXPECT_EQ("/", Path("//").basename()); + EXPECT_EQ("/", Path("///").basename()); +} + + +// Test many corner cases of Path::dirname. +TEST(PathTest, Dirname) +{ + // Empty path check. + EXPECT_EQ(".", Path("").dirname()); + + // Check common path patterns. + EXPECT_EQ("/", Path("/").dirname()); + EXPECT_EQ(".", Path(".").dirname()); + EXPECT_EQ(".", Path("..").dirname()); + + EXPECT_EQ(".", Path("a").dirname()); + EXPECT_EQ("a", Path("a/b").dirname()); + EXPECT_EQ("a/b", Path("a/b/c/").dirname()); + + // Check leading slashes get cleaned up properly. + EXPECT_EQ("/", Path("/a").dirname()); + EXPECT_EQ("/", Path("//a").dirname()); + EXPECT_EQ("/", Path("/a/").dirname()); + EXPECT_EQ("/a", Path("/a/b").dirname()); + EXPECT_EQ("//a", Path("//a//b").dirname()); + EXPECT_EQ("/a/b", Path("/a/b/c").dirname()); + + // Check intermittent slashes get handled just like ::dirname does. + EXPECT_EQ("/a//b", Path("/a//b//c//").dirname()); + EXPECT_EQ("//a/b", Path("//a/b//c").dirname()); + + // Check trailing slashes get cleaned up properly. + EXPECT_EQ(".", Path("a/").dirname()); + EXPECT_EQ("a/b", Path("a/b/c").dirname()); + EXPECT_EQ("/a/b", Path("/a/b/c/").dirname()); + EXPECT_EQ("/a/b", Path("/a/b/c//").dirname()); + EXPECT_EQ("/a/b", Path("/a/b/c///").dirname()); + EXPECT_EQ("/", Path("//").dirname()); + EXPECT_EQ("/", Path("///").dirname()); +} + + TEST(PathTest, Join) { EXPECT_EQ("a/b/c", path::join("a", "b", "c"));
