mirror of
https://github.com/OpenFOAM/OpenFOAM-6.git
synced 2025-12-08 06:57:46 +00:00
362 lines
10 KiB
C
362 lines
10 KiB
C
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | Copyright (C) 2011-2018 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 "entry.H"
|
|
#include "primitiveEntry.H"
|
|
#include "dictionaryEntry.H"
|
|
#include "functionEntry.H"
|
|
#include "includeEntry.H"
|
|
#include "inputModeEntry.H"
|
|
#include "stringOps.H"
|
|
#include "dictionaryListEntry.H"
|
|
|
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
|
|
bool Foam::entry::getKeyword(keyType& keyword, token& keywordToken, Istream& is)
|
|
{
|
|
// Read the next valid token discarding spurious ';'s
|
|
do
|
|
{
|
|
if
|
|
(
|
|
is.read(keywordToken).bad()
|
|
|| is.eof()
|
|
|| !keywordToken.good()
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
while (keywordToken == token::END_STATEMENT);
|
|
|
|
// If the token is a valid keyword set 'keyword' return true...
|
|
if (keywordToken.isWord())
|
|
{
|
|
keyword = keywordToken.wordToken();
|
|
return true;
|
|
}
|
|
else if (keywordToken.isString())
|
|
{
|
|
// Enable wildcards
|
|
keyword = keywordToken.stringToken();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
|
|
{
|
|
token keywordToken;
|
|
bool ok = getKeyword(keyword, keywordToken, is);
|
|
|
|
if (ok)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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 a valid keyword return true
|
|
bool valid = getKeyword(keyword, keyToken, is);
|
|
|
|
if (!valid)
|
|
{
|
|
// 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::New(dictionary&, 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 (keyword[0] == '#') // ... Function entry
|
|
{
|
|
word functionName = keyword(1, keyword.size()-1);
|
|
if (disableFunctionEntries)
|
|
{
|
|
return parentDict.add
|
|
(
|
|
new functionEntry
|
|
(
|
|
keyword,
|
|
parentDict,
|
|
is
|
|
),
|
|
false
|
|
);
|
|
}
|
|
else
|
|
{
|
|
return functionEntry::execute(functionName, parentDict, is);
|
|
}
|
|
}
|
|
else if
|
|
(
|
|
!disableFunctionEntries
|
|
&& keyword[0] == '$'
|
|
) // ... Substitution entry
|
|
{
|
|
token nextToken(is);
|
|
is.putBack(nextToken);
|
|
|
|
if (keyword.size() > 2 && keyword[1] == token::BEGIN_BLOCK)
|
|
{
|
|
// Recursive substitution mode. Replace between {} with
|
|
// expansion and then let standard variable expansion deal
|
|
// with rest.
|
|
string s(keyword(2, keyword.size()-3));
|
|
// Substitute dictionary and environment variables. Do not allow
|
|
// empty substitutions.
|
|
stringOps::inplaceExpand(s, parentDict, true, false);
|
|
keyword.std::string::replace(1, keyword.size()-1, s);
|
|
}
|
|
|
|
if (nextToken == token::BEGIN_BLOCK)
|
|
{
|
|
word varName = keyword(1, keyword.size()-1);
|
|
|
|
// lookup the variable name in the given dictionary
|
|
const entry* ePtr = parentDict.lookupScopedEntryPtr
|
|
(
|
|
varName,
|
|
true,
|
|
true
|
|
);
|
|
|
|
if (ePtr)
|
|
{
|
|
// Read as primitiveEntry
|
|
const keyType newKeyword(ePtr->stream());
|
|
|
|
return parentDict.add
|
|
(
|
|
new dictionaryEntry(newKeyword, parentDict, is),
|
|
false
|
|
);
|
|
}
|
|
else
|
|
{
|
|
FatalIOErrorInFunction(is)
|
|
<< "Attempt to use undefined variable " << varName
|
|
<< " as keyword"
|
|
<< exit(FatalIOError);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
parentDict.substituteScopedKeyword(keyword);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else if
|
|
(
|
|
!disableFunctionEntries
|
|
&& keyword == "include"
|
|
) // ... For backward compatibility
|
|
{
|
|
return functionEntries::includeEntry::execute(parentDict, is);
|
|
}
|
|
else // ... Data entries
|
|
{
|
|
token nextToken(is);
|
|
is.putBack(nextToken);
|
|
|
|
// Deal with duplicate entries
|
|
bool mergeEntry = false;
|
|
|
|
// See (using exact match) if entry already present
|
|
entry* existingPtr = parentDict.lookupEntryPtr
|
|
(
|
|
keyword,
|
|
false,
|
|
false
|
|
);
|
|
|
|
if (existingPtr)
|
|
{
|
|
if (functionEntries::inputModeEntry::merge())
|
|
{
|
|
mergeEntry = true;
|
|
}
|
|
else if (functionEntries::inputModeEntry::overwrite())
|
|
{
|
|
// clear dictionary so merge acts like overwrite
|
|
if (existingPtr->isDict())
|
|
{
|
|
existingPtr->dict().clear();
|
|
}
|
|
mergeEntry = true;
|
|
}
|
|
else if (functionEntries::inputModeEntry::protect())
|
|
{
|
|
// read and discard the entry
|
|
if (nextToken == token::BEGIN_BLOCK)
|
|
{
|
|
dictionaryEntry dummy(keyword, parentDict, is);
|
|
}
|
|
else
|
|
{
|
|
primitiveEntry dummy(keyword, parentDict, is);
|
|
}
|
|
return true;
|
|
}
|
|
else if (functionEntries::inputModeEntry::error())
|
|
{
|
|
FatalIOErrorInFunction(is)
|
|
<< "ERROR! duplicate entry: " << keyword
|
|
<< exit(FatalIOError);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (nextToken == token::BEGIN_BLOCK)
|
|
{
|
|
return parentDict.add
|
|
(
|
|
new dictionaryEntry(keyword, parentDict, is),
|
|
mergeEntry
|
|
);
|
|
}
|
|
else
|
|
{
|
|
return parentDict.add
|
|
(
|
|
new primitiveEntry(keyword, parentDict, is),
|
|
mergeEntry
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Foam::autoPtr<Foam::entry> Foam::entry::New(Istream& is)
|
|
{
|
|
is.fatalCheck("entry::New(Istream&)");
|
|
|
|
keyType keyword;
|
|
|
|
// Get the next keyword and if invalid return false
|
|
if (!getKeyword(keyword, is))
|
|
{
|
|
return autoPtr<entry>(nullptr);
|
|
}
|
|
else // Keyword starts entry ...
|
|
{
|
|
token nextToken(is);
|
|
is.putBack(nextToken);
|
|
|
|
if (nextToken == token::BEGIN_BLOCK)
|
|
{
|
|
return autoPtr<entry>
|
|
(
|
|
new dictionaryEntry(keyword, dictionary::null, is)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
return autoPtr<entry>
|
|
(
|
|
new primitiveEntry(keyword, is)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * Ostream operator * * * * * * * * * * * * * * * //
|
|
|
|
Foam::Ostream& Foam::operator<<(Ostream& os, const entry& e)
|
|
{
|
|
e.write(os);
|
|
return os;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|