Merge branch 'dict-lookup' into 'develop'

Dict lookup

See merge request !105
This commit is contained in:
Andrew Heather 2017-05-02 16:37:57 +01:00
commit c9df5f9249
13 changed files with 368 additions and 247 deletions

View File

@ -0,0 +1,53 @@
/*--------------------------------*- 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
// Can a leading '^' or ':' as anchor for scoping
key3 $^subdict.key1;
key3 ${^update.subdict.key3};
key4 ${:update.subdict...subdict.key1};
// This is currently not working
#remove update.key1
// #remove update
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -288,6 +288,9 @@ Foam::vtkPVFoam::vtkPVFoam
fullCasePath = cwd();
}
// The name of the executable, unless already present in the environment
setEnv("FOAM_EXECUTABLE", "paraview", false);
// Set the case as an environment variable - some BCs might use this
if (fullCasePath.name().find("processor", 0) == 0)
{

View File

@ -206,6 +206,9 @@ Foam::vtkPVblockMesh::vtkPVblockMesh
fullCasePath = cwd();
}
// The name of the executable, unless already present in the environment
setEnv("FOAM_EXECUTABLE", "paraview", false);
// Set the case as an environment variable - some BCs might use this
if (fullCasePath.name().find("processor", 0) == 0)
{

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -60,114 +60,101 @@ const Foam::entry* Foam::dictionary::lookupScopedSubEntryPtr
// Non-scoped lookup
return lookupEntryPtr(keyword, recursive, patternMatch);
}
else
else if (dotPos == 0)
{
if (dotPos == 0)
// Starting with a '.' -> go up for every further '.' found
++dotPos;
const dictionary* dictPtr = this;
for
(
string::const_iterator it = keyword.begin()+1;
it != keyword.end() && *it == '.';
++dotPos, ++it
)
{
// Starting with a '.'. Go up for every 2nd '.' found
const dictionary* dictPtr = this;
string::size_type begVar = dotPos + 1;
string::const_iterator iter = keyword.begin() + begVar;
string::size_type endVar = begVar;
while (iter != keyword.end() && *iter == '.')
// Go to parent
if (&dictPtr->parent_ != &dictionary::null)
{
++iter;
++endVar;
// Go to parent
if (&dictPtr->parent_ == &dictionary::null)
{
FatalIOErrorInFunction
(
*this
) << "No parent of current dictionary"
<< " when searching for "
<< keyword.substr(begVar, keyword.size()-begVar)
<< exit(FatalIOError);
}
dictPtr = &dictPtr->parent_;
}
else
{
FatalIOErrorInFunction
(
*this
) << "No parent of current dictionary when searching for "
<< keyword.substr(1)
<< exit(FatalIOError);
return dictPtr->lookupScopedSubEntryPtr
return nullptr;
}
}
return dictPtr->lookupScopedSubEntryPtr
(
keyword.substr(dotPos),
false,
patternMatch
);
}
else
{
// The first word
const entry* entPtr = lookupScopedSubEntryPtr
(
keyword.substr(0, dotPos),
false,
patternMatch
);
if (!entPtr)
{
// Fall back to finding key with '.' so e.g. if keyword is
// a.b.c.d it would try
// a.b, a.b.c, a.b.c.d
while (true)
{
dotPos = keyword.find('.', dotPos+1);
entPtr = lookupEntryPtr
(
keyword.substr(0, dotPos),
false,
patternMatch
);
if (dotPos == string::npos)
{
// Parsed the whole word. Return entry or null.
return entPtr;
}
if (entPtr && entPtr->isDict())
{
return entPtr->dict().lookupScopedSubEntryPtr
(
keyword.substr(dotPos),
false,
patternMatch
);
}
}
}
if (entPtr->isDict())
{
return entPtr->dict().lookupScopedSubEntryPtr
(
keyword.substr(endVar),
keyword.substr(dotPos),
false,
patternMatch
);
}
else
{
// Extract the first word
word firstWord = keyword.substr(0, dotPos);
const entry* entPtr = lookupScopedSubEntryPtr
(
firstWord,
false, //recursive
patternMatch
);
if (!entPtr)
{
// Fall back to finding key with '.' so e.g. if keyword is
// a.b.c.d it would try
// a.b, a.b.c, a.b.c.d
string::size_type nextDotPos = keyword.find
(
'.',
dotPos+1
);
while (true)
{
const entry* subEntPtr = lookupEntryPtr
(
keyword.substr(0, nextDotPos),
false, //recursive,
patternMatch
);
if (nextDotPos == string::npos)
{
// Parsed the whole word. Return entry or null.
return subEntPtr;
}
if (subEntPtr && subEntPtr->isDict())
{
return subEntPtr->dict().lookupScopedSubEntryPtr
(
keyword.substr
(
nextDotPos,
keyword.size()-nextDotPos
),
false,
patternMatch
);
}
nextDotPos = keyword.find('.', nextDotPos+1);
}
}
if (entPtr->isDict())
{
return entPtr->dict().lookupScopedSubEntryPtr
(
keyword.substr(dotPos, keyword.size()-dotPos),
false,
patternMatch
);
}
else
{
return nullptr;
}
}
}
return nullptr;
}
@ -588,7 +575,7 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
bool patternMatch
) const
{
if (keyword[0] == ':')
if (keyword[0] == ':' || keyword[0] == '^')
{
// Go up to top level
const dictionary* dictPtr = this;
@ -597,10 +584,9 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
dictPtr = &dictPtr->parent_;
}
// At top. Recurse to find entries
return dictPtr->lookupScopedSubEntryPtr
(
keyword.substr(1, keyword.size()-1),
keyword.substr(1),
false,
patternMatch
);
@ -617,9 +603,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
const entry* ePtr = lookupScopedEntryPtr(varName, true, true);
@ -631,7 +621,7 @@ bool Foam::dictionary::substituteScopedKeyword(const word& keyword)
forAllConstIter(IDLList<entry>, addDict, iter)
{
add(iter());
add(iter(), mergeEntry);
}
return true;
@ -1034,7 +1024,6 @@ bool Foam::dictionary::changeKeyword
IDLList<entry>::replace(iter2(), iter());
delete iter2();
hashedEntries_.erase(iter2);
}
else
{

View File

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

View File

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

View File

@ -34,12 +34,20 @@ Description
\endverbatim
The possible input modes:
- \par merge merge sub-dictionaries when possible
- \par overwrite keep last entry and silently remove previous ones
- \par protect 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 currently identical to merge
- \par merge
merge sub-dictionaries when possible
- \par overwrite
keep last entry and silently remove previous ones
- \par protect
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
inputModeEntry.C
@ -83,13 +91,13 @@ class inputModeEntry
// Private Member Functions
//- Read the mode as a word and set enum appropriately
static void setMode(Istream&);
static void setMode(Istream& is);
//- Disallow default bitwise copy construct
inputModeEntry(const inputModeEntry&);
inputModeEntry(const inputModeEntry&) = delete;
//- Disallow default bitwise assignment
void operator=(const inputModeEntry&);
void operator=(const inputModeEntry&) = delete;
public:
@ -101,7 +109,7 @@ public:
// Member Functions
//- 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)
static void clear();

View File

@ -67,10 +67,10 @@ class removeEntry
// Private Member Functions
//- Disallow default bitwise copy construct
removeEntry(const removeEntry&);
removeEntry(const removeEntry&) = delete;
//- Disallow default bitwise assignment
void operator=(const removeEntry&);
void operator=(const removeEntry&) = delete;
public:
@ -82,7 +82,7 @@ public:
// Member Functions
//- 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
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
PrimitiveEntry constructor from Istream and Ostream output operator.
\*---------------------------------------------------------------------------*/
#include "primitiveEntry.H"

