dynamicCodeContext: Lookup variables from the context dictionary
codeStream (#calc etc.) creates a local sub-dictionary in which to expand the
code so variable lookup needs to be checked with respect to the context
dictionary rather than with respect to the code sub-dictionary. With this
change the following test/dictionary/testCalc #calc example now works:
a 1.1;
d
{
b 4.8;
}
// Access to higher-level sub-entries using the "../" operators, e.g.
f
{
g #calc "$a / $../d/b";
}
This commit is contained in:
@ -85,13 +85,14 @@ bool Foam::functionEntries::codeStream::masterOnlyRead
|
||||
Foam::functionEntries::codeStream::streamingFunctionType
|
||||
Foam::functionEntries::codeStream::getFunction
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
const dictionary& contextDict,
|
||||
const dictionary& codeDict
|
||||
)
|
||||
{
|
||||
// Get code, codeInclude, ...
|
||||
const dynamicCodeContext context
|
||||
(
|
||||
contextDict,
|
||||
codeDict,
|
||||
{"code", "codeInclude", "localCode"},
|
||||
{"dict", word::null, word::null}
|
||||
@ -162,7 +163,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
parentDict
|
||||
contextDict
|
||||
) << "Failed writing files for" << nl
|
||||
<< dynCode.libRelPath() << nl
|
||||
<< exit(FatalIOError);
|
||||
@ -173,7 +174,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
parentDict
|
||||
contextDict
|
||||
) << "Failed wmake " << dynCode.libRelPath() << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
@ -182,7 +183,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
// Only block if not master only reading of a global dictionary
|
||||
if
|
||||
(
|
||||
!masterOnlyRead(parentDict)
|
||||
!masterOnlyRead(contextDict)
|
||||
&& regIOobject::fileModificationSkew > 0
|
||||
)
|
||||
{
|
||||
@ -224,7 +225,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
parentDict
|
||||
contextDict
|
||||
) << "Cannot read (NFS mounted) library " << nl
|
||||
<< libPath << nl
|
||||
<< "on processor " << Pstream::myProcNo()
|
||||
@ -272,7 +273,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
parentDict
|
||||
contextDict
|
||||
) << "Failed loading library " << libPath << nl
|
||||
<< "Did you add all libraries to the 'libs' entry"
|
||||
<< " in system/controlDict?"
|
||||
@ -280,7 +281,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
}
|
||||
|
||||
bool haveLib = lib;
|
||||
if (!masterOnlyRead(parentDict))
|
||||
if (!masterOnlyRead(contextDict))
|
||||
{
|
||||
reduce(haveLib, andOp<bool>());
|
||||
}
|
||||
@ -289,7 +290,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
parentDict
|
||||
contextDict
|
||||
) << "Failed loading library " << libPath
|
||||
<< " on some processors."
|
||||
<< exit(FatalIOError);
|
||||
@ -308,7 +309,7 @@ Foam::functionEntries::codeStream::getFunction
|
||||
{
|
||||
FatalIOErrorInFunction
|
||||
(
|
||||
parentDict
|
||||
contextDict
|
||||
) << "Failed looking up symbol " << dynCode.codeName()
|
||||
<< " in library " << lib << exit(FatalIOError);
|
||||
}
|
||||
@ -319,31 +320,31 @@ Foam::functionEntries::codeStream::getFunction
|
||||
|
||||
Foam::string Foam::functionEntries::codeStream::run
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
const dictionary& contextDict,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Using #codeStream at line " << is.lineNumber()
|
||||
<< " in file " << parentDict.name() << endl;
|
||||
<< " in file " << contextDict.name() << endl;
|
||||
}
|
||||
|
||||
dynamicCode::checkSecurity
|
||||
(
|
||||
"functionEntries::codeStream::execute(..)",
|
||||
parentDict
|
||||
contextDict
|
||||
);
|
||||
|
||||
// Construct codeDict for codeStream
|
||||
// Parent dictionary provided for string expansion and variable substitution
|
||||
const dictionary codeDict("#codeStream", parentDict, is);
|
||||
const dictionary codeDict("#codeStream", contextDict, is);
|
||||
|
||||
const streamingFunctionType function = getFunction(parentDict, codeDict);
|
||||
const streamingFunctionType function = getFunction(contextDict, codeDict);
|
||||
|
||||
// Use function to write stream
|
||||
OStringStream os(is.format());
|
||||
(*function)(os, parentDict);
|
||||
(*function)(os, contextDict);
|
||||
|
||||
// Return the string containing the results of the code execution
|
||||
return os.str();
|
||||
@ -354,22 +355,22 @@ Foam::string Foam::functionEntries::codeStream::run
|
||||
|
||||
bool Foam::functionEntries::codeStream::execute
|
||||
(
|
||||
dictionary& parentDict,
|
||||
dictionary& contextDict,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
return insert(parentDict, run(parentDict, is));
|
||||
return insert(contextDict, run(contextDict, is));
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionEntries::codeStream::execute
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
const dictionary& contextDict,
|
||||
primitiveEntry& thisEntry,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
return insert(parentDict, thisEntry, run(parentDict, is));
|
||||
return insert(contextDict, thisEntry, run(contextDict, is));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -222,14 +222,14 @@ class codeStream
|
||||
//- Construct, compile, load and return streaming function
|
||||
static streamingFunctionType getFunction
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
const dictionary& contextDict,
|
||||
const dictionary& codeDict
|
||||
);
|
||||
|
||||
//- Compile and execute the code and return the resulting string
|
||||
static string run
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
const dictionary& contextDict,
|
||||
Istream& is
|
||||
);
|
||||
|
||||
@ -260,12 +260,12 @@ public:
|
||||
// Member Functions
|
||||
|
||||
//- Execute the functionEntry in a sub-dict context
|
||||
static bool execute(dictionary& parentDict, Istream&);
|
||||
static bool execute(dictionary& contextDict, Istream&);
|
||||
|
||||
//- Execute the functionEntry in a primitiveEntry context
|
||||
static bool execute
|
||||
(
|
||||
const dictionary& parentDict,
|
||||
const dictionary& contextDict,
|
||||
primitiveEntry&,
|
||||
Istream&
|
||||
);
|
||||
|
||||
@ -44,12 +44,13 @@ void Foam::dynamicCodeContext::addLineDirective
|
||||
|
||||
Foam::dynamicCodeContext::dynamicCodeContext
|
||||
(
|
||||
const dictionary& dict,
|
||||
const dictionary& contextDict,
|
||||
const dictionary& codeDict,
|
||||
const wordList& codeKeys,
|
||||
const wordList& codeDictVars
|
||||
)
|
||||
:
|
||||
dict_(dict),
|
||||
contextDict_(contextDict),
|
||||
code_(),
|
||||
options_(),
|
||||
libs_()
|
||||
@ -61,11 +62,16 @@ Foam::dynamicCodeContext::dynamicCodeContext
|
||||
forAll(codeKeys, i)
|
||||
{
|
||||
const word& key = codeKeys[i];
|
||||
codePtrs[i] = dict.lookupEntryPtr(key, false, false);
|
||||
codePtrs[i] = codeDict.lookupEntryPtr(key, false, false);
|
||||
if (codePtrs[i])
|
||||
{
|
||||
string s(stringOps::trim(verbatimString(codePtrs[i]->stream())));
|
||||
stringOps::inplaceExpandCodeString(s, dict, codeDictVars[i]);
|
||||
stringOps::inplaceExpandCodeString
|
||||
(
|
||||
s,
|
||||
contextDict, // Lookup variables from the context dictionary
|
||||
codeDictVars[i]
|
||||
);
|
||||
code_.insert(key, s);
|
||||
}
|
||||
else
|
||||
@ -75,19 +81,20 @@ Foam::dynamicCodeContext::dynamicCodeContext
|
||||
}
|
||||
|
||||
// Options
|
||||
const entry* optionsPtr = dict.lookupEntryPtr("codeOptions", false, false);
|
||||
const entry* optionsPtr =
|
||||
codeDict.lookupEntryPtr("codeOptions", false, false);
|
||||
if (optionsPtr)
|
||||
{
|
||||
options_ = stringOps::trim(verbatimString(optionsPtr->stream()));
|
||||
stringOps::inplaceExpandCodeString(options_, dict, word::null);
|
||||
stringOps::inplaceExpandCodeString(options_, contextDict, word::null);
|
||||
}
|
||||
|
||||
// Libs
|
||||
const entry* libsPtr = dict.lookupEntryPtr("codeLibs", false, false);
|
||||
const entry* libsPtr = codeDict.lookupEntryPtr("codeLibs", false, false);
|
||||
if (libsPtr)
|
||||
{
|
||||
libs_ = stringOps::trim(verbatimString(libsPtr->stream()));
|
||||
stringOps::inplaceExpandCodeString(libs_, dict, word::null);
|
||||
stringOps::inplaceExpandCodeString(libs_, contextDict, word::null);
|
||||
}
|
||||
|
||||
// Calculate SHA1 digest from all entries
|
||||
@ -110,11 +117,22 @@ Foam::dynamicCodeContext::dynamicCodeContext
|
||||
(
|
||||
code_[key],
|
||||
codePtrs[i]->startLineNumber(),
|
||||
dict.name()
|
||||
codeDict.name()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::dynamicCodeContext::dynamicCodeContext
|
||||
(
|
||||
const dictionary& contextDict,
|
||||
const wordList& codeKeys,
|
||||
const wordList& codeDictVars
|
||||
)
|
||||
:
|
||||
dynamicCodeContext(contextDict, contextDict, codeKeys, codeDictVars)
|
||||
{}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -52,8 +52,8 @@ class dynamicCodeContext
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The parent dictionary context
|
||||
const dictionary& dict_;
|
||||
//- The context dictionary
|
||||
const dictionary& contextDict_;
|
||||
|
||||
//- Code entries
|
||||
HashTable<string> code_;
|
||||
@ -84,11 +84,21 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from a dictionary and lists of which entries correspond
|
||||
// to code
|
||||
//- Construct from the context and code dictionaries
|
||||
// and lists of which entries correspond to code
|
||||
dynamicCodeContext
|
||||
(
|
||||
const dictionary& dict,
|
||||
const dictionary& contextDict,
|
||||
const dictionary& codeDict,
|
||||
const wordList& codeKeys,
|
||||
const wordList& codeDictVars
|
||||
);
|
||||
|
||||
//- Construct from the context dictionary also containing the code
|
||||
// and lists of which entries correspond
|
||||
dynamicCodeContext
|
||||
(
|
||||
const dictionary& contextDict,
|
||||
const wordList& codeKeys,
|
||||
const wordList& codeDictVars
|
||||
);
|
||||
@ -96,10 +106,10 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the parent dictionary context
|
||||
//- Return the context dictionary
|
||||
const dictionary& dict() const
|
||||
{
|
||||
return dict_;
|
||||
return contextDict_;
|
||||
}
|
||||
|
||||
//- Return the code table
|
||||
|
||||
@ -36,6 +36,12 @@ d
|
||||
}
|
||||
e #calc "$a / $d/b";
|
||||
|
||||
// Access to higher-level sub-entries using the "../" operators, e.g.
|
||||
f
|
||||
{
|
||||
g #calc "$a / $../d/b";
|
||||
}
|
||||
|
||||
s "field";
|
||||
fieldName #calc "$<string>s + \"Name\"";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user