BUG: dictionary entries not being properly merged/overwritten (closes #418)

STYLE: update dictionary documentation
This commit is contained in:
Mark Olesen
2017-03-03 11:36:24 +01:00
parent 5fc6c3ca34
commit f05be160e2
9 changed files with 227 additions and 126 deletions

View File

@ -0,0 +1,52 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object testDict;
note "test with foamDictionary -expand";
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// #inputMode overwrite
key1 val1;
subdict
{
key1 a;
key2 b;
}
update
{
key1 val1b;
key2 val2;
subdict
{
key2 $key1;
key3 val3;
key2b ${..key2};
key3b ${:key1};
}
}
$update
key3 ${:subdict.key1};
key3 ${:update.subdict.key3};
key4 ${:update.subdict...subdict.key1};
// This is currently not working
#remove update.key1
// #remove update
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -100,7 +100,7 @@ const Foam::entry* Foam::dictionary::lookupScopedSubEntryPtr
else else
{ {
// Extract the first word // Extract the first word
word firstWord = keyword.substr(0, dotPos); const word firstWord = keyword.substr(0, dotPos);
const entry* entPtr = lookupScopedSubEntryPtr const entry* entPtr = lookupScopedSubEntryPtr
( (
@ -126,7 +126,7 @@ const Foam::entry* Foam::dictionary::lookupScopedSubEntryPtr
const entry* subEntPtr = lookupEntryPtr const entry* subEntPtr = lookupEntryPtr
( (
keyword.substr(0, nextDotPos), keyword.substr(0, nextDotPos),
false, //recursive, false,
patternMatch patternMatch
); );
if (nextDotPos == string::npos) if (nextDotPos == string::npos)
@ -617,9 +617,13 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
} }
bool Foam::dictionary::substituteScopedKeyword(const word& keyword) bool Foam::dictionary::substituteScopedKeyword
(
const word& keyword,
bool mergeEntry
)
{ {
word varName = keyword(1, keyword.size()-1); const word varName = keyword(1, keyword.size()-1);
// Lookup the variable name in the given dictionary // Lookup the variable name in the given dictionary
const entry* ePtr = lookupScopedEntryPtr(varName, true, true); const entry* ePtr = lookupScopedEntryPtr(varName, true, true);
@ -631,7 +635,7 @@ bool Foam::dictionary::substituteScopedKeyword(const word& keyword)
forAllConstIter(IDLList<entry>, addDict, iter) forAllConstIter(IDLList<entry>, addDict, iter)
{ {
add(iter()); add(iter(), mergeEntry);
} }
return true; return true;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,26 +25,57 @@ Class
Foam::dictionary Foam::dictionary
Description Description
A list of keyword definitions, which are a keyword followed by any number A list of keyword definitions, which are a keyword followed by a number
of values (e.g. words and numbers). The keywords can represent patterns of values (eg, words and numbers) or by a sub-dictionary.
which are matched using Posix regular expressions. The general order for Since the dictionary format is used extensively throughout OpenFOAM for
searching is as follows: input/output files, there are many examples of its use.
Dictionary keywords are a plain word or a pattern (regular expression).
The general order for searching is as follows:
- exact match - exact match
- pattern match (in reverse order) - pattern match (in reverse order)
- optional recursion into the enclosing (parent) dictionaries - optional recursion into the enclosing (parent) dictionaries
The dictionary class is the base class for IOdictionary. The dictionary class is the base class for IOdictionary and also serves
It also serves as a bootstrap dictionary for the objectRegistry data as a bootstrap dictionary for the objectRegistry data dictionaries.
dictionaries since, unlike the IOdictionary class, it does not use an
objectRegistry itself to work.
To add - a merge() member function with a non-const dictionary parameter? Note
This would avoid unnecessary cloning in the add(entry*, bool) method. Within dictionaries, entries can be referenced by using the '$' syntax
familiar from shell programming. A '.' separator is used when referencing
sub-dictionary entries. Leading '.' prefixes can be used to specify
an entry from a parent directory. A leading ':' prefix specifies
starting from the top-level entry. For example,
\verbatim
key1 val1;
key2 $key1; // use key1 value from current scope
key3 $.key1; // use key1 value from current scope
subdict1
{
key1 val1b;
key2 $..key1; // use key1 value from parent
subdict2
{
key2 val2;
key3 $...key1; // use key1 value from grandparent
}
}
key4 $:subdict1.subdict2.key3;
\endverbatim
It is also possible to use the '${}' syntax for clarity.
SourceFiles SourceFiles
dictionary.C dictionary.C
dictionaryIO.C dictionaryIO.C
SeeAlso
- Foam::entry
- Foam::dictionaryEntry
- Foam::primitiveEntry
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef dictionary_H #ifndef dictionary_H
@ -76,6 +107,7 @@ Ostream& operator<<(Ostream&, const dictionary&);
Class dictionaryName Declaration Class dictionaryName Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
//- Holds name for a dictionary
class dictionaryName class dictionaryName
{ {
// Private data // Private data
@ -87,11 +119,11 @@ public:
// Constructors // Constructors
//- Construct dictionaryName null //- Construct null
dictionaryName() dictionaryName()
{} {}
//- Construct dictionaryName as copy of the given fileName //- Construct as copy of the given fileName
dictionaryName(const fileName& name) dictionaryName(const fileName& name)
: :
name_(name) name_(name)
@ -116,16 +148,15 @@ public:
const word dictName() const const word dictName() const
{ {
const word scopedName = name_.name(); const word scopedName = name_.name();
const std::string::size_type i = scopedName.rfind('.');
string::size_type i = scopedName.rfind('.'); if (i == std::string::npos)
if (i == scopedName.npos)
{ {
return scopedName; return scopedName;
} }
else else
{ {
return scopedName.substr(i + 1, scopedName.npos); return scopedName.substr(i+1);
} }
} }
}; };
@ -142,8 +173,7 @@ class dictionary
{ {
// Private data // Private data
//- If true write optional keywords and values //- Report optional keywords and values if not present in dictionary
// if not present in dictionary
static bool writeOptionalEntries; static bool writeOptionalEntries;
//- HashTable of the entries held on the DL-list for quick lookup //- HashTable of the entries held on the DL-list for quick lookup
@ -165,7 +195,7 @@ class dictionary
// otherwise return nullptr. Allows scoping using '.' // otherwise return nullptr. Allows scoping using '.'
const entry* lookupScopedSubEntryPtr const entry* lookupScopedSubEntryPtr
( (
const word&, const word& keyword,
bool recursive, bool recursive,
bool patternMatch bool patternMatch
) const; ) const;
@ -217,38 +247,38 @@ public:
( (
const fileName& name, const fileName& name,
const dictionary& parentDict, const dictionary& parentDict,
Istream& Istream& is
); );
//- Construct top-level dictionary from Istream, //- Construct top-level dictionary from Istream,
// reading entries until EOF // reading entries until EOF
dictionary(Istream&); dictionary(Istream& is);
//- Construct top-level dictionary from Istream, //- Construct top-level dictionary from Istream,
// reading entries until EOF, optionally keeping the header // reading entries until EOF, optionally keeping the header
dictionary(Istream&, const bool keepHeader); dictionary(Istream& is, const bool keepHeader);
//- Construct as copy given the parent dictionary //- Construct as copy given the parent dictionary
dictionary(const dictionary& parentDict, const dictionary&); dictionary(const dictionary& parentDict, const dictionary&);
//- Construct top-level dictionary as copy //- Construct top-level dictionary as copy
dictionary(const dictionary&); dictionary(const dictionary& dict);
//- Construct top-level dictionary as copy from pointer to dictionary. //- Construct top-level dictionary as copy from pointer to dictionary.
// A null pointer is treated like an empty dictionary. // A null pointer is treated like an empty dictionary.
dictionary(const dictionary*); dictionary(const dictionary* dictPtr);
//- Construct by transferring parameter contents given parent dictionary //- Construct by transferring parameter contents given parent dictionary
dictionary(const dictionary& parentDict, const Xfer<dictionary>&); dictionary(const dictionary& parentDict, const Xfer<dictionary>& dict);
//- Construct top-level dictionary by transferring parameter contents //- Construct top-level dictionary by transferring parameter contents
dictionary(const Xfer<dictionary>&); dictionary(const Xfer<dictionary>& dict);
//- Construct and return clone //- Construct and return clone
autoPtr<dictionary> clone() const; autoPtr<dictionary> clone() const;
//- Construct top-level dictionary on freestore from Istream //- Construct top-level dictionary on freestore from Istream
static autoPtr<dictionary> New(Istream&); static autoPtr<dictionary> New(Istream& is);
//- Destructor //- Destructor
@ -286,8 +316,8 @@ public:
// If patternMatch, use regular expressions // If patternMatch, use regular expressions
bool found bool found
( (
const word&, const word& keyword,
bool recursive=false, bool recursive = false,
bool patternMatch = true bool patternMatch = true
) const; ) const;
@ -297,7 +327,7 @@ public:
// If patternMatch, use regular expressions // If patternMatch, use regular expressions
const entry* lookupEntryPtr const entry* lookupEntryPtr
( (
const word&, const word& keyword,
bool recursive, bool recursive,
bool patternMatch bool patternMatch
) const; ) const;
@ -308,7 +338,7 @@ public:
// If patternMatch, use regular expressions. // If patternMatch, use regular expressions.
entry* lookupEntryPtr entry* lookupEntryPtr
( (
const word&, const word& keyword,
bool recursive, bool recursive,
bool patternMatch bool patternMatch
); );
@ -318,7 +348,7 @@ public:
// If patternMatch, use regular expressions. // If patternMatch, use regular expressions.
const entry& lookupEntry const entry& lookupEntry
( (
const word&, const word& keyword,
bool recursive, bool recursive,
bool patternMatch bool patternMatch
) const; ) const;
@ -328,22 +358,21 @@ public:
// If patternMatch, use regular expressions. // If patternMatch, use regular expressions.
ITstream& lookup ITstream& lookup
( (
const word&, const word& keyword,
bool recursive=false, bool recursive = false,
bool patternMatch=true bool patternMatch = true
) const; ) const;
//- Find and return a T, //- Find and return a T, or return the given default value
// if not found return the given default value
// If recursive, search parent dictionaries. // If recursive, search parent dictionaries.
// If patternMatch, use regular expressions. // If patternMatch, use regular expressions.
template<class T> template<class T>
T lookupOrDefault T lookupOrDefault
( (
const word&, const word& keyword,
const T&, const T& deflt,
bool recursive=false, bool recursive = false,
bool patternMatch=true bool patternMatch = true
) const; ) const;
//- Find and return a T, if not found return the given //- Find and return a T, if not found return the given
@ -353,10 +382,10 @@ public:
template<class T> template<class T>
T lookupOrAddDefault T lookupOrAddDefault
( (
const word&, const word& keyword,
const T&, const T& deflt,
bool recursive=false, bool recursive = false,
bool patternMatch=true bool patternMatch = true
); );
//- Find an entry if present, and assign to T //- Find an entry if present, and assign to T
@ -366,10 +395,10 @@ public:
template<class T> template<class T>
bool readIfPresent bool readIfPresent
( (
const word&, const word& keyword,
T&, T& val,
bool recursive=false, bool recursive = false,
bool patternMatch=true bool patternMatch = true
) const; ) const;
//- Find and return an entry data stream pointer if present //- Find and return an entry data stream pointer if present
@ -377,33 +406,33 @@ public:
// Special handling for ':' at start of keyword and '..'. // Special handling for ':' at start of keyword and '..'.
const entry* lookupScopedEntryPtr const entry* lookupScopedEntryPtr
( (
const word&, const word& keyword,
bool recursive, bool recursive,
bool patternMatch bool patternMatch
) const; ) const;
//- Check if entry is a sub-dictionary //- Check if entry is a sub-dictionary
bool isDict(const word&) const; bool isDict(const word& keyword) const;
//- Find and return a sub-dictionary pointer if present //- Find and return a sub-dictionary pointer if present
// otherwise return nullptr. // otherwise return nullptr.
const dictionary* subDictPtr(const word&) const; const dictionary* subDictPtr(const word& keyword) const;
//- Find and return a sub-dictionary pointer if present //- Find and return a sub-dictionary pointer if present
// otherwise return nullptr. // otherwise return nullptr.
dictionary* subDictPtr(const word&); dictionary* subDictPtr(const word& keyword);
//- Find and return a sub-dictionary //- Find and return a sub-dictionary
const dictionary& subDict(const word&) const; const dictionary& subDict(const word& keyword) const;
//- Find and return a sub-dictionary for manipulation //- Find and return a sub-dictionary for manipulation
dictionary& subDict(const word&); dictionary& subDict(const word& keyword);
//- Find and return a sub-dictionary as a copy, or //- Find and return a sub-dictionary as a copy, or
// return an empty dictionary if the sub-dictionary does not exist // return an empty dictionary if the sub-dictionary does not exist
dictionary subOrEmptyDict dictionary subOrEmptyDict
( (
const word&, const word& keyword,
const bool mustRead = false const bool mustRead = false
) const; ) const;
@ -414,74 +443,78 @@ public:
wordList sortedToc() const; wordList sortedToc() const;
//- Return the list of available keys or patterns //- Return the list of available keys or patterns
List<keyType> keys(bool patterns=false) const; List<keyType> keys(bool patterns = false) const;
// Editing // Editing
//- Substitute the given keyword prepended by '$' with the //- Substitute the given keyword prepended by '$' with the
// corresponding sub-dictionary entries // corresponding sub-dictionary entries
bool substituteKeyword(const word& keyword); bool substituteKeyword(const word& keyword, bool mergeEntry=false);
//- Substitute the given scoped keyword prepended by '$' with the //- Substitute the given scoped keyword prepended by '$' with the
// corresponding sub-dictionary entries // corresponding sub-dictionary entries
bool substituteScopedKeyword(const word& keyword); bool substituteScopedKeyword
(
const word& keyword,
bool mergeEntry=false
);
//- Add a new entry //- Add a new entry
// With the merge option, dictionaries are interwoven and // With the merge option, dictionaries are interwoven and
// primitive entries are overwritten // primitive entries are overwritten
bool add(entry*, bool mergeEntry=false); bool add(entry* entryPtr, bool mergeEntry=false);
//- Add an entry //- Add an entry
// With the merge option, dictionaries are interwoven and // With the merge option, dictionaries are interwoven and
// primitive entries are overwritten // primitive entries are overwritten
void add(const entry&, bool mergeEntry=false); void add(const entry& e, bool mergeEntry=false);
//- Add a word entry //- Add a word entry
// optionally overwrite an existing entry // optionally overwrite an existing entry
void add(const keyType&, const word&, bool overwrite=false); void add(const keyType& k, const word& w, bool overwrite=false);
//- Add a string entry //- Add a string entry
// optionally overwrite an existing entry // optionally overwrite an existing entry
void add(const keyType&, const string&, bool overwrite=false); void add(const keyType& k, const string& s, bool overwrite=false);
//- Add a label entry //- Add a label entry
// optionally overwrite an existing entry // optionally overwrite an existing entry
void add(const keyType&, const label, bool overwrite=false); void add(const keyType&, const label l, bool overwrite=false);
//- Add a scalar entry //- Add a scalar entry
// optionally overwrite an existing entry // optionally overwrite an existing entry
void add(const keyType&, const scalar, bool overwrite=false); void add(const keyType&, const scalar s, bool overwrite=false);
//- Add a dictionary entry //- Add a dictionary entry
// optionally merge with an existing sub-dictionary // optionally merge with an existing sub-dictionary
void add void add
( (
const keyType&, const keyType& k,
const dictionary&, const dictionary& d,
bool mergeEntry=false bool mergeEntry = false
); );
//- Add a T entry //- Add a T entry
// optionally overwrite an existing entry // optionally overwrite an existing entry
template<class T> template<class T>
void add(const keyType&, const T&, bool overwrite=false); void add(const keyType& k, const T& t, bool overwrite=false);
//- Assign a new entry, overwrite any existing entry //- Assign a new entry, overwrite any existing entry
void set(entry*); void set(entry* entryPtr);
//- Assign a new entry, overwrite any existing entry //- Assign a new entry, overwrite any existing entry
void set(const entry&); void set(const entry& e);
//- Assign a dictionary entry, overwrite any existing entry //- Assign a dictionary entry, overwrite any existing entry
void set(const keyType&, const dictionary&); void set(const keyType& k, const dictionary& d);
//- Assign a T entry, overwrite any existing entry //- Assign a T entry, overwrite any existing entry
template<class T> template<class T>
void set(const keyType&, const T&); void set(const keyType& k, const T& t);
//- Remove an entry specified by keyword //- Remove an entry specified by keyword
bool remove(const word&); bool remove(const word& Keyword);
//- Change the keyword for an entry, //- Change the keyword for an entry,
// optionally forcing overwrite of an existing entry // optionally forcing overwrite of an existing entry
@ -494,13 +527,13 @@ public:
//- Merge entries from the given dictionary. //- Merge entries from the given dictionary.
// Also merge sub-dictionaries as required. // Also merge sub-dictionaries as required.
bool merge(const dictionary&); bool merge(const dictionary& dict);
//- Clear the dictionary //- Clear the dictionary
void clear(); void clear();
//- Transfer the contents of the argument and annul the argument. //- Transfer the contents of the argument and annul the argument.
void transfer(dictionary&); void transfer(dictionary& dict);
//- Transfer contents to the Xfer container //- Transfer contents to the Xfer container
Xfer<dictionary> xfer(); Xfer<dictionary> xfer();
@ -509,53 +542,53 @@ public:
// Read // Read
//- Read dictionary from Istream //- Read dictionary from Istream
bool read(Istream&); bool read(Istream& is);
//- Read dictionary from Istream, optionally keeping the header //- Read dictionary from Istream, optionally keeping the header
bool read(Istream&, const bool keepHeader); bool read(Istream& is, const bool keepHeader);
// Write // Write
//- Write sub-dictionary with the keyword as its header //- Write sub-dictionary with the keyword as its header
void writeEntry(const keyType& keyword, Ostream&) const; void writeEntry(const keyType& keyword, Ostream& os) const;
//- Write dictionary entries. //- Write dictionary entries.
// Optionally with extra new line between entries for // Optionally with extra new line between entries for
// "top-level" dictionaries // "top-level" dictionaries
void writeEntries(Ostream&, const bool extraNewLine=false) const; void writeEntries(Ostream& os, const bool extraNewLine=false) const;
//- Write dictionary, normally with sub-dictionary formatting //- Write dictionary, normally with sub-dictionary formatting
void write(Ostream&, const bool subDict=true) const; void write(Ostream& os, const bool subDict=true) const;
// Member Operators // Member Operators
//- Find and return entry //- Find and return entry
ITstream& operator[](const word&) const; ITstream& operator[](const word& keyword) const;
void operator=(const dictionary&); void operator=(const dictionary& rhs);
//- Include entries from the given dictionary. //- Include entries from the given dictionary.
// Warn, but do not overwrite existing entries. // Warn, but do not overwrite existing entries.
void operator+=(const dictionary&); void operator+=(const dictionary& rhs);
//- Conditionally include entries from the given dictionary. //- Conditionally include entries from the given dictionary.
// Do not overwrite existing entries. // Do not overwrite existing entries.
void operator|=(const dictionary&); void operator|=(const dictionary& rhs);
//- Unconditionally include entries from the given dictionary. //- Unconditionally include entries from the given dictionary.
// Overwrite existing entries. // Overwrite existing entries.
void operator<<=(const dictionary&); void operator<<=(const dictionary& rhs);
// IOstream operators // IOstream operators
//- Read dictionary from Istream //- Read dictionary from Istream
friend Istream& operator>>(Istream&, dictionary&); friend Istream& operator>>(Istream& is, dictionary& dict);
//- Write dictionary to Ostream //- Write dictionary to Ostream
friend Ostream& operator<<(Ostream&, const dictionary&); friend Ostream& operator<<(Ostream& os, const dictionary& dict);
}; };

View File

@ -128,21 +128,21 @@ bool Foam::dictionary::read(Istream& is)
} }
bool Foam::dictionary::substituteKeyword(const word& keyword) bool Foam::dictionary::substituteKeyword(const word& keyword, bool mergeEntry)
{ {
word varName = keyword(1, keyword.size()-1); const word varName = keyword(1, keyword.size()-1);
// lookup the variable name in the given dictionary // Lookup the variable name in the given dictionary
const entry* ePtr = lookupEntryPtr(varName, true, true); const entry* ePtr = lookupEntryPtr(varName, true, true);
// if defined insert its entries into this dictionary // If defined insert its entries into this dictionary
if (ePtr != nullptr) if (ePtr != nullptr)
{ {
const dictionary& addDict = ePtr->dict(); const dictionary& addDict = ePtr->dict();
forAllConstIter(IDLList<entry>, addDict, iter) forAllConstIter(IDLList<entry>, addDict, iter)
{ {
add(iter()); add(iter(), mergeEntry);
} }
return true; return true;

View File

@ -73,7 +73,7 @@ bool Foam::entry::getKeyword(keyType& keyword, token& keywordToken, Istream& is)
bool Foam::entry::getKeyword(keyType& keyword, Istream& is) bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
{ {
token keywordToken; token keywordToken;
bool ok = getKeyword(keyword, keywordToken, is); const bool ok = getKeyword(keyword, keywordToken, is);
if (ok) if (ok)
{ {
@ -112,7 +112,7 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
token keyToken; token keyToken;
// Get the next keyword and if a valid keyword return true // Get the next keyword and if a valid keyword return true
bool valid = getKeyword(keyword, keyToken, is); const bool valid = getKeyword(keyword, keyToken, is);
if (!valid) if (!valid)
{ {
@ -153,7 +153,7 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
{ {
if (keyword[0] == '#') // ... Function entry if (keyword[0] == '#') // ... Function entry
{ {
word functionName = keyword(1, keyword.size()-1); const word functionName = keyword(1, keyword.size()-1);
if (disableFunctionEntries) if (disableFunctionEntries)
{ {
return parentDict.add return parentDict.add
@ -195,7 +195,7 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
if (nextToken == token::BEGIN_BLOCK) if (nextToken == token::BEGIN_BLOCK)
{ {
word varName = keyword(1, keyword.size()-1); const word varName = keyword(1, keyword.size()-1);
// lookup the variable name in the given dictionary // lookup the variable name in the given dictionary
const entry* ePtr = parentDict.lookupScopedEntryPtr const entry* ePtr = parentDict.lookupScopedEntryPtr
@ -227,7 +227,14 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
} }
else else
{ {
parentDict.substituteScopedKeyword(keyword); // Deal with duplicate entries (at least partially)
const bool mergeEntry =
(
functionEntries::inputModeEntry::merge()
|| functionEntries::inputModeEntry::overwrite()
);
parentDict.substituteScopedKeyword(keyword, mergeEntry);
} }
return true; return true;

View File

@ -62,7 +62,7 @@ void Foam::functionEntries::inputModeEntry::setMode(Istream& is)
{ {
clear(); clear();
word mode(is); const word mode(is);
if (mode == "merge" || mode == "default") if (mode == "merge" || mode == "default")
{ {
mode_ = MERGE; mode_ = MERGE;
@ -97,7 +97,7 @@ void Foam::functionEntries::inputModeEntry::setMode(Istream& is)
bool Foam::functionEntries::inputModeEntry::execute bool Foam::functionEntries::inputModeEntry::execute
( (
dictionary& parentDict, dictionary& unused,
Istream& is Istream& is
) )
{ {

View File

@ -34,12 +34,20 @@ Description
\endverbatim \endverbatim
The possible input modes: The possible input modes:
- \par merge merge sub-dictionaries when possible - \par merge
- \par overwrite keep last entry and silently remove previous ones merge sub-dictionaries when possible
- \par protect keep initial entry and silently ignore subsequent ones - \par overwrite
- \par warn keep initial entry and warn about subsequent ones keep last entry and silently remove previous ones
- \par error issue a FatalError for duplicate entries - \par protect
- \par default currently identical to merge keep initial entry and silently ignore subsequent ones
- \par warn
keep initial entry and warn about subsequent ones
- \par error
issue a FatalError for duplicate entries
- \par default
The default treatment - currently identical to \b merge.
Note that the clear() method resets to the default mode (merge).
SourceFiles SourceFiles
inputModeEntry.C inputModeEntry.C
@ -83,13 +91,13 @@ class inputModeEntry
// Private Member Functions // Private Member Functions
//- Read the mode as a word and set enum appropriately //- Read the mode as a word and set enum appropriately
static void setMode(Istream&); static void setMode(Istream& is);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
inputModeEntry(const inputModeEntry&); inputModeEntry(const inputModeEntry&) = delete;
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const inputModeEntry&); void operator=(const inputModeEntry&) = delete;
public: public:
@ -101,7 +109,7 @@ public:
// Member Functions // Member Functions
//- Execute the functionEntry in a sub-dict context //- Execute the functionEntry in a sub-dict context
static bool execute(dictionary& parentDict, Istream&); static bool execute(dictionary& parentDict, Istream& is);
//- Reset the inputMode to %default (ie, %merge) //- Reset the inputMode to %default (ie, %merge)
static void clear(); static void clear();

View File

@ -67,10 +67,10 @@ class removeEntry
// Private Member Functions // Private Member Functions
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
removeEntry(const removeEntry&); removeEntry(const removeEntry&) = delete;
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const removeEntry&); void operator=(const removeEntry&) = delete;
public: public:
@ -82,7 +82,7 @@ public:
// Member Functions // Member Functions
//- Execute the functionEntry in a sub-dict context //- Execute the functionEntry in a sub-dict context
static bool execute(dictionary& parentDict, Istream&); static bool execute(dictionary& parentDict, Istream& is);
}; };

View File

@ -21,9 +21,6 @@ License
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
PrimitiveEntry constructor from Istream and Ostream output operator.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "primitiveEntry.H" #include "primitiveEntry.H"