mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: additional fileName methods
- add an extension to the file name
- remove a file extension
- check if a file name has an extension
- check if a file name has a particular extension (as word),
or matches a particular grouping of extensions (as wordRe).
This commit is contained in:
@ -37,6 +37,7 @@ Description
|
||||
#include "IOstreams.H"
|
||||
#include "OSspecific.H"
|
||||
#include "POSIX.H"
|
||||
#include "Switch.H"
|
||||
#include "etcFiles.H"
|
||||
|
||||
using namespace Foam;
|
||||
@ -47,6 +48,7 @@ using namespace Foam;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::addBoolOption("ext", "test handing of file extensions");
|
||||
argList::addBoolOption("construct", "test constructors");
|
||||
argList::addBoolOption("default", "reinstate default tests");
|
||||
argList::addNote("runs default tests or specified ones only");
|
||||
@ -108,6 +110,131 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
// Test various ext() methods
|
||||
if (args.optionFound("ext"))
|
||||
{
|
||||
Info<<nl << nl << "handling of fileName extension" << nl;
|
||||
|
||||
fileName empty;
|
||||
fileName endWithDot("some.path/name.");
|
||||
fileName endWithSlash("some.path/");
|
||||
fileName input0("some.file/with.out/extension");
|
||||
fileName input1("path.to/media/image.png");
|
||||
|
||||
Info<<"File : " << input0 << " ext: "
|
||||
<< Switch(input0.hasExt())
|
||||
<< " = " << input0.ext() << nl;
|
||||
Info<<"File : " << input1 << " ext: "
|
||||
<< Switch(input1.hasExt())
|
||||
<< " = " << input1.ext() << nl;
|
||||
Info<<"File : " << endWithDot << " ext: "
|
||||
<< Switch(endWithDot.hasExt())
|
||||
<< " = " << endWithDot.ext() << " <-- perhaps return false?" << nl;
|
||||
Info<<"File : " << endWithSlash << " ext: "
|
||||
<< Switch(endWithSlash.hasExt())
|
||||
<< " = " << endWithSlash.ext() << nl;
|
||||
|
||||
|
||||
Info<<"Remove extension " << (input0.removeExt());
|
||||
Info<< " now: " << input0 << nl;
|
||||
|
||||
Info<<"Remove extension " << (input1.removeExt());
|
||||
Info<< " now: " << input1 << nl;
|
||||
|
||||
Info<<"Remove extension " << (endWithSlash.removeExt());
|
||||
Info<< " now: " << endWithSlash << nl;
|
||||
|
||||
wordList exts{ "jpg", "png", "txt", word::null };
|
||||
Info<<"Add extension(s): " << input1 << nl;
|
||||
for (const word& e : exts)
|
||||
{
|
||||
Info<<"<" << e << "> -> " << input1.ext(e) << nl;
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
|
||||
Info<<"Test hasExt(word)" << nl
|
||||
<<"~~~~~~~~~~~~~~~~~" << nl;
|
||||
Info<<"Has extension(s):" << nl
|
||||
<< "input: " << input1 << nl;
|
||||
for (const word& e : exts)
|
||||
{
|
||||
Info<<" '" << e << "' -> "
|
||||
<< Switch(input1.hasExt(e)) << nl;
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
Info<<"Has extension(s):" << nl
|
||||
<< "input: " << endWithDot << nl;
|
||||
for (const word& e : exts)
|
||||
{
|
||||
Info<<" '" << e << "' -> "
|
||||
<< Switch(endWithDot.hasExt(e)) << nl;
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
|
||||
Info<<"Test hasExt(wordRe)" << nl
|
||||
<<"~~~~~~~~~~~~~~~~~~~" << nl;
|
||||
|
||||
// A regex with a zero length matcher doesn't work at all:
|
||||
// eg "(png|jpg|txt|)" regex matcher itself
|
||||
|
||||
wordRe matcher0("()", wordRe::REGEXP);
|
||||
wordRe matcher1("(png|jpg|txt)", wordRe::REGEXP);
|
||||
wordRe matcher2("(png|txt)", wordRe::REGEXP);
|
||||
|
||||
Info<<"Has extension(s):" << nl
|
||||
<< "input: " << endWithDot << nl;
|
||||
Info<<" " << matcher0 << " -> "
|
||||
<< Switch(endWithDot.hasExt(matcher0)) << nl;
|
||||
Info<<" " << matcher1 << " -> "
|
||||
<< Switch(endWithDot.hasExt(matcher1)) << nl;
|
||||
Info<<" " << matcher2 << " -> "
|
||||
<< Switch(endWithDot.hasExt(matcher2)) << nl;
|
||||
|
||||
Info<< "input: " << input1 << nl;
|
||||
Info<<" " << matcher0 << " -> "
|
||||
<< Switch(input1.hasExt(matcher0)) << nl;
|
||||
Info<<" " << matcher1 << " -> "
|
||||
<< Switch(input1.hasExt(matcher1)) << nl;
|
||||
Info<<" " << matcher2 << " -> "
|
||||
<< Switch(input1.hasExt(matcher2)) << nl;
|
||||
Info<< nl;
|
||||
|
||||
Info<<"Remove extension(s):" << nl << "input: " << input1 << nl;
|
||||
while (!input1.empty())
|
||||
{
|
||||
if (input1.removeExt())
|
||||
{
|
||||
Info<< " -> " << input1 << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "stop> " << input1 << nl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
input0.clear();
|
||||
Info<<"test with zero-sized: " << input0 << nl;
|
||||
Info<<"add extension: " << input0.ext("abc") << nl;
|
||||
Info<< nl;
|
||||
|
||||
input0 = "this/";
|
||||
Info<<"test add after slash: " << input0 << nl;
|
||||
Info<<"add extension: " << input0.ext("abc")
|
||||
<< " <-- avoids accidentally creating hidden files" << nl;
|
||||
Info<< nl;
|
||||
|
||||
input0 = "this.file.";
|
||||
Info<<"test after dot: " << input0 << nl;
|
||||
Info<<"add extension: " << input0.ext("abc")
|
||||
<< " <-- No check for repeated dots (user error!)" << nl;
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
if (!defaultTests)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@ -27,6 +27,7 @@ License
|
||||
#include "wordList.H"
|
||||
#include "DynamicList.H"
|
||||
#include "OSspecific.H"
|
||||
#include "wordRe.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -303,9 +304,9 @@ Foam::fileName Foam::fileName::path() const
|
||||
|
||||
Foam::fileName Foam::fileName::lessExt() const
|
||||
{
|
||||
size_type i = find_last_of("./");
|
||||
size_type i = find_ext();
|
||||
|
||||
if (i == npos || i == 0 || operator[](i) == '/')
|
||||
if (i == npos)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
@ -318,9 +319,9 @@ Foam::fileName Foam::fileName::lessExt() const
|
||||
|
||||
Foam::word Foam::fileName::ext() const
|
||||
{
|
||||
size_type i = find_last_of("./");
|
||||
size_type i = find_ext();
|
||||
|
||||
if (i == npos || i == 0 || operator[](i) == '/')
|
||||
if (i == npos)
|
||||
{
|
||||
return word::null;
|
||||
}
|
||||
@ -331,6 +332,71 @@ Foam::word Foam::fileName::ext() const
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName& Foam::fileName::ext(const word& ending)
|
||||
{
|
||||
if (!ending.empty() && !empty() && operator[](size()-1) != '/')
|
||||
{
|
||||
append(".");
|
||||
append(ending);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::fileName::hasExt() const
|
||||
{
|
||||
return (find_ext() != npos);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::fileName::hasExt(const word& ending) const
|
||||
{
|
||||
size_type i = find_ext();
|
||||
if (i == npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++i; // Do next comparison *after* the dot
|
||||
return
|
||||
(
|
||||
// Lengths must match
|
||||
((size() - i) == ending.size())
|
||||
&& !compare(i, npos, ending)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::fileName::hasExt(const wordRe& ending) const
|
||||
{
|
||||
size_type i = find_ext();
|
||||
if (i == npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string end = substr(i+1, npos);
|
||||
return ending.match(end);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::fileName::removeExt()
|
||||
{
|
||||
const size_type i = find_ext();
|
||||
|
||||
if (i == npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->resize(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::fileName::components(const char delimiter) const
|
||||
{
|
||||
DynamicList<word> wrdList(20);
|
||||
|
||||
@ -57,6 +57,7 @@ template<class T> class UList;
|
||||
typedef List<word> wordList;
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
class wordRe;
|
||||
class fileName;
|
||||
|
||||
Istream& operator>>(Istream&, fileName&);
|
||||
@ -73,6 +74,10 @@ class fileName
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Find position of the file extension dot, return npos on failure.
|
||||
// A wrapped version of find_last_of("./") with additional logic.
|
||||
inline size_type find_ext() const;
|
||||
|
||||
//- Strip invalid characters
|
||||
inline void stripInvalid();
|
||||
|
||||
@ -104,35 +109,35 @@ public:
|
||||
inline fileName();
|
||||
|
||||
//- Construct as copy
|
||||
inline fileName(const fileName&);
|
||||
inline fileName(const fileName& fn);
|
||||
|
||||
//- Construct as copy of word
|
||||
inline fileName(const word&);
|
||||
inline fileName(const word& s);
|
||||
|
||||
//- Construct as copy of string
|
||||
inline fileName(const string&, const bool doStripInvalid=true);
|
||||
inline fileName(const string& s, const bool doStripInvalid=true);
|
||||
|
||||
//- Construct as copy of std::string
|
||||
inline fileName(const std::string&, const bool doStripInvalid=true);
|
||||
inline fileName(const std::string& s, const bool doStripInvalid=true);
|
||||
|
||||
//- Construct as copy of character array
|
||||
inline fileName(const char*, const bool doStripInvalid=true);
|
||||
inline fileName(const char* s, const bool doStripInvalid=true);
|
||||
|
||||
//- Construct by concatenating elements of wordList separated by '/'
|
||||
explicit fileName(const UList<word>&);
|
||||
explicit fileName(const UList<word>& lst);
|
||||
|
||||
//- Construct by concatenating words separated by '/'
|
||||
explicit fileName(std::initializer_list<word>);
|
||||
explicit fileName(std::initializer_list<word> lst);
|
||||
|
||||
|
||||
//- Construct from Istream
|
||||
fileName(Istream&);
|
||||
fileName(Istream& is);
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
//- Is this character valid for a fileName?
|
||||
inline static bool valid(char);
|
||||
inline static bool valid(char c);
|
||||
|
||||
//- Cleanup file name
|
||||
//
|
||||
@ -209,6 +214,24 @@ public:
|
||||
//- Return file name extension (part after last .)
|
||||
word ext() const;
|
||||
|
||||
//- Append a '.' and the ending, and return the object.
|
||||
// The '.' and ending will not be added when the ending is empty,
|
||||
// or when the file name is empty or ended with a '/'.
|
||||
fileName& ext(const word& ending);
|
||||
|
||||
//- Return true if it has an extension or simply ends with a '.'
|
||||
bool hasExt() const;
|
||||
|
||||
//- Return true if the extension is the same as the given ending.
|
||||
bool hasExt(const word& ending) const;
|
||||
|
||||
//- Return true if the extension matches the given ending.
|
||||
bool hasExt(const wordRe& ending) const;
|
||||
|
||||
//- Remove extension, returning true if string changed.
|
||||
bool removeExt();
|
||||
|
||||
|
||||
//- Return path components as wordList
|
||||
//
|
||||
// Behaviour:
|
||||
@ -222,29 +245,43 @@ public:
|
||||
wordList components(const char delimiter = '/') const;
|
||||
|
||||
//- Return a single component of the path
|
||||
word component(const size_type, const char delimiter='/') const;
|
||||
word component
|
||||
(
|
||||
const size_type cmpt,
|
||||
const char delimiter = '/'
|
||||
) const;
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
// Assignment
|
||||
|
||||
void operator=(const fileName&);
|
||||
void operator=(const word&);
|
||||
void operator=(const string&);
|
||||
void operator=(const std::string&);
|
||||
void operator=(const char*);
|
||||
//- Copy, no character validation required
|
||||
void operator=(const fileName& str);
|
||||
|
||||
//- Copy, no character validation required
|
||||
void operator=(const word& str);
|
||||
|
||||
//- Copy, stripping invalid characters
|
||||
void operator=(const string& str);
|
||||
|
||||
//- Copy, stripping invalid characters
|
||||
void operator=(const std::string& str);
|
||||
|
||||
//- Copy, stripping invalid characters
|
||||
void operator=(const char* str);
|
||||
|
||||
|
||||
// IOstream operators
|
||||
|
||||
friend Istream& operator>>(Istream&, fileName&);
|
||||
friend Ostream& operator<<(Ostream&, const fileName&);
|
||||
friend Istream& operator>>(Istream& is, fileName& fn);
|
||||
friend Ostream& operator<<(Ostream& os, const fileName& fn);
|
||||
};
|
||||
|
||||
|
||||
//- Assemble words and fileNames as pathnames by adding a '/' separator
|
||||
fileName operator/(const string&, const string&);
|
||||
//- Assemble words and fileNames as pathnames by adding a '/' separator.
|
||||
// No '/' separator is added if either argument is an empty string.
|
||||
fileName operator/(const string& a, const string& b);
|
||||
|
||||
|
||||
//- Recursively search the given directory for the file
|
||||
|
||||
@ -25,6 +25,21 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
inline std::string::size_type Foam::fileName::find_ext() const
|
||||
{
|
||||
const size_type i = find_last_of("./");
|
||||
|
||||
if (i == npos || i == 0 || operator[](i) == '/')
|
||||
{
|
||||
return npos;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::fileName::stripInvalid()
|
||||
{
|
||||
// skip stripping unless debug is active to avoid
|
||||
|
||||
@ -78,5 +78,3 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const fileName& fn)
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user