View File

@ -310,17 +310,17 @@ bool Foam::argList::postProcess(int argc, char *argv[])
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Convert argv -> args_
// Transform sequences with "(" ... ")" into string lists in the process
bool Foam::argList::regroupArgv(int& argc, char**& argv)
{
int nArgs = 0;
int listDepth = 0;
int nArgs = 1;
unsigned listDepth = 0;
string tmpString;
// Note: we also re-write directly into args_
// Note: we rewrite directly into args_
// and use a second pass to sort out args/options
for (int argI = 0; argI < argc; ++argI)
args_[0] = fileName(argv[0]);
for (int argI = 1; argI < argc; ++argI)
{
if (strcmp(argv[argI], "(") == 0)
{
@ -333,7 +333,7 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
{
--listDepth;
tmpString += ")";
if (listDepth == 0)
if (!listDepth)
{
args_[nArgs++] = tmpString;
tmpString.clear();
@ -359,11 +359,21 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
if (tmpString.size())
{
// Group(s) not closed, but flush anything still pending
args_[nArgs++] = tmpString;
}
args_.setSize(nArgs);
std::string::size_type len = (nArgs-1); // Spaces between args
forAll(args_, argi)
{
len += args_[argi].size();
}
// Length needed for regrouped command-line
argListStr_.reserve(len);
return nArgs < argc;
}
@ -403,6 +413,8 @@ void Foam::argList::getRootCase()
globalCase_ = casePath.name();
case_ = globalCase_;
// The name of the executable, unless already present in the environment
setEnv("FOAM_EXECUTABLE", executable_, false);
// Set the case and case-name as an environment variable
if (rootPath_.isAbsolute())
@ -440,7 +452,7 @@ Foam::argList::argList
{
// Check if this run is a parallel run by searching for any parallel option
// If found call runPar which might filter argv
for (int argI = 0; argI < argc; ++argI)
for (int argI = 1; argI < argc; ++argI)
{
if (argv[argI][0] == '-')
{
@ -455,17 +467,11 @@ Foam::argList::argList
}
// Convert argv -> args_ and capture ( ... ) lists
// for normal arguments and for options
regroupArgv(argc, argv);
argListStr_ += args_[0];
// Get executable name
args_[0] = fileName(argv[0]);
executable_ = fileName(argv[0]).name();
// Check arguments and options, we already have argv[0]
// Check arguments and options, argv[0] was already handled
int nArgs = 1;
argListStr_ = args_[0];
for (int argI = 1; argI < args_.size(); ++argI)
{
argListStr_ += ' ';
@ -525,6 +531,9 @@ Foam::argList::argList
args_.setSize(nArgs);
// Set executable name
executable_ = fileName(args_[0]).name();
parse(checkArgs, checkOpts, initialise);
}
@ -769,7 +778,7 @@ void Foam::argList::parse
}
// Distribute the master's argument list (with new root)
bool hadCaseOpt = options_.found("case");
const bool hadCaseOpt = options_.found("case");
for
(
int slave = Pstream::firstSlave();

View File

@ -42,6 +42,8 @@ Description
Default command-line options:
- \par -case \<dir\>
Select a case directory instead of the current working directory
- \par -decomposeParDict \<file\>
Read decomposePar dictionary from specified location
- \par -parallel
Specify case as a parallel job
- \par -doc
@ -51,10 +53,25 @@ Description
- \par -help
Print the usage
The environment variable \b FOAM_CASE is set to the path of the
global case (same for serial and parallel jobs).
The environment variable \b FOAM_CASENAME is set to the name of the
global case.
Additionally, the \b -noFunctionObjects and \b -postProcess options
may be present for some solvers or utilities.
Environment variables set by argList or by Time:
- \par FOAM_CASE
The path of the global case.
It is the same for serial and parallel jobs.
- \par FOAM_CASENAME
The name of the global case.
- \par FOAM_EXECUTABLE
If not already present in the calling environment,
it is set to the \a name portion of the calling executable.
- \par FOAM_APPLICATION
If not already present in the calling environment,
it is set to the value of the \c application entry
(from \c controlDict) if that entry is present.
The value of the \b FOAM_APPLICATION may be inconsistent if the value of
the \c application entry is adjusted during runtime.
Note
- The document browser used is defined by the \b FOAM_DOC_BROWSER
@ -131,10 +148,12 @@ class argList
// * cwd
//
// Also export FOAM_CASE and FOAM_CASENAME environment variables
// so they can be used immediately (eg, in decomposeParDict)
// so they can be used immediately (eg, in decomposeParDict), as well
// as the FOAM_EXECUTABLE environment.
void getRootCase();
//- Transcribe argv into internal args_
//- Transcribe argv into internal args_.
// Transform sequences with "(" ... ")" into string lists
// return true if any "(" ... ")" sequences were captured
bool regroupArgv(int& argc, char**& argv);