103 for (
const entry& dEntry : boundaryDict)
105 if (!dEntry.isDict())
110 const word& patchName = dEntry.keyword();
116 for (
const word& groupName : groupNames)
118 auto groupIter = groupToPatch.
find(groupName);
119 if (groupIter.found())
121 (*groupIter).append(patchName);
136 const bool addNonExisting,
149 const entry& mergeEntry,
150 const bool literalRE,
154 bool changed =
false;
178 thisDict.
add(mergeEntry.
clone(thisDict).ptr(),
true);
202 else if (shortcuts.
size())
207 for (
const label idx : indices)
209 const word&
name = shortcutNames[idx];
213 const label index = thisKeys.
find(keys[j]);
232 const bool addNonExisting,
235 const bool literalRE,
241 bool changed =
false;
246 for (
const word&
k : thisDict.
keys(
false))
254 for (
const entry& mergeEntry : mergeDict)
260 const word eraseKey =
key.substr(1);
261 if (thisDict.
remove(eraseKey))
265 thisKeysSet.
erase(eraseKey);
269 else if (literalRE || !(
key.isPattern() || shortcuts.
found(key)))
299 thisDict.
add(mergeEntry.
clone(thisDict).ptr());
305 <<
"Ignoring non-existing entry " <<
key
315 if (!literalRE && thisKeysSet.
size())
320 for (
const entry& mergeEntry : mergeDict)
326 const word eraseKey =
key.substr(1);
341 for (
const label matchi : matches)
343 const word&
k = thisKeys[matchi];
363 for (
const label matchi : matches)
365 const word&
k = thisKeys[matchi];
394int main(
int argc,
char *argv[])
398 "Utility to change dictionary entries"
399 " (such as the patch type for fields and polyMesh/boundary files)."
402 argList::addOption(
"dict",
"file",
"Alternative changeDictionaryDict");
408 "Specify the subDict name of the replacements dictionary"
414 "Override instance setting (default is the time name)"
418 timeSelector::addOptions();
420 argList::addBoolOption
423 "Treat regular expressions literally (i.e., as a keyword)"
425 argList::addBoolOption
427 "enableFunctionEntries",
428 "Enable expansion of dictionary directives - #include, #codeStream etc"
430 argList::addBoolOption
432 "disablePatchGroups",
433 "Disable matching keys to patch groups"
443 if (times.
size() < 1)
446 <<
"No times selected." <<
exit(FatalError);
453 if (times.
size() > 1)
456 <<
"Multiple times selected with 'instance' option"
462 runTime.setTime(times[timei], timei);
468 const bool literalRE =
args.
found(
"literalRE");
471 Info<<
"Not interpreting any regular expressions (RE)"
472 <<
" in the changeDictionaryDict." <<
endl
473 <<
"Instead they are handled as any other entry, i.e. added if"
474 <<
" not present." <<
endl;
477 const bool enableEntries =
args.
found(
"enableFunctionEntries");
480 Info<<
"Allowing dictionary preprocessing (#include, #codeStream)."
484 const int oldFlag = entry::disableFunctionEntries;
488 entry::disableFunctionEntries = 1;
492 const bool disablePatchGroups =
args.
found(
"disablePatchGroups");
493 if (disablePatchGroups)
495 Info<<
"Not interpreting any keys in the changeDictionary"
503 IOobject::fileModificationChecking = IOobject::timeStamp;
516 replaceDictsPtr = &
dict.subDict(
args[
"subDict"]);
519 const dictionary& replaceDicts = *replaceDictsPtr;
521 Info<<
"Read dictionary " <<
dict.name()
522 <<
" with replacements for dictionaries "
530 Info<<
"Reading polyMesh/boundary file to extract patch names"
543 polyMesh::regionName(
regionName)/polyMesh::meshSubDir,
545 IOobject::READ_IF_PRESENT
547 polyMesh::meshSubDir,
549 IOobject::READ_IF_PRESENT,
557 const_cast<word&
>(dictList.type()) = dictList.headerClassName();
561 for (
const entry&
e : dictList)
565 fieldDict.
add(
e.keyword(),
e.dict());
571 Info<<
"Loaded dictionary " << dictList.name()
572 <<
" with entries " << fieldDict.
toc() <<
endl;
578 if (!disablePatchGroups)
580 patchGroups = extractPatchGroups(fieldDict);
581 if (patchGroups.
size())
583 Info<<
"Extracted patch groups:" <<
endl;
587 Info<<
" group " << groups[i] <<
" with patches "
588 << patchGroups[groups[i]] <<
endl;
596 for (
const entry& replaceEntry : replaceDicts)
598 if (!replaceEntry.isDict())
604 const word& fieldName = replaceEntry.keyword();
605 const dictionary& replaceDict = replaceEntry.dict();
607 Info<<
"Replacing entries in dictionary " << fieldName <<
endl;
612 if (fieldName ==
"boundary")
614 Info<<
"Special handling of " << fieldName
615 <<
" as polyMesh/boundary file." <<
endl;
618 Info<<
"Merging entries from " << replaceDict.
toc() <<
endl;
619 merge(
false, fieldDict, replaceDict, literalRE, patchGroups);
621 Info<<
"fieldDict:" << fieldDict <<
endl;
626 label nEntries = fieldDict.size();
631 doneKeys[i] = dictList[i].keyword();
641 dictList.set(nEntries++, ePtr->
clone());
642 fieldDict.
remove(doneKeys[i]);
647 for (
const entry&
e : fieldDict)
649 dictList.set(nEntries++,
e.clone());
651 dictList.setSize(nEntries);
653 Info<<
"Writing modified " << fieldName <<
endl;
664 Info<<
"Loading dictionary " << fieldName <<
endl;
665 const word oldTypeName = IOdictionary::typeName;
673 IOobject::MUST_READ_IF_MODIFIED,
682 const_cast<word&
>(IOdictionary::typeName) = oldTypeName;
685 const_cast<word&
>(fieldDict.type()) =
686 fieldDict.headerClassName();
688 Info<<
"Loaded dictionary " << fieldName
689 <<
" with entries " << fieldDict.toc() <<
endl;
692 Info<<
"Merging entries from " << replaceDict.
toc() <<
endl;
693 merge(
true, fieldDict, replaceDict, literalRE, patchGroups);
695 Info<<
"Writing modified fieldDict " << fieldName <<
endl;
696 fieldDict.regIOobject::write();
701 <<
"Requested field to change " << fieldName
702 <<
" does not exist in " << fieldHeader.path() <<
endl;
706 entry::disableFunctionEntries = oldFlag;
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
A HashTable similar to std::unordered_map.
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
bool found(const Key &key) const
Return true if hashed entry is found in table.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
label size() const noexcept
The number of elements in table.
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
A PtrList of objects of type <T> with automated input and output.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
The IOstreamOption is a simple container for options an IOstream can normally have.
void append(const T &val)
Append an element at the end of the list.
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
void size(const label n)
Older name for setAddressableSize.
bool found(const word &optName) const
Return true if the named option is found.
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find for an entry (non-const access) with the given keyword.
bool remove(const word &keyword)
Remove an entry specified by keyword.
List< keyType > keys(bool patterns=false) const
Return the list of available keys or patterns.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
wordList toc() const
Return the table of contents.
A keyword and a list of tokens is an 'entry'.
virtual bool isDict() const noexcept
Return true if this entry is a dictionary.
virtual autoPtr< entry > clone(const dictionary &parentDict) const =0
Construct on freestore as copy with reference to the.
const keyType & keyword() const noexcept
Return keyword.
virtual const dictionary & dict() const =0
Return dictionary, if entry is a dictionary.
A class for handling keywords in dictionaries.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
A class for handling words, derived from Foam::string.
#define defineTemplateTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information for templates, useful.
Foam::word regionName(Foam::polyMesh::defaultRegion)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const word dictName("faMeshDefinition")
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
errorManipArg< error, int > exit(error &err, const int errNo=1)
labelList findStrings(const regExp &matcher, const UList< StringType > &input, const bool invert=false)
Return list indices for strings matching the regular expression.
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
Operations on lists of strings.