Skip to content

Commit

Permalink
--Internal tool to rebuild an abs path to be relative to another abs …
Browse files Browse the repository at this point in the history
…path.
  • Loading branch information
jturner65 committed May 21, 2024
1 parent 2561215 commit 03bc117
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
41 changes: 41 additions & 0 deletions src/esp/io/Io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,47 @@ std::string normalizePath(const std::string& srcPath) {
return normalizePath(filteredPath);
} // normalizePath

std::string getPathRelativeToAbsPath(const std::string& toRelPath,
const std::string& absPath) {
std::string result = "";
const char* delim = "/";

std::vector<std::string> absDirs =
Cr::Utility::String::split(absPath, delim[0]),
relDirs =
Cr::Utility::String::split(toRelPath, delim[0]);
auto absIter = absDirs.cbegin();
auto relIter = relDirs.cbegin();

// find where both paths diverge - skip shared path components
while (*relIter == *absIter && absIter != absDirs.cend() &&
relIter != relDirs.cend()) {
++relIter;
++absIter;
}

// Add back-path components for each directory in abspath not found in
// toRelPaath
while (absIter != absDirs.cend()) {
if (*absIter != *absDirs.crbegin()) {
Cr::Utility::formatInto(result, result.size(), "..{}", delim);
}
++absIter;
}
std::string scratch = "";
// build relative path in scratch
while (relIter != relDirs.cend()) {
if (*relIter == *relDirs.crbegin()) {
Cr::Utility::formatInto(result, result.size(), "{}{}", scratch,
*relDirs.crbegin());
} else {
Cr::Utility::formatInto(scratch, scratch.size(), "{}{}", *relIter, delim);
}
++relIter;
}
return result;
} // getPathRelativeToAbsPath

std::vector<std::string> globDirs(const std::string& pattern) {
// Check for ellipsis, if so process here.
glob_t glob_result;
Expand Down
10 changes: 10 additions & 0 deletions src/esp/io/Io.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ std::string changeExtension(const std::string& file, const std::string& ext);
*/
std::string normalizePath(const std::string& srcPath);

/**
* @brief This function will find the relative path of @p toRelPath relative to
* @p absPath
* @param toRelPath The absolute path to be converted to relative
* @param absPath The absolute path the conversion should be relative to
* @return the relative path of @p toRelPath relative to @p absPath
*/
std::string getPathRelativeToAbsPath(const std::string& toRelPath,
const std::string& absPath);

/**
* @brief This function will perform [glob-based pattern matching]
* (https://en.wikipedia.org/wiki/Glob_(programming)) to find and return all the
Expand Down
26 changes: 24 additions & 2 deletions src/tests/IOTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const std::string dataDir = Corrade::Utility::Path::join(SCENE_DATASETS, "../");
struct IOTest : Cr::TestSuite::Tester {
explicit IOTest();
void fileReplaceExtTest();
void absToRelativePathConverison();
void testEllipsisFilter();
void parseURDF();
void testJson();
Expand All @@ -52,8 +53,8 @@ struct IOTest : Cr::TestSuite::Tester {
};

IOTest::IOTest() {
addTests({&IOTest::fileReplaceExtTest, &IOTest::testEllipsisFilter,
&IOTest::parseURDF, &IOTest::testJson,
addTests({&IOTest::fileReplaceExtTest, &IOTest::absToRelativePathConverison,
&IOTest::testEllipsisFilter, &IOTest::parseURDF, &IOTest::testJson,
&IOTest::testJsonBuiltinTypes, &IOTest::testJsonStlTypes,
&IOTest::testJsonMagnumTypes, &IOTest::testJsonEspTypes,
&IOTest::testJsonUserType});
Expand Down Expand Up @@ -137,6 +138,27 @@ void IOTest::testEllipsisFilter() {

} // IOTest::testEllipsisFilter

void IOTest::absToRelativePathConverison() {
// Test conversion of an absolute path to a path relative to another path.
// Path to be relative to
const std::string absPathTarget = "/aa/bb/cc/dd/ee/ff/gg/";

// Path to convert
std::string absPathToConvert = "/aa/bb/cc/dd/xx/yy/zz/";
// Result of conversion
std::string relPathToBaseTarget =
esp::io::getPathRelativeToAbsPath(absPathToConvert, absPathTarget);

CORRADE_COMPARE(relPathToBaseTarget, "../../../xx/yy/zz/");

absPathToConvert = "/aa/bb/cc/../dd/xx/yy/zz/";
relPathToBaseTarget =
esp::io::getPathRelativeToAbsPath(absPathToConvert, absPathTarget);

CORRADE_COMPARE(relPathToBaseTarget, "../../../../../dd/xx/yy/zz/");

} // IOTest::absToRelativePathConverison

void IOTest::parseURDF() {
const std::string iiwaURDF = Cr::Utility::Path::join(
TEST_ASSETS, "urdf/kuka_iiwa/model_free_base.urdf");
Expand Down

0 comments on commit 03bc117

Please sign in to comment.