ENH: add fileName::concat static method

- similar to the global '/' operator, but taking raw strings and not
  performing any stripping.

  Was previously a local function within POSIX.C, but it is useful enough
  to be in fileName itself.
This commit is contained in:
Mark Olesen
2019-04-05 09:42:25 +02:00
parent e2de66f18e
commit 02e26b3aed
3 changed files with 51 additions and 56 deletions

View File

@ -87,44 +87,6 @@ static bool cwdPreference_(Foam::debug::optimisationSwitch("cwd", 0));
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
// Like fileName "/" global operator, but retain any invalid characters
static inline Foam::fileName fileNameConcat
(
const std::string& a,
const std::string& b
)
{
if (a.size())
{
if (b.size())
{
// Two non-empty strings: can concatenate
if (a.back() == '/' || b.front() == '/')
{
return Foam::fileName(a + b, false);
}
else
{
return Foam::fileName(a + '/' + b, false);
}
}
// The second string was empty
return Foam::fileName(a, false);
}
if (b.size())
{
// The first string is empty
return Foam::fileName(b, false);
}
// Both strings are empty
return Foam::fileName();
}
// After a fork in system(), before the exec() do the following // After a fork in system(), before the exec() do the following
// - close stdin when executing in background (daemon-like) // - close stdin when executing in background (daemon-like)
// - redirect stdout to stderr when infoDetailLevel == 0 // - redirect stdout to stderr when infoDetailLevel == 0
@ -1273,7 +1235,7 @@ bool Foam::rmDir(const fileName& directory, const bool silent)
// otherwise we cannot subdirs with these types of names. // otherwise we cannot subdirs with these types of names.
// -> const fileName path = directory/name; <- // -> const fileName path = directory/name; <-
const fileName path(fileNameConcat(directory, item)); const fileName path(fileName::concat(directory, item));
if (path.type(false) == fileName::DIRECTORY) if (path.type(false) == fileName::DIRECTORY)
{ {

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2011, 2016-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011, 2016-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation | Copyright (C) 2011-2017 OpenFOAM Foundation
@ -56,7 +56,7 @@ Foam::fileName Foam::fileName::validate
// but silently removes bad characters // but silently removes bad characters
fileName out; fileName out;
out.resize(s.size()); out.resize(s.length());
std::string::size_type len = 0; std::string::size_type len = 0;
@ -99,6 +99,33 @@ Foam::fileName Foam::fileName::validate
} }
Foam::fileName Foam::fileName::concat
(
const std::string& s1,
const std::string& s2
)
{
const auto n1 = s1.length();
const auto n2 = s2.length();
fileName out;
out.reserve(n1 + n2 + 1);
out += s1;
if (n1 && n2 && s1.back() != '/' && s2.front() != '/')
{
// Add separator
out += '/';
}
out += s2;
// Could also remove trailing '/', if desired.
return out;
}
bool Foam::fileName::equals(const std::string& s1, const std::string& s2) bool Foam::fileName::equals(const std::string& s1, const std::string& s2)
{ {
// Do not use (s1 == s2) or s1.compare(s2) first since this would // Do not use (s1 == s2) or s1.compare(s2) first since this would
@ -107,8 +134,8 @@ bool Foam::fileName::equals(const std::string& s1, const std::string& s2)
std::string::size_type i1 = 0; std::string::size_type i1 = 0;
std::string::size_type i2 = 0; std::string::size_type i2 = 0;
const auto n1 = s1.size(); const auto n1 = s1.length();
const auto n2 = s2.size(); const auto n2 = s2.length();
//Info<< "compare " << s1 << " == " << s2 << endl; //Info<< "compare " << s1 << " == " << s2 << endl;
while (i1 < n1 && i2 < n2) while (i1 < n1 && i2 < n2)
@ -264,7 +291,7 @@ bool Foam::fileName::clean(std::string& str)
// Number of output characters // Number of output characters
auto nChar = top+1; auto nChar = top+1;
const auto maxLen = str.size(); const auto maxLen = str.length();
for (auto src = nChar; src < maxLen; /*nil*/) for (auto src = nChar; src < maxLen; /*nil*/)
{ {
@ -477,7 +504,7 @@ Foam::fileName& Foam::fileName::operator/=(const string& other)
s += '/'; s += '/';
} }
s.append(other); s += other;
} }
} }
else if (other.size()) else if (other.size())
@ -492,32 +519,32 @@ Foam::fileName& Foam::fileName::operator/=(const string& other)
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
Foam::fileName Foam::operator/(const string& a, const string& b) Foam::fileName Foam::operator/(const string& s1, const string& s2)
{ {
if (a.size()) if (s1.length())
{ {
if (b.size()) if (s2.length())
{ {
// Two non-empty strings: can concatenate // Two non-empty strings: can concatenate
if (a.back() == '/' || b.front() == '/') if (s1.back() == '/' || s2.front() == '/')
{ {
return fileName(a + b); return fileName(s1 + s2);
} }
else else
{ {
return fileName(a + '/' + b); return fileName(s1 + '/' + s2);
} }
} }
// The second string was empty // The second string was empty
return a; return s1;
} }
if (b.size()) if (s2.length())
{ {
// The first string is empty // The first string is empty
return b; return s2;
} }
// Both strings are empty // Both strings are empty

View File

@ -82,7 +82,7 @@ public:
}; };
// Static data members // Static Data Members
//- The typeName //- The typeName
static const char* const typeName; static const char* const typeName;
@ -149,6 +149,12 @@ public:
//- removing duplicate or trailing slashes, etc. //- removing duplicate or trailing slashes, etc.
static fileName validate(const std::string& s, const bool doClean=true); static fileName validate(const std::string& s, const bool doClean=true);
//- Join two strings with '/' as a path separator.
// No '/' separator is added if either argument is an empty string or
// if the arguments already had the path separator at the junction.
// Invalid characters are \em not stripped (ie, retained).
static fileName concat(const std::string& s1, const std::string& s2);
//- This is a specialized (possibly slower) version of compare() //- This is a specialized (possibly slower) version of compare()
//- that ignores duplicate or trailing slashes. //- that ignores duplicate or trailing slashes.
static bool equals(const std::string& s1, const std::string& s2); static bool equals(const std::string& s1, const std::string& s2);
@ -402,7 +408,7 @@ Ostream& operator<<(Ostream& os, const fileName& val);
//- Assemble words and fileNames as pathnames by adding a '/' separator. //- Assemble words and fileNames as pathnames by adding a '/' separator.
// No '/' separator is added if either argument is an empty string. // No '/' separator is added if either argument is an empty string.
fileName operator/(const string& a, const string& b); fileName operator/(const string& s1, const string& s2);
//- Recursively search the given directory for the file //- Recursively search the given directory for the file