diff options
-rw-r--r-- | raul/Path.hpp | 3 | ||||
-rw-r--r-- | raul/URI.hpp | 2 | ||||
-rw-r--r-- | src/Path.cpp | 25 | ||||
-rw-r--r-- | test/path_test.cpp | 4 | ||||
-rw-r--r-- | wscript | 2 |
5 files changed, 34 insertions, 2 deletions
diff --git a/raul/Path.hpp b/raul/Path.hpp index 91122c6..a00740a 100644 --- a/raul/Path.hpp +++ b/raul/Path.hpp @@ -134,6 +134,9 @@ public: Path operator+(const Path& p) const { return child(p); } + /** Return the lowest common ancestor of a and b. */ + static Path lca(const Path& a, const Path& b); + /** Return the symbol of this path (everything after the last '/'). * This is e.g. the "method name" for OSC paths, the filename * for filesystem paths, etc. diff --git a/raul/URI.hpp b/raul/URI.hpp index 90d285c..6a6b532 100644 --- a/raul/URI.hpp +++ b/raul/URI.hpp @@ -90,6 +90,8 @@ public: inline bool operator==(const URI& uri) const { return _str == uri._str; } inline bool operator!=(const URI& uri) const { return _str != uri._str; } + inline char operator[](int i) const { return _str[i]; } + inline size_t length() const { return str().length(); } inline size_t find(const std::string& s) const { return str().find(s); } inline size_t find_last_of(char c) const { return str().find_last_of(c); } diff --git a/src/Path.cpp b/src/Path.cpp index fff4fbd..1c2f394 100644 --- a/src/Path.cpp +++ b/src/Path.cpp @@ -1,5 +1,5 @@ /* This file is part of Raul. - * Copyright 2007-2011 David Robillard <http://drobilla.net> + * Copyright 2007-2012 David Robillard <http://drobilla.net> * * Raul is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software @@ -210,5 +210,28 @@ Path::is_parent_of(const Path& child) const return child.is_child_of(*this); } +Path +Path::lca(const Path& patha, const Path& pathb) +{ + const std::string a = patha.chop_scheme(); + const std::string b = pathb.chop_scheme(); + size_t len = std::min(a.length(), b.length()); + + size_t last_slash = 0; + for (size_t i = 0; i < len; ++i) { + if (a[i] == '/' && b[i] == '/') { + last_slash = i; + } + if (a[i] != b[i]) { + break; + } + } + + if (last_slash <= 1) { + return root(); + } + return Path(a.substr(0, last_slash)); +} + } // namespace Raul diff --git a/test/path_test.cpp b/test/path_test.cpp index 099b463..7df1acf 100644 --- a/test/path_test.cpp +++ b/test/path_test.cpp @@ -41,6 +41,10 @@ main() CHECK(Path("/foo").is_parent_of(Path("/foo/bar"))); CHECK(!(Path("/foo").is_parent_of(Path("/foo2")))); + CHECK(Path::lca(Path("/foo"), Path("/foo/bar/baz")) == Path("/")); + CHECK(Path::lca(Path("/foo/bar"), Path("/foo/bar/baz")) == Path("/foo")); + CHECK(Path::lca(Path("/foo/bar/quux"), Path("/foo/bar/baz")) == Path("/foo/bar")); + CHECK(!Path::is_valid("")); CHECK(!Path::is_valid("hello")); CHECK(!Path::is_valid("/foo/bar/")); @@ -5,7 +5,7 @@ from waflib.extras import autowaf as autowaf import waflib.Options as Options # Version of this package (even if built as a child) -RAUL_VERSION = '0.8.3' +RAUL_VERSION = '0.8.5' # Library version (UNIX style major, minor, micro) # major increment <=> incompatible changes |