Commit c300fd5c authored by Henry Weller's avatar Henry Weller
Browse files

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
parent ab760b6c
......@@ -46,6 +46,131 @@ namespace Foam
// * * * * * * * * * * * * * 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
(
const bool patternMatch,
......@@ -475,7 +600,7 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
}
// At top. Recurse to find entries
return dictPtr->lookupScopedEntryPtr
return dictPtr->lookupScopedSubEntryPtr
(
keyword.substr(1, keyword.size()-1),
false,
......@@ -484,93 +609,12 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
}
else
{
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->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;
}
}
}
return lookupScopedSubEntryPtr
(
keyword,
recursive,
patternMatch
);
}
}
......
......@@ -161,6 +161,15 @@ class dictionary
// 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
bool findInPatterns
(
......@@ -364,7 +373,8 @@ public:
) const;
//- 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 word&,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment