diff --git a/applications/test/DirLister/DirLister.C b/applications/test/DirLister/DirLister.C
new file mode 100644
index 0000000000..45460ddd34
--- /dev/null
+++ b/applications/test/DirLister/DirLister.C
@@ -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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "DirLister.H"
+#include
+
+// * * * * * * * * * * * * * * 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_;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/DirLister/DirLister.H b/applications/test/DirLister/DirLister.H
new file mode 100644
index 0000000000..e1108e7122
--- /dev/null
+++ b/applications/test/DirLister/DirLister.H
@@ -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 .
+
+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(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
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+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 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
+ inline Filtered 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
+ List list() const;
+
+ //- Return complete list of names
+ template
+ List list
+ (
+ const UnaryPredicate& pred,
+ const bool prune = false
+ ) const;
+
+ //- Return a complete list of names, sorted in natural order
+ template
+ List sorted() const;
+
+ //- Return complete list of names, sorted in natural order
+ template
+ List 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 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
+
+// ************************************************************************* //
diff --git a/applications/test/DirLister/DirListerI.H b/applications/test/DirLister/DirListerI.H
new file mode 100644
index 0000000000..1c714acec1
--- /dev/null
+++ b/applications/test/DirLister/DirListerI.H
@@ -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 .
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
+
+inline bool Foam::DirLister::accept(const word& name) const
+{
+ return true;
+}
+
+
+template
+inline bool Foam::DirLister::Filtered::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
+inline Foam::DirLister::Filtered::Filtered
+(
+ const Foam::DirLister& lister,
+ const UnaryPredicate& pred,
+ const bool prune
+)
+:
+ DirLister(lister),
+ pred_(pred),
+ prune_(prune)
+{}
+
+
+template
+inline Foam::DirLister::Filtered
+Foam::DirLister::where(const UnaryPredicate& pred, const bool prune) const
+{
+ return DirLister::Filtered(*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();
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/DirLister/DirListerTemplates.C b/applications/test/DirLister/DirListerTemplates.C
new file mode 100644
index 0000000000..52c0bfe842
--- /dev/null
+++ b/applications/test/DirLister/DirListerTemplates.C
@@ -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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "predicates.H"
+#include "stringOps.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+Foam::List Foam::DirLister::list
+(
+ const UnaryPredicate& pred,
+ const bool prune
+) const
+{
+ // Initial list size and resizing increment
+ static const int incr = 100;
+
+ List 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
+Foam::List Foam::DirLister::list() const
+{
+ return list(predicates::always());
+}
+
+
+template
+Foam::List Foam::DirLister::sorted
+(
+ const UnaryPredicate& pred,
+ const bool prune
+) const
+{
+ List lst(list(pred, prune));
+ sort(lst, stringOps::natural_sort());
+
+ return lst;
+}
+
+
+template
+Foam::List Foam::DirLister::sorted() const
+{
+ return sorted(predicates::always());
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/DirLister/Make/files b/applications/test/DirLister/Make/files
new file mode 100644
index 0000000000..d42f88a4a5
--- /dev/null
+++ b/applications/test/DirLister/Make/files
@@ -0,0 +1,4 @@
+Test-DirLister.C
+DirLister.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-DirLister
diff --git a/applications/test/DirLister/Make/options b/applications/test/DirLister/Make/options
new file mode 100644
index 0000000000..6a9e9810b3
--- /dev/null
+++ b/applications/test/DirLister/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/DirLister/Test-DirLister.C b/applications/test/DirLister/Test-DirLister.C
new file mode 100644
index 0000000000..b528a1558a
--- /dev/null
+++ b/applications/test/DirLister/Test-DirLister.C
@@ -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 .
+
+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() << nl;
+ }
+
+ {
+ Info<< nl
+ << "List files - filtered" << nl
+ << "~~~~~~~~~~" << nl
+ << DirLister(".").list
+ (
+ [](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(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;
+}
+
+
+// ************************************************************************* //