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.
- exact match
- pattern match (in reverse order)
- optional recursion into the enclosing (parent) dictionaries
The dictionary class is the base class for IOdictionary. Dictionary keywords are a plain word or a pattern (regular expression).
It also serves as a bootstrap dictionary for the objectRegistry data The general order for searching is as follows:
dictionaries since, unlike the IOdictionary class, it does not use an - exact match
objectRegistry itself to work. - pattern match (in reverse order)
- optional recursion into the enclosing (parent) dictionaries
To add - a merge() member function with a non-const dictionary parameter? The dictionary class is the base class for IOdictionary and also serves
This would avoid unnecessary cloning in the add(entry*, bool) method. as a bootstrap dictionary for the objectRegistry data dictionaries.
Note
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"