diff --git a/applications/test/dictionary/testSubkeyword b/applications/test/dictionary/testSubkeyword new file mode 100644 index 0000000000000000000000000000000000000000..f8ee14850114e03cb7256b61966628fdd6f43980 --- /dev/null +++ b/applications/test/dictionary/testSubkeyword @@ -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 + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C index 2b7ab51888cf65e035a4f71c7450c9c4328119e6..c20a9655780968ec46788d4a6850eff433777dd0 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoam.C @@ -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) { diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C index e64f031dec7ac2e5d126f93c8e2403f1db7f6520..39c60bb7380df4a11f67d1b48a7f2f7fd6dfadd3 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/PVblockMeshReader/vtkPVblockMesh/vtkPVblockMesh.C @@ -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) { diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C index ea449f50e6dc5911a018b6e8df161300cbc45303..08c702fee3baeb78724778afae6314da0d863ecd 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.C +++ b/src/OpenFOAM/db/dictionary/dictionary.C @@ -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 2nd '.' found - - const dictionary* dictPtr = this; + // Starting with a '.' -> go up for every further '.' found + ++dotPos; - string::size_type begVar = dotPos + 1; - string::const_iterator iter = keyword.begin() + begVar; - string::size_type endVar = begVar; - while (iter != keyword.end() && *iter == '.') + const dictionary* dictPtr = this; + for + ( + string::const_iterator it = keyword.begin()+1; + it != keyword.end() && *it == '.'; + ++dotPos, ++it + ) + { + // 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 - ( - keyword.substr(endVar), - false, - patternMatch - ); + return nullptr; + } } - else - { - // Extract the first word - word firstWord = keyword.substr(0, dotPos); - const entry* entPtr = lookupScopedSubEntryPtr - ( - firstWord, - false, //recursive - patternMatch - ); + 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 - if (!entPtr) + while (true) { - // 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 + dotPos = keyword.find('.', dotPos+1); - string::size_type nextDotPos = keyword.find + entPtr = lookupEntryPtr ( - '.', - dotPos+1 + keyword.substr(0, dotPos), + false, + patternMatch ); - while (true) + if (dotPos == string::npos) + { + // Parsed the whole word. Return entry or null. + return entPtr; + } + + if (entPtr && entPtr->isDict()) { - const entry* subEntPtr = lookupEntryPtr + return entPtr->dict().lookupScopedSubEntryPtr ( - keyword.substr(0, nextDotPos), - false, //recursive, + keyword.substr(dotPos), + false, 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; - } + if (entPtr->isDict()) + { + return entPtr->dict().lookupScopedSubEntryPtr + ( + keyword.substr(dotPos), + false, + patternMatch + ); } } + + 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 { diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H index 6f03c6babcaf9152fc7b5db5ebfc3043ea28a2b0..a2031ede037c13586c28d658af516bfd43488f62 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.H +++ b/src/OpenFOAM/db/dictionary/dictionary.H @@ -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 - - 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. - - To add - a merge() member function with a non-const dictionary parameter? - This would avoid unnecessary cloning in the add(entry*, bool) method. + 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. + + 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 + + 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); }; diff --git a/src/OpenFOAM/db/dictionary/dictionaryIO.C b/src/OpenFOAM/db/dictionary/dictionaryIO.C index 231e3bc44b58a5041055ea02a0639e29cea6fc42..1d55ff27946c9b357592e63a554b4e6320744e7d 100644 --- a/src/OpenFOAM/db/dictionary/dictionaryIO.C +++ b/src/OpenFOAM/db/dictionary/dictionaryIO.C @@ -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; diff --git a/src/OpenFOAM/db/dictionary/entry/entryIO.C b/src/OpenFOAM/db/dictionary/entry/entryIO.C index 2a10aee4b89c73a6154fbc4483ccb83b9322bbbb..4f7b3e4f0fd318d7ecd6697968d93a4fda6ccad6 100644 --- a/src/OpenFOAM/db/dictionary/entry/entryIO.C +++ b/src/OpenFOAM/db/dictionary/entry/entryIO.C @@ -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; diff --git a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C index 96472b71cd4a0e9a3063e229e67694c58773e828..fbb6787ca1b8a982a6d56cc9d15d3d59e6f9df7c 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.C @@ -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 ) { diff --git a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H index 623524cd8048e9de4e327aa5bca77ada10fb1d0d..66c98243ade466db489fdbc213fb90402690dce9 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H +++ b/src/OpenFOAM/db/dictionary/functionEntries/inputModeEntry/inputModeEntry.H @@ -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(); diff --git a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H index 6ad9eb402e3a883c942d51e1578eb1f5a44abcb1..8508141f64dbd0cba9bed55967785a1ae1f502b7 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H +++ b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.H @@ -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); }; diff --git a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C index 8777819d450672c0b03be9f80f61982d01757541..1c447e88abcbe44dadb7ccb65a88538ca226fa24 100644 --- a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C +++ b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C @@ -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" diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index 7288489070c3567bbf6d1b7d51c1d6050b5320ff..fad74c2dd0abe63e349775d70cd8255c54bd4a8f 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -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(); diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H index 2bc6d288ccee38b853701910e466f3f2c5f56391..09c6777261cedff59a35f29fee42d26c6951b200 100644 --- a/src/OpenFOAM/global/argList/argList.H +++ b/src/OpenFOAM/global/argList/argList.H @@ -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);