38 template<
class WcIterator,
class ReIterator>
39 static bool findInPatterns
41 const bool patternMatch,
52 ? reIter()->match(keyword)
53 : wcIter()->keyword() == keyword
74 enum keyType::option matchOpt
77 auto scopePos = keyword.find(
'.');
79 if (scopePos == 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 == string::npos)
154 return finder.
dict().csearchDotScoped
156 keyword.substr(scopePos),
175 const dictionary* dictPtr =
this;
177 const auto slash = keyword.find(
'/');
179 if (slash == 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);
258 return const_searcher(dictPtr);
272 auto iter = hashedEntries_.cfind(keyword);
276 finder.
set(iter.val());
282 auto wcLink = patterns_.cbegin();
283 auto reLink = regexps_.cbegin();
286 if (findInPatterns(
true, keyword, wcLink, reLink))
295 return parent_.csearch(keyword, matchOpt);
308 return csearch(keyword, matchOpt);
320 return static_cast<const searcher&
>(finder);
330 if (keyword.find(
'/') != string::npos)
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())
393 dictPtr = &dictPtr->parent_;
400 for (
const word& cmpt : cmpts)
406 else if (cmpt ==
"..")
411 dictPtr = &dictPtr->parent_;
416 <<
"No parent for dictionary while searching "
428 auto iter = dictPtr->hashedEntries_.cfind(cmpt);
432 const entry *eptr = iter.val();
441 <<
"Found entry '" << cmpt
442 <<
"' but not a dictionary, while searching scoped"
466 return cfindScopedDict(dictPath);
475 const dictionary* ptr = cfindScopedDict(dictPath);
483 if (dictPath.empty())
494 dictPtr =
const_cast<dictionary*
>(&dictPtr->parent_);
499 std::string
path = dictPath;
505 for (
const auto& cmpt : cmpts)
511 else if (cmpt ==
"..")
516 dictPtr =
const_cast<dictionary*
>(&dictPtr->parent_);
521 <<
"No parent for dictionary while searching "
533 const word cmptName(cmpt.str(),
false);
535 auto iter = dictPtr->hashedEntries_.find(cmptName);
539 entry *eptr = iter.val();
548 <<
"Cannot create sub-dictionary entry '" << cmptName
549 <<
"' - a non-dictionary entry is in the way"
550 <<
nl <<
"Encountered in scope" <<
nl
565 if (dictPtr->
add(eptr,
false))
584 auto iter = hashedEntries_.find(keyword);
589 auto wcLink = patterns_.begin();
590 auto reLink = regexps_.begin();
593 if (findInPatterns(
false, keyword, wcLink, reLink))
595 patterns_.remove(wcLink);
596 regexps_.remove(reLink);
599 parent_type::remove(iter());
601 hashedEntries_.erase(iter);
618 if (oldKeyword == newKeyword)
624 auto iter = hashedEntries_.find(oldKeyword);
631 if (iter()->keyword().isPattern())
634 <<
"Old keyword " << oldKeyword <<
" is a pattern." <<
nl
635 <<
"Pattern replacement is not supported." <<
nl
640 auto iter2 = hashedEntries_.find(newKeyword);
647 if (iter2()->keyword().isPattern())
650 auto wcLink = patterns_.begin();
651 auto reLink = regexps_.begin();
654 if (findInPatterns(
false, iter2()->keyword(), wcLink, reLink))
656 patterns_.remove(wcLink);
657 regexps_.remove(reLink);
661 parent_type::replace(iter2(), iter());
663 hashedEntries_.erase(iter2);
668 <<
"Cannot rename keyword " << oldKeyword
669 <<
" to existing keyword " << newKeyword
670 <<
" in dictionary " <<
name() <<
endl;
676 iter()->keyword() = newKeyword;
677 iter()->name() =
name() +
'.' + newKeyword;
678 hashedEntries_.erase(oldKeyword);
679 hashedEntries_.insert(newKeyword, iter());
683 patterns_.insert(iter());