ENH: added fileName::relative() method

- this currently just strips off the leading parent directory name

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

     relative("/this/path")  -> "and/subdirs/name"
     relative("/this")       -> "path/and/subdirs/name"
This commit is contained in:
Mark Olesen
2018-01-23 18:25:55 +01:00
parent e98ff5ec73
commit 9bd7ea593e
4 changed files with 97 additions and 33 deletions

View File

@ -161,6 +161,29 @@ unsigned testEquals
} }
unsigned testRelative(std::initializer_list<Pair<std::string>> tests)
{
Info<< nl << "Checking fileName::relative()" << nl << endl;
unsigned nFail = 0;
for (const Pair<std::string>& test : tests)
{
const std::string& dir = test.first();
const std::string& parent = test.second();
fileName relative = fileName(dir).relative(parent);
Info<< "directory: " << dir << nl
<< "parent : " << parent << nl
<< "relative = " << relative << nl
<< endl;
}
return nFail;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
@ -170,12 +193,13 @@ int main(int argc, char *argv[])
argList::addBoolOption("validate", "test fileName::validate"); argList::addBoolOption("validate", "test fileName::validate");
argList::addBoolOption("ext", "test handing of file extensions"); argList::addBoolOption("ext", "test handing of file extensions");
argList::addBoolOption("construct", "test constructors"); argList::addBoolOption("construct", "test constructors");
argList::addBoolOption("relative", "test relative operations");
argList::addBoolOption("default", "reinstate default tests"); argList::addBoolOption("default", "reinstate default tests");
argList::addNote("runs default tests or specified ones only"); argList::addNote("runs default tests or specified ones only");
#include "setRootCase.H" #include "setRootCase.H"
// Run default tests, unless only specific tests are requested // Run default tests, unless specific tests are requested
const bool defaultTests = const bool defaultTests =
args.found("default") || args.options().empty(); args.found("default") || args.options().empty();
@ -418,6 +442,49 @@ int main(int argc, char *argv[])
} }
if (args.found("relative"))
{
unsigned nFail = 0;
nFail += testRelative
(
{
{ "/some/dir/subdir/name", "" },
{ "/some/dir/subdir/name", "/" },
{ "/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/subdir/name" },
{ "/some/dir/subdir/name", "/some/dir/subdir/name/" },
{ "/some/dir/subdir/name", "/some/other" },
// With single-char for name
{ "/some/dir/subdir/a", "" },
{ "/some/dir/subdir/a", "/" },
{ "/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/subdir/a" },
{ "/some/dir/subdir/a", "/some/dir/subdir/a/" },
{ "/some/dir/subdir/a", "/some/other" },
// Bad input (trailing slash)
{ "/some/dir/subdir/a/", "" },
{ "/some/dir/subdir/a/", "/" },
{ "/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/subdir/a" },
{ "/some/dir/subdir/a/", "/some/dir/subdir/a/" },
{ "/some/dir/subdir/a/", "/some/other" },
}
);
}
if (!defaultTests) if (!defaultTests)
{ {
return 0; return 0;

View File

@ -320,31 +320,6 @@ vtk::outputOptions getOutputOptions(const argList& args)
} }
fileName relativeName(const fileName& parent, const fileName& file)
{
string::size_type next = parent.size();
if
(
file.startsWith(parent)
&& next < file.size()
&& file[next] == '/'
)
{
return file.substr(next+1);
}
else
{
return file;
}
}
fileName relativeName(const Time& runTime, const fileName& file)
{
return relativeName(runTime.path(), file);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -672,7 +647,7 @@ int main(int argc, char *argv[])
+ timeDesc + timeDesc
); );
Info<< " faceSet : " Info<< " faceSet : "
<< relativeName(runTime, outputName) << nl; << outputName.relative(runTime.path()) << nl;
vtk::writeFaceSet vtk::writeFaceSet
( (
@ -700,7 +675,7 @@ int main(int argc, char *argv[])
+ timeDesc + timeDesc
); );
Info<< " pointSet : " Info<< " pointSet : "
<< relativeName(runTime, outputName) << nl; << outputName.relative(runTime.path()) << nl;
vtk::writePointSet vtk::writePointSet
( (
@ -1095,7 +1070,7 @@ int main(int argc, char *argv[])
+ timeDesc + timeDesc
); );
Info<< " Internal : " Info<< " Internal : "
<< relativeName(runTime, outputName) << endl; << outputName.relative(runTime.path()) << nl;
// Write mesh // Write mesh
vtk::internalWriter writer vtk::internalWriter writer
@ -1255,7 +1230,7 @@ int main(int argc, char *argv[])
+ timeDesc + timeDesc
); );
Info<< " Combined patches : " Info<< " Combined patches : "
<< relativeName(runTime, outputName) << nl; << outputName.relative(runTime.path()) << nl;
vtk::patchWriter writer vtk::patchWriter writer
( (
@ -1325,7 +1300,7 @@ int main(int argc, char *argv[])
+ timeDesc + timeDesc
); );
Info<< " Patch : " Info<< " Patch : "
<< relativeName(runTime, outputName) << nl; << outputName.relative(runTime.path()) << nl;
vtk::patchWriter writer vtk::patchWriter writer
( (
@ -1426,7 +1401,7 @@ int main(int argc, char *argv[])
+ timeDesc + timeDesc
); );
Info<< " FaceZone : " Info<< " FaceZone : "
<< relativeName(runTime, outputName) << nl; << outputName.relative(runTime.path()) << nl;
indirectPrimitivePatch pp indirectPrimitivePatch pp
( (
@ -1472,7 +1447,7 @@ int main(int argc, char *argv[])
+ "_" + timeDesc + "_" + timeDesc
); );
Info<< " Lagrangian: " Info<< " Lagrangian: "
<< relativeName(runTime, outputName) << nl; << outputName.relative(runTime.path()) << nl;
IOobjectList cloudObjs IOobjectList cloudObjs
( (

View File

@ -404,6 +404,25 @@ Foam::fileName Foam::fileName::path() const
} }
Foam::fileName Foam::fileName::relative(const fileName& parent) const
{
const auto top = parent.size();
const fileName& f = *this;
// Everything after "parent/xxx" -> "xxx"
if
(
top && (f.size() > (top+1)) && (*this)[top] == '/'
&& f.startsWith(parent)
)
{
return f.substr(top+1);
}
return f;
}
Foam::fileName Foam::fileName::lessExt() const Foam::fileName Foam::fileName::lessExt() const
{ {
const auto i = find_ext(); const auto i = find_ext();

View File

@ -265,6 +265,9 @@ public:
//- Return directory path name (part before last /) //- Return directory path name (part before last /)
fileName path() const; fileName path() const;
//- Return name after stripping off the parent directory
fileName relative(const fileName& parent) const;
//- Return file name without extension (part before last .) //- Return file name without extension (part before last .)
fileName lessExt() const; fileName lessExt() const;