expressionEntry.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Original code Copyright (C) 2014-2018 Bernhard Gschaider
9  Copyright (C) 2019-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "expressionEntry.H"
30 #include "stringOps.H"
31 #include "runTimeSelectionTables.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 namespace exprTools
39 {
40 
43 
44 // Various types can be used directly without any changes
45 
47 (
50  empty,
51  direct
52 );
53 
55 (
58  empty,
59  label
60 );
61 
63 (
66  empty,
67  scalar
68 );
69 
71 (
74  empty,
75  word
76 );
77 
78 } // End namespace exprTools
79 } // End namespace Foam
80 
81 
82 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
83 
84 namespace Foam
85 {
86 inline static const entry* getVariableOrDie
87 (
88  const word& name,
89  const dictionary& dict
90 )
91 {
93 
94  if (!eptr)
95  {
97  << "No dictionary entry " << name << nl
98  << exit(FatalIOError);
99  }
100 
101  if (eptr->isDict())
102  {
104  << "Found dictionary " << name << " instead of entry" << nl
105  << exit(FatalIOError);
106  }
107 
108  return eptr;
109 }
110 
111 } // End namespace Foam
112 
113 
114 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
115 
118 (
119  const word& name
120 )
121 {
122  auto* ctorPtr = emptyConstructorTable(name);
123 
124  if (!ctorPtr)
125  {
127  (
128  "expressionEntry",
129  name,
130  *emptyConstructorTablePtr_
131  ) << exit(FatalError);
132  }
133 
134  return autoPtr<expressionEntry>(ctorPtr());
135 }
136 
137 
138 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
139 
141 (
142  std::string& s,
143  const dictionary& dict
144 )
145 {
146  // This is much like stringOps::inplaceExpand
147  constexpr const char sigil = '$';
148 
149  // Step 1:
150  // Handle $[] special expansions first
151 
152  std::string::size_type varBeg = 0;
153 
154  while
155  (
156  (varBeg = s.find(sigil, varBeg)) != std::string::npos
157  && varBeg < s.size()-1
158  )
159  {
160  if (varBeg && s[varBeg-1] == '\\')
161  {
162  // Escaped character - pass through
163  ++varBeg;
164  continue;
165  }
166 
167  if (s[varBeg+1] == '[')
168  {
169  // An expression pattern with $[...]
170 
171  std::string::size_type varEnd = s.find(']', varBeg);
172  std::string::size_type delim = 1;
173 
174  if (varEnd == std::string::npos)
175  {
176  // Parsed '$[...' without closing ']' - error
178  << "No correct terminating ']' found in " << s << nl
179  << exit(FatalError);
180  break;
181  }
182 
183  // Look for embedded (type) cast
184  word castTo, varName;
185 
186  const auto lparen = varBeg+2;
187  if (lparen < s.size() && s[lparen] == '(')
188  {
189  const auto rparen = s.find(')', lparen);
190 
191  if (rparen > varEnd)
192  {
193  // Handles both "$[( ...]" and "$[( ...])" cases
194 
195  auto& err = FatalErrorInFunction;
196 
197  if (rparen == std::string::npos)
198  {
199  err << "No closing ')' found in ";
200  }
201  else
202  {
203  err << "Closing ')' found outside of";
204  }
205 
206  err << " substring "
207  << s.substr(varBeg, varEnd-varBeg) << nl
208  << exit(FatalError);
209  }
210 
211  castTo.assign(s.substr(lparen+1, rparen - lparen - 1));
212  varName.assign(s.substr(rparen+1, varEnd - rparen - 1));
213  }
214  else
215  {
216  varName.assign
217  (
218  s.substr(varBeg + 1 + delim, varEnd - varBeg - 2*delim)
219  );
220  }
221 
222  // Likely no spaces there, but for extra safety...
223  stringOps::inplaceTrim(varName);
224 
225  // Allow recursive plain expansion for the *variable* name.
226  // This means "$[(vector) var${index} ]" should work
227 
228  // Expand with env=true, empty=true, subDict=false
229  stringOps::inplaceExpand(varName, dict, true, true, false);
230 
231  // Length of original text to replace (incl. decorators)
232  const auto replaceLen = (varEnd - varBeg + 1);
233 
234  // Get primitiveEntry with env=false, subDict=false
235  const entry* eptr = getVariableOrDie(varName, dict);
236 
237  std::string varValue;
238 
239  if (castTo.empty())
240  {
241  // Serialized with spaces
242  ITstream& its = eptr->stream();
243 
244  if (its.size() == 1 && its[0].isStringType())
245  {
246  // Already a string-type (WORD, STRING, ...). Just copy.
247  varValue = its[0].stringToken();
248  }
249  else
250  {
251  varValue = its.toString();
252  }
253  }
254  else
255  {
256  varValue = expressionEntry::New(castTo)->toExpr(*eptr);
257  }
258 
259  s.std::string::replace(varBeg, replaceLen, varValue);
260  varBeg += varValue.size();
261  }
262  else
263  {
264  ++varBeg;
265  }
266  }
267 
268 
269  // Step 2:
270  // Handle all ${}, $var and ${{ ... }} expansions.
271  // - this is done second such that $[(vector) xyz] entries will have
272  // been properly expanded by this stage
273 
274  // Expand with env=true, empty=true, subDict=false
275  stringOps::inplaceExpand(s, dict, true, true, false);
276 }
277 
278 
281 (
282  const std::string& orig,
283  const dictionary& dict
284 )
285 {
286  // Copy without validation (use assign)
288  s.assign(orig);
289 
290  inplaceExpand(s, dict);
291 
292  return s;
293 }
294 
295 
296 // ************************************************************************* //
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::keyType::LITERAL_RECURSIVE
Definition: keyType.H:86
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::entry::stream
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::stringOps::inplaceTrim
void inplaceTrim(std::string &s)
Trim leading and trailing whitespace inplace.
Definition: stringOps.C:1067
Foam::exprTools::expressionEntry
Convert dictionary entry to a stringified expression.
Definition: expressionEntry.H:85
Foam::entry::isDict
virtual bool isDict() const noexcept
Return true if this entry is a dictionary.
Definition: entry.H:233
Foam::FatalIOError
IOerror FatalIOError
Foam::exprTools::expressionEntry::inplaceExpand
static void inplaceExpand(std::string &s, const dictionary &dict)
Inplace expand expression with dictionary variables/entries.
Definition: expressionEntry.C:141
Foam::exprTools::defineRunTimeSelectionTable
defineRunTimeSelectionTable(expressionEntry, empty)
Foam::stringOps::inplaceExpand
void inplaceExpand(std::string &s, const HashTable< string > &mapping, const char sigil='$')
Definition: stringOps.C:731
Foam::getVariableOrDie
static const entry * getVariableOrDie(const word &name, const dictionary &dict)
Definition: expressionEntry.C:87
expressionEntry.H
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:52
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
Foam::exprTools::expressionEntry::New
static autoPtr< expressionEntry > New(const word &name)
Return an entry to expression converter.
Definition: expressionEntry.C:118
Foam::exprTools::defineTypeName
defineTypeName(expressionEntry)
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
FatalErrorInLookup
#define FatalErrorInLookup(lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalError.
Definition: error.H:457
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::exprTools::expressionEntry::expand
static expressions::exprString expand(const std::string &str, const dictionary &dict)
Expand expression with dictionary entries.
Definition: expressionEntry.C:281
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::dictionary::findScoped
const entry * findScoped(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for a scoped entry (const access) with the given keyword.
Definition: dictionaryI.H:117
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::ITstream::toString
std::string toString() const
Definition: ITstream.C:320
Foam::exprTools::addNamedToRunTimeSelectionTable
addNamedToRunTimeSelectionTable(expressionEntry, expressionEntry, empty, direct)
runTimeSelectionTables.H
Macros to ease declaration of run-time selection tables.
Foam::expressions::exprString
Definition: exprString.H:60
Foam::expressions::exprString
A variant of Foam::string with expansion of dictionary variables into a comma-separated form.
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
stringOps.H