codeBlockEntry.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "codeBlockEntry.H"
27 #include "endCodeBlockEntry.H"
28 #include "codeBlockStreamEntry.H"
29 #include "codeBlockDictEntry.H"
30 #include "codeStream.H"
31 #include "codeDict.H"
32 #include "streamEntry.H"
33 #include "calcEntry.H"
34 #include "codeIncludeEntry.H"
35 #include "negEntry.H"
36 #include "OTstream.H"
37 #include "ITstream.H"
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44 namespace functionEntries
45 {
48 }
49 }
50 
51 const Foam::word Foam::functionEntries::codeBlockEntry::codeOptions
52 (
53  "codeBlockOptions"
54 );
55 
56 const Foam::wordList Foam::functionEntries::codeBlockEntry::compileFiles
57 {
58  "codeBlockTemplate.C"
59 };
60 
61 
62 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
63 
65 (
66  const label lineNumber,
67  const dictionary& parentDict,
68  Istream& is
69 )
70 :
71  functionEntry(typeName, lineNumber, parentDict),
72  codeBlockName_(word::null),
73  lib_(nullptr)
74 {}
75 
76 
77 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
78 
80 (
81  dictionary& contextDict,
82  Istream& is
83 )
84 {
85  if (debug)
86  {
87  Info<< "Compiling code within " << typeName << " starting at line "
88  << is.lineNumber() << " in file " << contextDict.name() << endl;
89  }
90 
91  // Construct codeDict for codeStream with the parent dictionary provided for
92  // string expansion and variable substitution and the same name as the
93  // parent for consistent error messaging
94  dictionary codeDict(typeName, contextDict);
95  string codeString;
96 
97  List<fileName> includeFileNames;
98 
99  // Disable functionEntry expansion
101 
102  // Read the dictionary up to #endCodeBlock
103 
104  // Dict stream including the code retrieval entries
105  OTstream dictCodeStream(contextDict.name());
106 
107  // Dict stream without the code retrieval entries
108  // used to provide entries for the code to lookup
109  OTstream dictStream(contextDict.name());
110 
111  label codeIndex = 0;
112 
113  token t;
114  while (!is.eof() && !is.read(t).bad() && t.good())
115  {
116  if (t.isFunctionName())
117  {
119  {
120  break;
121  }
122  else if (t.functionNameToken() == codeStream::typeName)
123  {
124  // Accumulate the #codeStream code strings
125  // into a single code block
126  codeString +=
127  codeStream::codeString(codeIndex, contextDict, is);
128 
129  // Replace the #codeStream with a #codeBlockStream followed by
130  // the pointer to this codeBlockEntry and the index of
131  // #codeStream
132  dictCodeStream
134  << reinterpret_cast<uint64_t>(this) << token::SPACE
135  << codeIndex++ << endl;
136  }
137  else if (t.functionNameToken() == codeDict::typeName)
138  {
139  // Accumulate the #codeDict code strings
140  // into a single code block
141  codeString +=
142  codeDict::codeString(codeIndex, contextDict, is);
143 
144  // Replace the #codeDict with a #codeBlockDict followed by the
145  // pointer to this codeBlockEntry and the index of #codeDict
146  dictCodeStream
148  << reinterpret_cast<uint64_t>(this) << token::SPACE
149  << codeIndex++ << endl;
150  }
152  {
153  // Accumulate the #stream code strings into a single code block
154  codeString +=
155  streamEntry::codeString(codeIndex, codeDict, is);
156 
157  // Replace the #stream with a #codeBlockStream followed by
158  // the pointer to this codeBlockEntry and the index of #stream
159  dictCodeStream
161  << reinterpret_cast<uint64_t>(this) << token::SPACE
162  << codeIndex++ << endl;
163  }
164  else if (t.functionNameToken() == calcEntry::typeName)
165  {
166  // Accumulate the #calc code strings into a single code block
167  codeString +=
168  calcEntry::codeString(codeIndex, codeDict, is);
169 
170  // Replace the #calc with a #codeBlockStream followed by
171  // the pointer to this codeBlockEntry and the index of #calc
172  dictCodeStream
174  << reinterpret_cast<uint64_t>(this) << token::SPACE
175  << codeIndex++ << endl;
176  }
178  {
179  // Add any optional codeInclude entry to codeDict
180  includeFileNames.append
181  (
183  );
184  }
185  else if (t.functionNameToken() == negEntry::typeName)
186  {
187  dictCodeStream.append(t);
188  }
189  else
190  {
192  << t.functionNameToken() << " not supported within "
193  << codeBlockEntry::typeName << "..."
195  << exit(FatalIOError);
196  }
197  }
198  else
199  {
200  dictCodeStream.append(t);
201  dictStream.append(t);
202  }
203  }
204 
205  // Read the dictionary without expanding functionEntries
206  // to provide entries for the code to lookup
207  contextDict.read(ITstream(dictStream.name(), dictStream)());
208 
209  // Add the code entry to the codeDict
210  codeDict.add(primitiveEntry("code", codeString, 0));
211 
212  codeIncludeEntry::addCodeInclude(includeFileNames, contextDict, codeDict);
213 
214  // Compile the codeBlock library and cache the pointer
215  lib_ = codeStream::compile
216  (
217  typeName,
218  contextDict,
219  codeDict,
220  codeOptions,
221  compileFiles,
222  codeBlockName_
223  );
224 
225  // Re-enable functionEntry expansion
227 
228  // Re-read the dictionary expanding all functionEntries
229  // including #codeBlockStream and #codeBlockDict using the functions in lib_
230  contextDict.read(ITstream(dictCodeStream.name(), dictCodeStream)());
231 
232  return true;
233 }
234 
235 
236 // ************************************************************************* //
Macros for easy insertion into run-time selection tables.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
label lineNumber() const
Return current stream line number.
Definition: IOstream.H:450
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:351
Input token stream.
Definition: ITstream.H:56
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
virtual Istream & read(token &)=0
Return next token from stream.
bool eof() const
Return true if end of input seen.
Definition: Istream.H:107
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
Output token stream.
Definition: OTstream.H:56
virtual const fileName & name() const
Return the name of the stream.
Definition: OTstream.H:86
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:111
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
bool read(Istream &, const bool keepHeader=false)
Read dictionary from Istream, optionally keeping the header.
Definition: dictionaryIO.C:105
static int disableFunctionEntries
Definition: entry.H:102
Part of the #codeBlock...#codeBlock clause.
virtual bool execute(dictionary &contextDict, Istream &is)
Expand the functionEntry into the contextDict.
codeBlockEntry(const label lineNumber, const dictionary &parentDict, Istream &is)
Construct from line number, dictionary and Istream.
Compiles and executes C++ OpenFOAM code string expressions.
Definition: codeDict.H:131
Specify an include file or list of files for #calc within #codeBlock.
const List< fileName > & fileNames() const
Return the include file names.
static void addCodeInclude(const List< fileName > &fileNames, const dictionary &contextDict, dictionary &codeDict)
Add the codeInclude entry to codeDict.
static string codeString(const label index, const dictionary &codeDict, Istream &, const string &startString=string::null, const string &endString=string::null)
Return the code string.
Definition: streamEntry.C:57
A functionEntry causes entries to be added/manipulated on the specified dictionary given an input str...
Definition: functionEntry.H:66
A class for handling keywords in dictionaries.
Definition: keyType.H:69
A keyword and a list of tokens is a 'primitiveEntry'. An primitiveEntry can be read,...
A token holds items read from Istream.
Definition: token.H:74
const functionName & functionNameToken() const
Definition: tokenI.H:365
bool isFunctionName() const
Definition: tokenI.H:360
bool good() const
Definition: tokenI.H:309
label lineNumber() const
Definition: tokenI.H:847
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
defineFunctionTypeNameAndDebug(includeFvConstraintEntry, 0)
addToRunTimeSelectionTable(functionEntry, includeFvConstraintEntry, dictionary)
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
messageStream Info
IOerror FatalIOError