38 template<
class WcIterator,
class ReIterator>
52 ? wcIter()->keyword() == keyword
53 : reIter()->
match(keyword)
74 enum keyType::option matchOpt
77 auto scopePos = keyword.find(
'.');
79 if (scopePos == std::string::npos)
82 return csearch(keyword, matchOpt);
96 string::const_iterator it = keyword.begin()+1;
97 it != keyword.end() && *it ==
'.';
104 dictPtr = &dictPtr->parent_;
109 <<
"No parent of current dictionary when searching for " 117 return dictPtr->csearchDotScoped
119 keyword.substr(scopePos),
127 keyword.substr(0, scopePos),
137 while (!finder.isDict())
139 scopePos = keyword.find(
'.', scopePos+1);
142 finder =
csearch(keyword.substr(0, scopePos), matchOpt);
144 if (scopePos == std::string::npos)
154 return finder.
dict().csearchDotScoped
156 keyword.substr(scopePos),
177 const auto slash = keyword.find(
'/');
179 if (slash == std::string::npos)
183 return csearch(keyword, matchOpt);
191 dictPtr = &dictPtr->parent_;
196 auto cmpts = stringOps::split<std::string>(keyword,
'/');
197 auto remaining = cmpts.size();
199 for (
const auto& cmpt : cmpts)
207 else if (cmpt ==
"..")
212 dictPtr = &dictPtr->parent_;
217 <<
"No parent of current dictionary when searching for " 218 << keyword <<
" at " << cmpt
228 auto finder = dictPtr->csearch(
key, matchOpt);
237 dictPtr = finder.dictPtr();
241 return const_searcher(dictPtr);
270 const_searcher finder(
this);
272 auto iter = hashedEntries_.cfind(keyword);
276 finder.set(iter.val());
282 auto wcLink = patterns_.cbegin();
283 auto reLink = regexps_.cbegin();
286 if (findInPatterns(
false, keyword, wcLink, reLink))
295 return parent_.csearch(keyword, matchOpt);
308 return csearch(keyword, matchOpt);
320 return static_cast<const searcher&
>(finder);
332 return csearchSlashScoped(keyword, matchOpt);
335 if (keyword[0] ==
':' || keyword[0] ==
'^')
344 dictPtr = &dictPtr->parent_;
347 return dictPtr->csearchDotScoped(keyword.substr(1), matchOpt);
350 return csearchDotScoped(keyword, matchOpt);
360 return csearchScoped(keyword, matchOpt);
372 return static_cast<const searcher&
>(finder);
382 if (dictPath.empty())
388 if (dictPath[0] ==
'/')
394 dictPtr = &dictPtr->parent_;
398 fileName
path(dictPath);
402 for (
const auto& cmpt : dictCmpts)
408 else if (cmpt ==
"..")
413 dictPtr = &dictPtr->parent_;
418 <<
"No parent for dictionary while searching " 430 const word cmptName(cmpt.str(),
false);
432 auto iter = dictPtr->hashedEntries_.cfind(cmptName);
436 const entry *eptr = iter.val();
440 dictPtr = eptr->dictPtr();
445 <<
"Found entry '" << cmptName
446 <<
"' but not a dictionary, while searching scoped" 467 const fileName& dictPath
470 return cfindScopedDict(dictPath);
479 const dictionary* ptr = cfindScopedDict(dictPath);
487 if (dictPath.empty())
493 if (dictPath[0] ==
'/')
499 dictPtr =
const_cast<dictionary*
>(&dictPtr->parent_);
503 std::string
path(dictPath);
507 for (
const auto& cmpt : dictCmpts)
513 else if (cmpt ==
"..")
518 dictPtr =
const_cast<dictionary*
>(&dictPtr->parent_);
523 <<
"No parent for dictionary while searching " 535 const word cmptName(cmpt.str(),
false);
537 auto iter = dictPtr->hashedEntries_.find(cmptName);
541 entry *eptr = iter.val();
545 dictPtr = eptr->dictPtr();
550 <<
"Cannot create sub-dictionary entry '" << cmptName
551 <<
"' - a non-dictionary entry is in the way" 552 <<
nl <<
"Encountered in scope" <<
nl 561 dictionaryEntry *eptr =
562 new dictionaryEntry(cmptName, *dictPtr,
dictionary());
567 if (dictPtr->add(eptr,
false))
586 auto iter = hashedEntries_.find(keyword);
591 auto wcLink = patterns_.begin();
592 auto reLink = regexps_.begin();
595 if (findInPatterns(
true, keyword, wcLink, reLink))
597 patterns_.remove(wcLink);
598 regexps_.remove(reLink);
601 parent_type::remove(iter());
603 hashedEntries_.erase(iter);
614 const keyType& oldKeyword,
615 const keyType& newKeyword,
620 if (oldKeyword == newKeyword)
626 auto iter = hashedEntries_.find(oldKeyword);
633 if (iter()->keyword().isPattern())
636 <<
"Old keyword " << oldKeyword <<
" is a pattern." <<
nl 637 <<
"Pattern replacement is not supported." <<
nl 642 auto iter2 = hashedEntries_.find(newKeyword);
649 if (iter2()->keyword().isPattern())
652 auto wcLink = patterns_.begin();
653 auto reLink = regexps_.begin();
656 if (findInPatterns(
true, iter2()->keyword(), wcLink, reLink))
658 patterns_.remove(wcLink);
659 regexps_.remove(reLink);
663 parent_type::replace(iter2(), iter());
665 hashedEntries_.erase(iter2);
670 <<
"Cannot rename keyword " << oldKeyword
671 <<
" to existing keyword " << newKeyword
672 <<
" in dictionary " <<
name() <<
endl;
678 iter()->keyword() = newKeyword;
680 hashedEntries_.erase(oldKeyword);
681 hashedEntries_.insert(newKeyword, iter());
683 if (newKeyword.isPattern())
685 patterns_.push_front(iter());
dict_reference dict() const
Return the found entry as a dictionary. Error if not found, or not a dictionary.
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Foam::SubStrings< StringType > split(const StringType &str, const char delim, std::string::size_type pos=0, const bool keepEmpty=false)
Split string into sub-strings at the delimiter character.
A class for handling file names.
virtual const fileName & name() const
The name of the stream.
bool contains(char c) const noexcept
True if string contains given character (cf. C++23)
errorManipArg< error, int > exit(error &err, const int errNo=1)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
bool clean()
Cleanup filename (inplace)
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool match(const std::string &text) const
Test for equality.
Recursive search (eg, in dictionary)
bool remove(const word &keyword)
Remove an entry specified by keyword.
const_searcher search(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search dictionary for given keyword.
dictionary()
Default construct, a top-level empty dictionary.
const dictionary * findScopedDict(const fileName &dictPath) const
Locate a sub-dictionary using slash-scoping.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Generic const/non-const dictionary entry searcher.
A class for handling words, derived from Foam::string.
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
const dictionary * cfindScopedDict(const fileName &dictPath) const
Locate a sub-dictionary using slash-scoping.
const_searcher csearchScoped(const word &keyword, enum keyType::option matchOpt) const
Search using scoping.
static bool clean(std::string &str)
Cleanup filename string, possibly applies other transformations such as changing the path separator e...
Searcher< true > const_searcher
Searcher with const access.
static fileName concat(const std::string &s1, const std::string &s2, const char delim='/')
Join two strings with a path separator ('/' by default).
const_searcher searchScoped(const word &keyword, enum keyType::option matchOpt) const
Search using dot or slash scoping.
dictionary * makeScopedDict(const fileName &dictPath)
Locate existing or create sub-dictionary using slash-scoping.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
option
Enumeration for the data type and search/match modes (bitmask)
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
const_searcher csearch(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search dictionary for given keyword.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
bool changeKeyword(const keyType &oldKeyword, const keyType &newKeyword, bool overwrite=false)
Change the keyword for an entry,.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...