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"));

Reply via email to