Commit 1d1f71f7 authored by Henry Weller's avatar Henry Weller
Browse files

foamDictionary: Added support for manipulating lists of dictionaries

  - provides support for manipulating polyMesh/boundary

  - changed behaviour of disableFunctionEntries option to preserve
    #include

  - dictionary: added reading of lists of dictionaries.
    + each list element may be accessed using the 'entryDDD' keyword
      according to their list index.

Patch contributed by Mattijs Janssens
parent 81de1dc9
......@@ -57,6 +57,9 @@ Usage
- \par -includes
List the \c #include and \c #includeIfPresent files to standard output
- \par -disableFunctionEntries
Do not expand macros or directives (#include etc)
Example usage:
- Change simulation to run for one timestep only:
\verbatim
......@@ -97,6 +100,15 @@ Usage
-entry boundaryField
\endverbatim
- Change patch type:
\verbatim
foamDictionary constant/polyMesh/boundary \
-entry entry0.fixedWalls.type -set patch
\endverbatim
This uses special parsing of Lists which stores these in the
dictionary with keyword 'entryDDD' where DDD is the position
in the dictionary (after ignoring the FoamFile entry).
\*---------------------------------------------------------------------------*/
#include "argList.H"
......@@ -271,6 +283,11 @@ int main(int argc, char *argv[])
"Read the specified dictionary file, expand the macros etc. and write "
"the resulting dictionary to standard output"
);
argList::addBoolOption
(
"disableFunctionEntries",
"Disable expansion of dictionary directives - #include, #codeStream etc"
);
argList args(argc, argv);
......@@ -281,6 +298,15 @@ int main(int argc, char *argv[])
Foam::functionEntries::includeEntry::log = true;
}
const bool disableEntries = args.optionFound("disableFunctionEntries");
if (disableEntries)
{
Info<< "Not expanding variables or dictionary directives"
<< endl;
entry::disableFunctionEntries = true;
}
fileName dictFileName(args[1]);
autoPtr<IFstream> dictFile(new IFstream(dictFileName));
......
......@@ -182,6 +182,10 @@ dictionaryEntry = $(dictionary)/dictionaryEntry
$(dictionaryEntry)/dictionaryEntry.C
$(dictionaryEntry)/dictionaryEntryIO.C
dictionaryListEntry = $(dictionary)/dictionaryListEntry
$(dictionaryListEntry)/dictionaryListEntry.C
$(dictionaryListEntry)/dictionaryListEntryIO.C
functionEntries = $(dictionary)/functionEntries
$(functionEntries)/calcEntry/calcEntry.C
$(functionEntries)/codeStream/codeStream.C
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ 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 "dictionaryListEntry.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dictionaryListEntry::dictionaryListEntry
(
const dictionary& parentDict,
const dictionaryListEntry& dictEnt
)
:
dictionaryEntry(parentDict, dictEnt)
{}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ 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::dictionaryListEntry
Description
Read/write List of dictionaries.
The List entries get stored in a
dictionary which itself is stored in the parent dictionary with
keyword 'entryDDD' where DDD is the position in the parent dictionary.
The printing is again in List format - the keyword is only printed as
comment. Can be used to e.g. manipulate polyMesh/boundary files.
SourceFiles
dictionaryListEntry.C
dictionaryListEntryIO.C
\*---------------------------------------------------------------------------*/
#ifndef dictionaryListEntry_H
#define dictionaryListEntry_H
#include "dictionaryEntry.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
class dictionaryListEntry;
Ostream& operator<<(Ostream&, const dictionaryListEntry&);
/*---------------------------------------------------------------------------*\
Class dictionaryListEntry Declaration
\*---------------------------------------------------------------------------*/
class dictionaryListEntry
:
public dictionaryEntry
{
// Private Member Functions
//- Returns size of dictionary without FoamFile
static label realSize(const dictionary&);
//- Dissallow bitwise copy
dictionaryListEntry(const dictionary&);
public:
// Constructors
//- Construct from the parent dictionary and Istream
dictionaryListEntry(const dictionary& parentDict, Istream&);
//- Construct as copy for the given parent dictionary
dictionaryListEntry
(
const dictionary& parentDict,
const dictionaryListEntry&
);
autoPtr<entry> clone(const dictionary& parentDict) const
{
return autoPtr<entry>(new dictionaryListEntry(parentDict, *this));
}
// Member functions
//- Write
virtual void write(Ostream&) const;
//- Return info proxy.
// Used to print token information to a stream
InfoProxy<dictionaryListEntry> info() const
{
return *this;
}
// Ostream operator
friend Ostream& operator<<(Ostream&, const dictionaryListEntry&);
};
template<>
Ostream& operator<<(Ostream&, const InfoProxy<dictionaryListEntry>&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ 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 "dictionaryListEntry.H"
#include "keyType.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::dictionaryListEntry::realSize(const dictionary& dict)
{
if (dict.size() < 1 || dict.first()->keyword() != "FoamFile")
{
return dict.size();
}
else
{
return dict.size() - 1;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dictionaryListEntry::dictionaryListEntry
(
const dictionary& parentDict,
Istream& is
)
:
dictionaryEntry
(
word("entry" + Foam::name(realSize(parentDict))),
parentDict,
dictionary::null
)
{
token firstToken(is);
if (firstToken.isLabel())
{
label s = firstToken.labelToken();
is.readBeginList("List");
for (label i=0; i<s; i++)
{
entry::New(*this, is);
}
is.readEndList("List");
}
else if
(
firstToken.isPunctuation()
&& firstToken.pToken() == token::BEGIN_LIST
)
{
while (true)
{
token nextToken(is);
if
(
nextToken.isPunctuation()
&& nextToken.pToken() == token::END_LIST
)
{
break;
}
is.putBack(nextToken);
entry::New(*this, is);
}
}
else
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< exit(FatalIOError);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::dictionaryListEntry::write(Ostream& os) const
{
os << nl << indent << size()
<< token::SPACE << "// " << keyword() << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
// Write contents
dictionary::write(os, false);
// Write end delimiter
os << decrIndent << indent << token::END_LIST << nl;
// Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const dictionaryListEntry&)");
}
// * * * * * * * * * * * * * * Ostream operator * * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const dictionaryListEntry& de)
{
de.write(os);
return os;
}
template<>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const InfoProxy<dictionaryListEntry>& ip
)
{
const dictionaryListEntry& e = ip.t_;
os << " dictionaryListEntry '" << e.keyword() << "'" << endl;
return os;
}
// ************************************************************************* //
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -75,6 +75,9 @@ class entry
// Private Member Functions
//- Get the next valid keyword. Return true if is valid keyType.
static bool getKeyword(keyType&, token&, Istream&);
//- Get the next valid keyword otherwise return false
static bool getKeyword(keyType&, Istream&);
......
......@@ -23,21 +23,19 @@ License
\*---------------------------------------------------------------------------*/
#include "entry.H"
#include "primitiveEntry.H"
#include "dictionaryEntry.H"
#include "functionEntry.H"
#include "includeEntry.H"
#include "inputModeEntry.H"
#include "stringOps.H"
#include "dictionaryListEntry.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
bool Foam::entry::getKeyword(keyType& keyword, token& keywordToken, Istream& is)
{
token keywordToken;
// Read the next valid token discarding spurious ';'s
do
{
......@@ -65,25 +63,43 @@ bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
keyword = keywordToken.stringToken();
return true;
}
// If it is the end of the dictionary or file return false...
else if (keywordToken == token::END_BLOCK || is.eof())
else
{
return false;
}
// Otherwise the token is invalid
}
bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
{
token keywordToken;
bool ok = getKeyword(keyword, keywordToken, is);
if (ok)
{
return true;
}
else
{
cerr<< "--> FOAM Warning : " << std::endl
<< " From function "
<< "entry::getKeyword(keyType&, Istream&)" << std::endl
<< " in file " << __FILE__
<< " at line " << __LINE__ << std::endl
<< " Reading " << is.name().c_str() << std::endl
<< " found " << keywordToken << std::endl
<< " expected either " << token::END_BLOCK << " or EOF"
<< std::endl;
return false;
// Do some more checking
if (keywordToken == token::END_BLOCK || is.eof())
{
return false;
}
else
{
// Otherwise the token is invalid
cerr<< "--> FOAM Warning : " << std::endl
<< " From function "
<< "entry::getKeyword(keyType&, Istream&)" << std::endl
<< " in file " << __FILE__
<< " at line " << __LINE__ << std::endl
<< " Reading " << is.name().c_str() << std::endl
<< " found " << keywordToken << std::endl
<< " expected either " << token::END_BLOCK << " or EOF"
<< std::endl;
return false;
}
}
}
......@@ -93,22 +109,68 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
is.fatalCheck("entry::New(const dictionary& parentDict, Istream&)");
keyType keyword;
token keyToken;
// Get the next keyword and if invalid return false
if (!getKeyword(keyword, is))
// Get the next keyword and if a valid keyword return true
bool valid = getKeyword(keyword, keyToken, is);
if (!valid)
{
return false;
// Do some more checking
if (keyToken == token::END_BLOCK || is.eof())
{
return false;
}
else if
(
keyToken.isLabel()
|| (keyToken.isPunctuation() && keyToken.pToken() == token::BEGIN_LIST)
)
{
is.putBack(keyToken);
return parentDict.add
(
new dictionaryListEntry(parentDict, is),
false
);
}
else
{
// Otherwise the token is invalid
cerr<< "--> FOAM Warning : " << std::endl
<< " From function "
<< "entry::getKeyword(keyType&, Istream&)" << std::endl
<< " in file " << __FILE__
<< " at line " << __LINE__ << std::endl
<< " Reading " << is.name().c_str() << std::endl
<< " found " << keyToken << std::endl
<< " expected either " << token::END_BLOCK << " or EOF"
<< std::endl;
return false;
}
}
else // Keyword starts entry ...
{
if
(
!disableFunctionEntries
&& keyword[0] == '#'
) // ... Function entry
if (keyword[0] == '#') // ... Function entry
{
word functionName = keyword(1, keyword.size()-1);
return functionEntry::execute(functionName, parentDict, is);
if (disableFunctionEntries)
{
return parentDict.add
(
new functionEntry
(
keyword,
parentDict,
is
),
false
);
}
else
{
return functionEntry::execute(functionName, parentDict, is);
}
}
else if
(
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -24,6 +24,8 @@ License
\*---------------------------------------------------------------------------*/
#include "functionEntry.H"
#include "IOstreams.H"
#include "ISstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -45,6 +47,34 @@ namespace Foam
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::token Foam::functionEntry::readLine(const word& key, Istream& is)
{
string s;
dynamic_cast<ISstream&>(is).getLine(s);
return token(string(key+s), is.lineNumber());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionEntry::functionEntry
(
const word& key,
const dictionary& dict,
Istream& is
)
:
primitiveEntry
(
word(key+dict.name()+Foam::name(is.lineNumber())),
readLine(key, is)