ENH: extend fileName::relative() method

- optionally replace stripped parent directory with the \<case\> shortcut

    "/this/path/and/subdirs/name"

    relative("/this/path")        -> "and/subdirs/name"
    relative("/this/path", true)  -> "\<case\>/and/subdirs/name"
This commit is contained in:
Mark Olesen
2018-12-14 17:44:07 +01:00
parent db8ba80ae4
commit 2617c326d8
3 changed files with 43 additions and 9 deletions

View File

@ -204,11 +204,10 @@ unsigned testRelative(std::initializer_list<Pair<std::string>> tests)
const std::string& dir = test.first(); const std::string& dir = test.first();
const std::string& parent = test.second(); const std::string& parent = test.second();
fileName relative = fileName(dir).relative(parent);
Info<< "directory: " << dir << nl Info<< "directory: " << dir << nl
<< "parent : " << parent << nl << "parent : " << parent << nl
<< "relative = " << relative << nl << "relative = " << fileName(dir).relative(parent) << nl
<< "case-rel = " << fileName(dir).relative(parent, true) << nl
<< endl; << endl;
} }
@ -537,12 +536,17 @@ int main(int argc, char *argv[])
nFail += testRelative nFail += testRelative
( (
{ {
{ "", "" },
{ "", "/" },
{ "", "/some" },
{ "/some/dir/subdir/name", "" }, { "/some/dir/subdir/name", "" },
{ "/some/dir/subdir/name", "/" }, { "/some/dir/subdir/name", "/" },
{ "/some/dir/subdir/name", "/some" }, { "/some/dir/subdir/name", "/some" },
{ "/some/dir/subdir/name", "/some/" }, { "/some/dir/subdir/name", "/some/" },
{ "/some/dir/subdir/name", "/some/dir" }, { "/some/dir/subdir/name", "/some/dir" },
{ "/some/dir/subdir/name", "/some/dir/" }, { "/some/dir/subdir/name", "/some/dir/" },
{ "/some/dir/subdir/name", "/some/dir/subdir" },
{ "/some/dir/subdir/name", "/some/dir/subdir/name" }, { "/some/dir/subdir/name", "/some/dir/subdir/name" },
{ "/some/dir/subdir/name", "/some/dir/subdir/name/" }, { "/some/dir/subdir/name", "/some/dir/subdir/name/" },
{ "/some/dir/subdir/name", "/some/other" }, { "/some/dir/subdir/name", "/some/other" },
@ -554,6 +558,7 @@ int main(int argc, char *argv[])
{ "/some/dir/subdir/a", "/some/" }, { "/some/dir/subdir/a", "/some/" },
{ "/some/dir/subdir/a", "/some/dir" }, { "/some/dir/subdir/a", "/some/dir" },
{ "/some/dir/subdir/a", "/some/dir/" }, { "/some/dir/subdir/a", "/some/dir/" },
{ "/some/dir/subdir/a", "/some/dir/subdir" },
{ "/some/dir/subdir/a", "/some/dir/subdir/a" }, { "/some/dir/subdir/a", "/some/dir/subdir/a" },
{ "/some/dir/subdir/a", "/some/dir/subdir/a/" }, { "/some/dir/subdir/a", "/some/dir/subdir/a/" },
{ "/some/dir/subdir/a", "/some/other" }, { "/some/dir/subdir/a", "/some/other" },
@ -565,6 +570,7 @@ int main(int argc, char *argv[])
{ "/some/dir/subdir/a/", "/some/" }, { "/some/dir/subdir/a/", "/some/" },
{ "/some/dir/subdir/a/", "/some/dir" }, { "/some/dir/subdir/a/", "/some/dir" },
{ "/some/dir/subdir/a/", "/some/dir/" }, { "/some/dir/subdir/a/", "/some/dir/" },
{ "/some/dir/subdir/a/", "/some/dir/subdir/" },
{ "/some/dir/subdir/a/", "/some/dir/subdir/a" }, { "/some/dir/subdir/a/", "/some/dir/subdir/a" },
{ "/some/dir/subdir/a/", "/some/dir/subdir/a/" }, { "/some/dir/subdir/a/", "/some/dir/subdir/a/" },
{ "/some/dir/subdir/a/", "/some/other" }, { "/some/dir/subdir/a/", "/some/other" },

View File

@ -364,20 +364,38 @@ std::string Foam::fileName::nameLessExt(const std::string& str)
} }
Foam::fileName Foam::fileName::relative(const fileName& parent) const Foam::fileName Foam::fileName::relative
(
const fileName& parent,
const bool caseRelative
) const
{ {
const auto top = parent.size(); const auto top = parent.size();
const fileName& f = *this; const fileName& f = *this;
// Everything after "parent/xxx" -> "xxx" // Everything after "parent/xxx/yyy" -> "xxx/yyy"
//
// case-relative:
// "parent/xxx/yyy" -> "<case>/xxx/yyy"
if if
( (
top && (f.size() > (top+1)) && (*this)[top] == '/' top && (f.size() > (top+1)) && f[top] == '/'
&& f.startsWith(parent) && f.startsWith(parent)
) )
{
if (caseRelative)
{
return "<case>"/f.substr(top+1);
}
else
{ {
return f.substr(top+1); return f.substr(top+1);
} }
}
else if (caseRelative && f.size() && !f.isAbsolute())
{
return "<case>"/f;
}
return f; return f;
} }

View File

@ -290,8 +290,18 @@ public:
//- Remove leading path, returning true if string changed. //- Remove leading path, returning true if string changed.
inline bool removePath(); inline bool removePath();
//- Return name after stripping off the parent directory //- Return a relative name by stripping off the parent directory
fileName relative(const fileName& parent) const; //- where possible.
//
// \param parent the parent directory
// \param caseRelative replace the parent with \<case\> for later
// use with expand(), or prefix \<case\> if the file name was
// not an absolute location
fileName relative
(
const fileName& parent,
const bool caseRelative = false
) const;
//- Return file name without extension (part before last .) //- Return file name without extension (part before last .)
inline fileName lessExt() const; inline fileName lessExt() const;