ENH: add testing for directory lister class

This commit is contained in:
Mark Olesen 2018-01-10 15:01:12 +01:00
parent eb7f6d2406
commit 2feb11dbeb
7 changed files with 948 additions and 0 deletions

View File

@ -0,0 +1,144 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "DirLister.H"
#include <dirent.h>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
static const Foam::word extgz("gz");
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
bool Foam::DirLister::const_iterator::open(const fileName& dir)
{
if (!dir.empty())
{
dirptr_ = ::opendir(dir.c_str());
}
return dirptr_;
}
void Foam::DirLister::const_iterator::close()
{
if (dirptr_)
{
::closedir(dirptr_);
dirptr_ = nullptr;
}
}
Foam::word Foam::DirLister::next(DIR* dirPtr) const
{
// Read next entry in the directory
struct dirent *list;
while (dirPtr && (list = ::readdir(dirPtr)) != nullptr)
{
const std::string item(list->d_name);
// Ignore files/directories beginning with "."
// These are the ".", ".." directories and any hidden files/dirs
if (item.empty() || item[0] == '.')
{
continue;
}
// Validate filename without spaces, quotes, etc in the name.
// No duplicate slashes to strip - dirent will not have them anyhow.
word name(fileName::validate(item));
if (name != item)
{
// ++nFailed_;
continue;
}
bool ok = false;
fileName::Type fType = fileName::UNDEFINED;
if
(
(requestedType_ == fileName::DIRECTORY)
|| (requestedType_ == fileName::FILE && !fileName::isBackup(name))
)
{
fType = (dirName_/name).type(followLink_);
// A DIRECTORY or FILE was request, so only accept the same type
ok = (requestedType_ == fType);
}
else if (requestedType_ == fileName::UNDEFINED)
{
fType = (dirName_/name).type(followLink_);
// An UNDEFINED type was requested, so accept DIRECTORY or FILE
ok =
(
(fType == fileName::DIRECTORY)
|| (fType == fileName::FILE && !fileName::isBackup(name))
);
}
if (ok)
{
if (fType == fileName::FILE && stripgz_ && name.hasExt(extgz))
{
name = name.lessExt();
}
if (!name.empty() && accept(name))
{
return name;
}
}
}
return word();
}
// * * * * * * * * * * * * * * * Const Iterator * * * * * * * * * * * * * * //
bool Foam::DirLister::const_iterator::next()
{
if (lister_ && dirptr_)
{
name_ = lister_->next(dirptr_);
if (name_.empty())
{
close();
}
}
return dirptr_;
}
// ************************************************************************* //

View File

