commit 193e849da95c65069f306748ef3a92dca23e2807
parent 644aa3eac196f790b983f69c5b43198b951873e6
Author: cfillion <cfillion@users.noreply.github.com>
Date: Fri, 2 Jun 2017 00:54:40 -0400
api: support absolute path given to GetOwner
Diffstat:
4 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/src/api.cpp b/src/api.cpp
@@ -122,9 +122,16 @@ DEFINE_API(bool, CompareVersions, ((const char*, ver1))((const char*, ver2))
DEFINE_API(int, GetOwner, ((const char*, fn))((char*, errorOut))((int, errorOut_sz)),
"Returns ID of the package owning the given file or 0 on error.",
{
+ Path path(fn);
+
+ const Path &rp = ReaPack::resourcePath();
+
+ if(path.startsWith(rp))
+ path.remove(0, rp.size());
+
try {
const Registry reg(Path::prefixRoot(Path::REGISTRY));
- const int owner = (int)reg.getOwner(Path(fn));
+ const int owner = (int)reg.getOwner(path);
if(!owner && errorOut)
snprintf(errorOut, errorOut_sz, "file is not owned by any package");
diff --git a/src/path.cpp b/src/path.cpp
@@ -105,6 +105,25 @@ void Path::clear()
m_parts.clear();
}
+void Path::remove(const size_t pos, size_t count)
+{
+ if(pos > size())
+ return;
+ else if(pos + count > size())
+ count = size() - pos;
+
+ auto begin = m_parts.begin();
+ advance(begin, pos);
+
+ auto end = begin;
+ advance(end, count);
+
+ m_parts.erase(begin, end);
+
+ if(!pos && m_absolute)
+ m_absolute = false;
+}
+
void Path::removeLast()
{
if(!empty())
@@ -161,6 +180,19 @@ string Path::last() const
return m_parts.back();
}
+bool Path::startsWith(const Path &o) const
+{
+ if(size() < o.size() || absolute() != o.absolute())
+ return false;
+
+ for(size_t i = 0; i < o.size(); i++) {
+ if(o[i] != at(i))
+ return false;
+ }
+
+ return true;
+}
+
bool Path::operator==(const Path &o) const
{
return m_parts == o.m_parts;
diff --git a/src/path.hpp b/src/path.hpp
@@ -37,6 +37,7 @@ public:
void append(const std::string &part, bool traversal = true);
void append(const Path &other);
+ void remove(size_t pos, size_t count);
void removeLast();
void clear();
@@ -49,6 +50,7 @@ public:
std::string join(const char sep = 0) const;
std::string first() const;
std::string last() const;
+ bool startsWith(const Path &) const;
bool operator==(const Path &) const;
bool operator!=(const Path &) const;
diff --git a/test/path.cpp b/test/path.cpp
@@ -228,7 +228,7 @@ TEST_CASE("directory traversal", M) {
}
}
-TEST_CASE("append full paths") {
+TEST_CASE("append full paths", M) {
Path a;
a += Path("a/b");
a.append(Path("c/d"));
@@ -237,9 +237,43 @@ TEST_CASE("append full paths") {
REQUIRE(a == Path("a/b/c/d/e/f"));
}
-TEST_CASE("temporary path") {
+TEST_CASE("temporary path", M) {
TempPath a(Path("hello/world"));
REQUIRE(a.target() == Path("hello/world"));
REQUIRE(a.temp() == Path("hello/world.part"));
}
+
+TEST_CASE("path starts with", M) {
+ const Path ref("a/b");
+
+ REQUIRE(ref.startsWith(ref));
+ REQUIRE(Path("a/b/c").startsWith(ref));
+ REQUIRE_FALSE(Path("/a/b/c").startsWith(ref));
+ REQUIRE_FALSE(Path("0/a/b/c").startsWith(ref));
+ REQUIRE_FALSE(Path("a").startsWith(ref));
+}
+
+TEST_CASE("remove path segments", M) {
+ Path path("/a/b/c/d/e");
+
+ SECTION("remove from start") {
+ path.remove(0, 1);
+ REQUIRE(path == Path("b/c/d/e"));
+ REQUIRE_FALSE(path.absolute());
+ }
+
+ SECTION("remove from middle") {
+ path.remove(1, 2);
+ REQUIRE(path == Path("/a/d/e"));
+#ifndef _WIN32
+ REQUIRE(path.absolute());
+#endif
+ }
+
+ SECTION("remove past the end") {
+ path.remove(4, 2);
+ path.remove(18, 1);
+ REQUIRE(path == Path("/a/b/c/d"));
+ }
+}