Commit 1cf795a4 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: use exprString expansions for #eval

- follows the principle of least surprise if the expansion behaviour
  for #eval and expressions (eg, exprFixedValue) are the same.  This
  is possible now that we harness the regular stringOps::expand()
  within exprString::expand()
parent c1b07cd1
......@@ -47,10 +47,10 @@ eval6b #eval " pi() * 2 * ${{ ${unknown:-0} * ${{ 15 * 3 }} }} + 5";
eval6c #eval " pi() * 2 * ${{ -${unknown:-0} * ${{ 15 * 3 }} }} + 5";
// Even this work
eval7a #eval " pi() * 1 * ${factor${{2*5}}:-100}";
eval7a #eval " pi() * 1 * ${factor${{2*5}}:-100}";
// Even this work
eval7b #eval " pi() * 1 * ${factorXYZ${{2*5}}:-100}";
eval7b #eval " pi() * 1 * ${factorXYZ${{2*5}}:-100}";
index 10;
......@@ -58,7 +58,40 @@ eval8a #eval " pi() * 2 * ${{ ${factor$index} + ${factor10} }}";
eval8b #eval " pi() * 2 * $factor * ${{ 100 }}";
eval10a #eval "vector(1,2,3) * 5";
eval10a #eval "vector(1,2,3) * 5";
// Slightly stranger ideas:
axis1 (1 0 0);
axis2 (0 1 0);
axis3 (0 0 1);
index 100;
location #eval #{
400 *
// Numerator: use the index to get relevant suffix [1,2,3]
// to form the lookup of axis1,axis2,...
// Treat the lookup as a vector within the expression evaluation
$[(vector) axis${{
($index % 3) + 1 /* Evaluates: 1,2,3 from index */ }}
]
// Denominator: divide by index with zero-division protection
/ ${{max(1, $index)}}
// Same thing, but using expressions-syntax for variable lookup
/ ${{max(1, $[index])}}
#};
// This is still a rather clunky syntax
length #eval{ cbrt(mag($[(vector) location])) };
// Remove evidence of some variables
#remove ("axis[0-9]*" index)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -231,6 +231,9 @@ std::string Foam::ITstream::toString() const
label len = tokens.size();
// NOTE: may wish to have special handling if there is a single token
// and it is already a string or word
for (const token& tok : tokens)
{
buf << tok;
......
......@@ -105,10 +105,10 @@ Foam::tokenList Foam::functionEntries::evalEntry::evaluate
<< "input: " << s << endl;
#endif
// Expanding with env-variables, with empty
stringOps::inplaceRemoveComments(s);
stringOps::inplaceExpand(s, parentDict, true, true);
// Expand with env=true, empty=true, subDict=false
// with comments stripped.
// Special handling of $[...] syntax enabled.
expressions::exprString::inplaceExpand(s, parentDict, true);
stringOps::inplaceTrim(s);
// An extraneous trailing ';' is a common input error, catch it now.
......
......@@ -223,12 +223,15 @@ void Foam::exprTools::expressionEntry::inplaceExpand
stringOps::inplaceTrim(varName);
// Allow recursive plain expansion for the *variable* name.
// This means "$[(vector) var${index] ]" should work
stringOps::inplaceExpand(varName, dict);
// This means "$[(vector) var${index} ]" should work
// Expand with env=true, empty=true, subDict=false
stringOps::inplaceExpand(varName, dict, true, true, false);
// Length of original text to replace (incl. decorators)
const auto replaceLen = (varEnd - varBeg + 1);
// Get primitiveEntry with env=false, subDict=false
const entry* eptr = getVariableOrDie(varName, dict);
std::string varValue;
......@@ -236,7 +239,17 @@ void Foam::exprTools::expressionEntry::inplaceExpand
if (castTo.empty())
{
// Serialized with spaces
varValue = eptr->stream().toString();
ITstream& its = eptr->stream();
if (its.size() == 1 && its[0].isStringType())
{
// Already a string-type (WORD, STRING, ...). Just copy.
varValue = its[0].stringToken();
}
else
{
varValue = its.toString();
}
}
else
{
......@@ -258,7 +271,8 @@ void Foam::exprTools::expressionEntry::inplaceExpand
// - this is done second such that $[(vector) xyz] entries will have
// been properly expanded by this stage
stringOps::inplaceExpand(s, dict);
// Expand with env=true, empty=true, subDict=false
stringOps::inplaceExpand(s, dict, true, true, false);
}
......
......@@ -134,7 +134,14 @@ public:
//- Generic concatenate tokens to space-separated string.
inline static string evaluate(const entry& e);
//- Inplace expand expression with dictionary entries
//- Inplace expand expression with dictionary variables/entries
//
// \par Expansion behaviour
// - alternatives = True
// - environment = True
// - allow empty = True
// - subDict = False
// .
static void inplaceExpand
(
std::string& s,
......
......@@ -118,7 +118,14 @@ public:
// Static Member Functions
//- Inplace expansion with dictionary variables,
//- and strip C/C++ comments from the input
//- and strip C/C++ comments from the input.
//
// \par Expansion behaviour
// - alternatives = True
// - environment = True
// - allow empty = True
// - subDict = False
// .
static void inplaceExpand
(
std::string& str,
......@@ -127,7 +134,9 @@ public:
);
//- Get and expand expression with dictionary entries,
//- optionally strip C/C++ comments from the input
//- optionally strip C/C++ comments from the input.
//
// Expansion behaviour as per inplaceExpand
static exprString getExpression
(
const word& name,
......
......@@ -252,7 +252,7 @@ static inline std::string entryToString
if (pe.size() == 1 && pe[0].isStringType())
{
// Already a string-type. Just copy.
// Already a string-type (WORD, STRING, ...). Just copy.
str = pe[0].stringToken();
}
else
......
......@@ -28,8 +28,7 @@ Namespace
Foam::stringOps
Description
Collection of static functions to do various simple string-related
operations
Collection of static functions for various string-related operations
SourceFiles
stringOps.C
......@@ -93,34 +92,37 @@ namespace stringOps
//- Does \b not use environment values.
//
// Expansion includes:
// -# variables
// -# Variables
// - \c $VAR
// - \c ${VAR}
// - \c ${VAR:-defValue}
// - \c ${VAR:+altValue}
//
// Default and alternative values as per the POSIX shell:
// \code
// 1. ${parameter:-defValue}
// 2. ${parameter:+altValue}
// \endcode
// -# If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
// -# If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
// -# Default and alternative values as per the POSIX shell:
// - \c ${parameter:-defValue}
// If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
// - \c ${parameter:+altValue}
// If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
// .
//
// General behaviour:
// - Unknown entries are removed silently.
// - Malformed entries (eg, brace mismatch, sigil followed by bad chars)
// are left as is.
//
// Currently only used by dynamicCode.
// - Malformed entries (eg, brace mismatch, sigil followed by unknown
// characters) are left as is.
//
// \param[in,out] s The string to modify inplace.
// \param mapping The lookup table
// \param sigil The leading sigil. Can be changed to avoid conflict
// with other string expansions. (default: '$')
//
// \par Expansion behaviour
// - alternatives = True
// - environment = False
// - allow empty = True
// - subDict = Not applicable
// .
//
// \note Currently only used by Foam::dynamicCode.
void inplaceExpand
(
std::string& s,
......@@ -133,17 +135,17 @@ namespace stringOps
//- and (optionally) environment variables.
//
// Expansion includes:
// -# dictionary variables and (optionally) environment variables
// -# Dictionary variables and (optionally) environment variables
// - \c $VAR
// - \c ${VAR}
// - \c ${VAR:-defValue}
// - \c ${VAR:+altValue}
// -# mathematical evaluation using stringOps::evaluate
// -# Mathematical evaluation using stringOps::evaluate
// - \c ${{EXPR}}
// -# current directory
// -# Current directory
// - leading "./"
// : the current directory - Foam::cwd()
// -# leading tag expansion for commonly used directories
// -# Leading tag expansion for commonly used directories
// - <b> \<etc\>/ </b>
// : user/group/other OpenFOAM etc directory
// - <b> \<etc:</b><em>[ugoa]+</em>)<b>\>/ </b>
......@@ -154,24 +156,21 @@ namespace stringOps
// : The \c $FOAM_CASE/constant directory
// - <b> \<system\>/ </b>
// : The \c $FOAM_CASE/system directory
// -# tilde expansion
// -# Tilde expansion
// - leading "~/" : home directory
// - leading "~user" : home directory for specified user
//
// Default and alternative values as per the POSIX shell:
// \code
// 1. ${parameter:-defValue}
// 2. ${parameter:+altValue}
// \endcode
// -# If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
// -# If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
// -# Default and alternative values as per the POSIX shell:
// - \c ${parameter:-defValue}
// If parameter is unset or null, the \c defValue is substituted.
// Otherwise, the value of parameter is substituted.
// - \c ${parameter:+altValue}
// If parameter is unset or null, nothing is substituted.
// Otherwise the \c altValue is substituted.
// .
//
// General behaviour:
// - Malformed entries (eg, brace mismatch, sigil followed by bad chars)
// are left as is.
// - Malformed entries (eg, brace mismatch, sigil followed by unknown
// characters) are left as is.
// - Supports recursive variable expansions.
// For example, "${var${num}}" and "${{100 + ${var}}}"
//
......@@ -186,7 +185,14 @@ namespace stringOps
//
// \sa Foam::findEtcEntry(), Foam::findEtcEntries(), stringOps::evaluate()
//
// \note this function has too many parameters and should generally
// \par Expansion behaviour
// - alternatives = True
// - environment = Given by parameter
// - allow empty = Given by parameter
// - subDict = Given by parameter (default: False)
// .
//
// \note This function has too many parameters and should generally
// be avoided in user coding.
void inplaceExpand
(
......@@ -217,7 +223,16 @@ namespace stringOps
// Empty expansions are allowed.
// Serialization of subDict entries is permitted.
//
// \sa stringOps::inplaceExpand(std::string&, const dictionary&, bool, bool, bool, char)
// \sa
// stringOps::inplaceExpand
// (std::string&, const dictionary&, bool, bool, bool, char)
//
// \par Expansion behaviour
// - alternatives = True
// - environment = True
// - allow empty = True
// - subDict = True
// .
void inplaceExpand
(
std::string& s,
......@@ -242,9 +257,17 @@ namespace stringOps
//- variables
//
// The expansion behaviour is identical to
// stringOps::inplaceExpand(std::string&, const dictionary&, bool, bool, bool, char)
// stringOps::inplaceExpand
// (std::string&, const dictionary&, bool, bool, bool, char)
// except that there is no dictionary and the environment variables
// are always enabled.
//
// \par Expansion behaviour
// - alternatives = True
// - environment = True
// - allow empty = Given by parameter (default: False)
// - subDict = Not applicable
// .
void inplaceExpand
(
std::string& s,
......
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