@ -0,0 +1,306 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::DirLister
Description
A class for listing directory contents, or obtaining a list of
directory contents.
For many situations, the iterator-based access is the most convenient
since it allows use of a range-for without any intermediate variables
or allocations.
List all directories or files:
\code
for (const word& item : DirLister("."))
{
Info<< "dir or file: " << item << nl;
}
\endcode
List files or directories only:
\code
for (const word& item : DirLister(".").files())
{
Info<< "file: " << item << nl;
}
for (const word& item : DirLister(".").dirs())
{
Info<< "dir: " << item << nl;
}
\endcode
These can be combined with a unary predicate to select only specific
items:
\code
{
wordReList matchProcs
{
wordRe("processors"),
wordRe("processor\\d+", wordRe::REGEX)
};
for
(
const word& item
: DirLister::dirs(".").where(wordRes(matchProcs))
)
{
Info<< "processor dir: " << item << nl;
}
}
\endcode
The unary predicate can similarly be used with the list or sorted
methods:
\code
{
wordReList matchProcs
{
wordRe("processor[0-9][0-9]*", wordRe::REGEX),
wordRe("processors")
};
fileNameList procDirs
(
DirLister::dirs(".").sorted<fileName>(wordRes(matchProcs))
);
}
\endcode
See Also
Foam::readDir
SourceFiles
DirListerI.H
DirLister.C
DirListerTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef DirLister_H
#define DirLister_H
#include "fileNameList.H"
#include "wordList.H"
#include <dirent.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class DirLister Declaration
\*---------------------------------------------------------------------------*/
class DirLister
{
// Private data
fileName dirName_;
fileName::Type requestedType_;
bool followLink_;
bool stripgz_;
protected:
// Protected Member Functions
//- Placeholder for additional selection filters
virtual inline bool accept(const word& name) const;
//- Traverse to next entry
word next(DIR* dirPtr) const;
public:
//- Specialization for filtering with a predicate
template<class UnaryPredicate> class Filtered;
// Constructors
//- Construct from components - list files and directories
inline DirLister
(
const fileName& directory,
const fileName::Type = fileName::UNDEFINED,
const bool filtergz = true,
const bool followLink = true
);
//- Convenience constructor for listing directories
inline static DirLister dirs
(
const fileName& directory,
const bool followLink = true
);
//- Convenience constructor for listing files
inline static DirLister files
(
const fileName& directory,
const bool filtergz = true,
const bool followLink = true
);
//- Convenience for constructing a filtered iterator
template<class UnaryPredicate>
inline Filtered<UnaryPredicate> where
(
const UnaryPredicate& pred,
const bool prune = false
) const;
//- Destructor
virtual ~DirLister() = default;
// Member Functions
//- Return the directory name
inline const fileName& dirName() const;
//- Return a complete list of names
template<class StringType=Foam::word>
List<StringType> list() const;
//- Return complete list of names
template<class StringType=Foam::word, class UnaryPredicate>
List<StringType> list
(
const UnaryPredicate& pred,
const bool prune = false
) const;
//- Return a complete list of names, sorted in natural order
template<class StringType=Foam::word>
List<StringType> sorted() const;
//- Return complete list of names, sorted in natural order
template<class StringType=Foam::word, class UnaryPredicate>
List<StringType> sorted
(
const UnaryPredicate& pred,
const bool prune = false
) const;
// Iterators
//- Const iterator for traversing directory contents
class const_iterator
{
const DirLister* lister_;
DIR* dirptr_;
word name_;
//- Open directory and set dirptr_ (nullptr on failure)
bool open(const fileName& dir);
//- Close dirptr_
void close();
bool next();
public:
//- Construct end iterator
inline const_iterator();
//- Construct begin iterator
inline const_iterator(const DirLister* lister);
//- Destructor
inline ~const_iterator();
inline const_iterator& operator++();
inline const word& operator*() const;
inline bool operator==(const const_iterator& iter) const;
inline bool operator!=(const const_iterator& iter) const;
};
inline const_iterator cbegin() const;
inline const_iterator cend() const;
inline const_iterator begin() const;
inline const_iterator end() const;
};
//- A DirLister specialization for filtering with a predicate
template<class UnaryPredicate>
class DirLister::Filtered
:
public DirLister
{
const UnaryPredicate& pred_;
bool prune_;
protected:
friend class DirLister;
virtual inline bool accept(const word& name) const;
//- Constructor
inline Filtered
(
const DirLister& lister,
const UnaryPredicate& pred,
const bool prune = false
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "DirListerI.H"
#ifdef NoRepository
#include "DirListerTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,203 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
inline bool Foam::DirLister::accept(const word& name) const
{
return true;
}
template<class UnaryPredicate>
inline bool Foam::DirLister::Filtered<UnaryPredicate>::accept
(
const word& name
) const
{
return (pred_(name) ? !prune_ : prune_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::DirLister::DirLister
(
const fileName& directory,
const fileName::Type requestedType,
const bool filtergz,
const bool followLink
)
:
dirName_(directory),
requestedType_(requestedType),
followLink_(followLink),
stripgz_(filtergz)
{}
inline Foam::DirLister Foam::DirLister::dirs
(
const fileName& directory,
const bool followLink
)
{
return DirLister(directory, fileName::DIRECTORY, false, followLink);
}
inline Foam::DirLister Foam::DirLister::files
(
const fileName& directory,
const bool filtergz,
const bool followLink
)
{
return DirLister(directory, fileName::FILE, filtergz, followLink);
}
template<class UnaryPredicate>
inline Foam::DirLister::Filtered<UnaryPredicate>::Filtered
(
const Foam::DirLister& lister,
const UnaryPredicate& pred,
const bool prune
)
:
DirLister(lister),
pred_(pred),
prune_(prune)
{}
template<class UnaryPredicate>
inline Foam::DirLister::Filtered<UnaryPredicate>
Foam::DirLister::where(const UnaryPredicate& pred, const bool prune) const
{
return DirLister::Filtered<UnaryPredicate>(*this, pred, prune);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::fileName& Foam::DirLister::dirName() const
{
return dirName_;
}
// * * * * * * * * * * * * * * * Const Iterator * * * * * * * * * * * * * * //
inline Foam::DirLister::const_iterator::const_iterator()
:
lister_(nullptr),
dirptr_(nullptr),
name_()
{}
inline Foam::DirLister::const_iterator::const_iterator
(
const Foam::DirLister* lister
)
:
lister_(lister),
dirptr_(nullptr),
name_()
{
if (lister_ && open(lister_->dirName()))
{
next(); // increment to first entry
}
}
inline Foam::DirLister::const_iterator::~const_iterator()
{
close();
}
inline const Foam::word& Foam::DirLister::const_iterator::operator*() const
{
return name_;
}
Foam::DirLister::const_iterator&
Foam::DirLister::const_iterator::operator++()
{
next();
return *this;
}
inline bool Foam::DirLister::const_iterator::operator==
(
const const_iterator& iter
)
const
{
// Directory entries are unique, so just compare the names
return (name_ == iter.name_);
}
inline bool Foam::DirLister::const_iterator::operator!=
(
const const_iterator& iter
)
const
{
return name_ != iter.name_;
}
inline Foam::DirLister::const_iterator Foam::DirLister::cbegin() const
{
return const_iterator(this);
}
inline Foam::DirLister::const_iterator Foam::DirLister::cend() const
{
return const_iterator();
}
inline Foam::DirLister::const_iterator Foam::DirLister::begin() const
{
return cbegin();
}
inline Foam::DirLister::const_iterator Foam::DirLister::end() const
{
return cend();
}
// ************************************************************************* //

View File

@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "predicates.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class StringType, class UnaryPredicate>
Foam::List<StringType> Foam::DirLister::list
(
const UnaryPredicate& pred,
const bool prune
) const
{
// Initial list size and resizing increment
static const int incr = 100;
List<StringType> lst(incr);
label nItems = 0;
for (const auto& item: *this)
{
if (pred(item) ? !prune : prune)
{
if (nItems >= lst.size())
{
lst.setSize(lst.size() + incr);
}
lst[nItems++] = item;
}
}
lst.setSize(nItems);
return lst;
}
template<class StringType>
Foam::List<StringType> Foam::DirLister::list() const
{
return list<StringType>(predicates::always());
}
template<class StringType, class UnaryPredicate>
Foam::List<StringType> Foam::DirLister::sorted
(
const UnaryPredicate& pred,
const bool prune
) const
{
List<StringType> lst(list<StringType>(pred, prune));
sort(lst, stringOps::natural_sort());
return lst;
}
template<class StringType>
Foam::List<StringType> Foam::DirLister::sorted() const
{
return sorted<StringType>(predicates::always());
}
// ************************************************************************* //

View File

@ -0,0 +1,4 @@
Test-DirLister.C
DirLister.C
EXE = $(FOAM_USER_APPBIN)/Test-DirLister

View File

@ -0,0 +1,2 @@
/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
/* EXE_LIBS = -lfiniteVolume */

View File

@ -0,0 +1,198 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Test functionality of DirLister
\*---------------------------------------------------------------------------*/
#include "DirLister.H"
#include "fileNameList.H"
#include "wordRes.H"
#include "predicates.H"
#include "FlatOutput.H"
#include "error.H"
#include "stringOps.H"
#include "scalar.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
{
Info<< nl
<< "List items" << nl
<< "~~~~~~~~~~" << nl;
for (const word& item : DirLister("."))
{
Info<< " " << item << nl;
}
}
{
Info<< nl
<< "List files" << nl
<< "~~~~~~~~~~" << nl;
for (const word& item : DirLister::files("."))
{
Info<< " " << item << nl;
}
}
{
Info<< nl
<< "List dirs" << nl
<< "~~~~~~~~~~" << nl;
for (const word& item : DirLister::dirs("."))
{
Info<< " " << item << nl;
}
}
{
Info<< nl
<< "List files - filtered" << nl
<< "~~~~~~~~~~" << nl;
for
(
const word& item
: DirLister::files(".").where
(
[](const word& val){ return val.startsWith("T"); }
)
)
{
Info<< " " << item << nl;
}
}
{
Info<< nl
<< "List dirs - filtered" << nl
<< "~~~~~~~~~~" << nl;
for
(
const word& item
: DirLister::dirs(".").where(regExp("Ma.*"))
)
{
Info<< " " << item << nl;
}
}
{
Info<< nl
<< "List dirs - filtered" << nl
<< "~~~~~~~~~~" << nl;
for
(
const word& item
: DirLister::dirs(".").where(predicates::always())
)
{
Info<< " " << item << nl;
}
}
{
Info<< nl
<< "List items" << nl
<< "~~~~~~~~~~" << nl
<< DirLister(".").list<fileName>() << nl;
}
{
Info<< nl
<< "List files - filtered" << nl
<< "~~~~~~~~~~" << nl
<< DirLister(".").list<fileName>
(
[](const word& val){ return val.startsWith("D"); },
false
)
<< nl;
}
{
Info<< nl
<< "List files - filtered" << nl
<< "~~~~~~~~~~" << nl;
wordReList relist
{
wordRe("processors"),
wordRe("processor[0-9][0-9]*", wordRe::REGEX)
};
wordRes matcher(relist);
Info<<"matcher: " << flatOutput(matcher) << endl;
for (const word& item : DirLister::dirs(".").where(wordRes(relist)))
{
Info<< "=> " << item << nl;
}
Info<< "dirList: "
<< flatOutput
(
DirLister::dirs(".").sorted<fileName>(wordRes(relist))
) << nl;
}
{
Info<< nl
<< "List time dirs" << nl
<< "~~~~~~~~~~" << nl;
for
(
const word& item
: DirLister::dirs(".").where
(
[](const word& val)
{
scalar s;
return readScalar(val, s) || val == "constant";
}
)
)
{
Info<< "=> " << item << nl;
}
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //