reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

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:
Msrc/api.cpp | 9++++++++-
Msrc/path.cpp | 32++++++++++++++++++++++++++++++++
Msrc/path.hpp | 2++
Mtest/path.cpp | 38++++++++++++++++++++++++++++++++++++--
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")); + } +}