dictionary: Handle the distinction between '.' as a keyword character and a scope operator
Patch contributed by Mattijs Janssens Resolves bug-report http://bugs.openfoam.org/view.php?id=2358
This commit is contained in:
parent
a5f3c25c06
commit
01083dd877
2 changed files with 143 additions and 89 deletions
|
|
@ -46,6 +46,131 @@ namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::entry* Foam::dictionary::lookupScopedSubEntryPtr
|
||||||
|
(
|
||||||
|
const word& keyword,
|
||||||
|
bool recursive,
|
||||||
|
bool patternMatch
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
string::size_type dotPos = keyword.find('.');
|
||||||
|
|
||||||
|
if (dotPos == string::npos)
|
||||||
|
{
|
||||||
|
// Non-scoped lookup
|
||||||
|
return lookupEntryPtr(keyword, recursive, patternMatch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dotPos == 0)
|
||||||
|
{
|
||||||
|
// 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 == '.')
|
||||||
|
{
|
||||||
|
++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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictPtr->lookupScopedSubEntryPtr
|
||||||
|
(
|
||||||
|
keyword.substr(endVar),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::dictionary::findInPatterns
|
bool Foam::dictionary::findInPatterns
|
||||||
(
|
(
|
||||||
const bool patternMatch,
|
const bool patternMatch,
|
||||||
|
|
@ -475,7 +600,7 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
|
||||||
}
|
}
|
||||||
|
|
||||||
// At top. Recurse to find entries
|
// At top. Recurse to find entries
|
||||||
return dictPtr->lookupScopedEntryPtr
|
return dictPtr->lookupScopedSubEntryPtr
|
||||||
(
|
(
|
||||||
keyword.substr(1, keyword.size()-1),
|
keyword.substr(1, keyword.size()-1),
|
||||||
false,
|
false,
|
||||||
|
|
@ -484,93 +609,12 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string::size_type dotPos = keyword.find('.');
|
return lookupScopedSubEntryPtr
|
||||||
|
(
|
||||||
if (dotPos == string::npos)
|
keyword,
|
||||||
{
|
recursive,
|
||||||
// Non-scoped lookup
|
patternMatch
|
||||||
return lookupEntryPtr(keyword, recursive, patternMatch);
|
);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (dotPos == 0)
|
|
||||||
{
|
|
||||||
// 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 == '.'
|
|
||||||
)
|
|
||||||
{
|
|
||||||
++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_;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dictPtr->lookupScopedEntryPtr
|
|
||||||
(
|
|
||||||
keyword.substr(endVar),
|
|
||||||
false,
|
|
||||||
patternMatch
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Extract the first word
|
|
||||||
word firstWord = keyword.substr(0, dotPos);
|
|
||||||
|
|
||||||
const entry* entPtr = lookupScopedEntryPtr
|
|
||||||
(
|
|
||||||
firstWord,
|
|
||||||
false, //recursive
|
|
||||||
patternMatch
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!entPtr)
|
|
||||||
{
|
|
||||||
FatalIOErrorInFunction
|
|
||||||
(
|
|
||||||
*this
|
|
||||||
) << "keyword " << firstWord
|
|
||||||
<< " is undefined in dictionary "
|
|
||||||
<< name() << endl
|
|
||||||
<< "Valid keywords are " << keys()
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entPtr->isDict())
|
|
||||||
{
|
|
||||||
return entPtr->dict().lookupScopedEntryPtr
|
|
||||||
(
|
|
||||||
keyword.substr(dotPos, keyword.size()-dotPos),
|
|
||||||
false,
|
|
||||||
patternMatch
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,15 @@ class dictionary
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Find and return an entry data stream pointer if present
|
||||||
|
// otherwise return nullptr. Allows scoping using '.'
|
||||||
|
const entry* lookupScopedSubEntryPtr
|
||||||
|
(
|
||||||
|
const word&,
|
||||||
|
bool recursive,
|
||||||
|
bool patternMatch
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Search patterns table for exact match or regular expression match
|
//- Search patterns table for exact match or regular expression match
|
||||||
bool findInPatterns
|
bool findInPatterns
|
||||||
(
|
(
|
||||||
|
|
@ -364,7 +373,8 @@ public:
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Find and return an entry data stream pointer if present
|
//- Find and return an entry data stream pointer if present
|
||||||
// otherwise return nullptr. Allows scoping using '.'
|
// otherwise return nullptr. Allows scoping using '.'.
|
||||||
|
// Special handling for ':' at start of keyword and '..'.
|
||||||
const entry* lookupScopedEntryPtr
|
const entry* lookupScopedEntryPtr
|
||||||
(
|
(
|
||||||
const word&,
|
const word&,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue