functionEntry.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) 2011-2024 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 "functionEntry.H"
27 #include "IOstreams.H"
28 #include "ISstream.H"
29 #include "Pstream.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
36  (
38  execute,
39  dictionaryIstream
40  );
41 
43  (
45  execute,
46  primitiveEntryIstream
47  );
48 }
49 
50 
51 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
52 
53 Foam::token Foam::functionEntry::readLine(Istream& is)
54 {
55  if (isA<Pstream>(is))
56  {
57  return token(is);
58  }
59  else
60  {
61  const Tuple2<string, label> argStringLine(readFuncNameArgs(is));
62  return token(word(argStringLine.first()), argStringLine.second());
63  }
64 }
65 
66 
67 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
68 
71 {
72  string fNameArgs;
73 
74  const label lineNumber0 = is.lineNumber();
75 
76  // Read the function name with arguments if on the same line
77  const token fName(is);
78 
79  if (fName.isWord())
80  {
81  const word& fNameWord = fName.wordToken();
82 
83  if (fNameWord.find(token::BEGIN_LIST) != string::npos)
84  {
85  // If the function name includes a '(' push it back onto the stream
86  // and re-read as a list
87 
88  ISstream& iss = dynamic_cast<ISstream&>(is);
89 
90  for
91  (
92  string::const_reverse_iterator rit = fNameWord.rbegin();
93  rit != fNameWord.rend();
94  ++rit
95  )
96  {
97  iss.putback(*rit);
98  }
99 
100  iss.readList(fNameArgs);
101  }
102  else
103  {
104  // Read the next token to check for '('
105  // in case the optional arguments start on the next line
106 
107  const token nextToken(is);
108 
109  if
110  (
111  nextToken.isPunctuation()
112  && nextToken.pToken() == token::BEGIN_LIST
113  )
114  {
115  ISstream& iss = dynamic_cast<ISstream&>(is);
116 
118 
119  const label fNameLineNumber = is.lineNumber();
120 
121  iss.readList(fNameArgs);
122 
123  // Reinstate the \n between fName and the '('
124  if (fNameLineNumber != lineNumber0)
125  {
126  fNameArgs =
127  fNameWord
128  + string(fNameLineNumber - lineNumber0, '\n')
129  + fNameArgs;
130  }
131  else
132  {
133  fNameArgs = fNameWord + fNameArgs;
134  }
135  }
136  else
137  {
138  is.putBack(nextToken);
139  fNameArgs = fNameWord;
140  }
141  }
142  }
143  else if (fName.isString())
144  {
145  // If the function name is a string delimit with '"'s
146  fNameArgs = '"' + fName.stringToken() + '"';
147  }
148  else
149  {
150  // For any other kind of string return for error reporting
151  fNameArgs = fName.anyStringToken();
152  }
153 
154  return Tuple2<string, label>(fNameArgs, lineNumber0);
155 }
156 
157 
159 (
160  dictionary& parentDict,
161  const string& str
162 )
163 {
164  parentDict.read(IStringStream(str)());
165  return true;
166 }
167 
168 
170 (
171  const dictionary& parentDict,
172  primitiveEntry& thisEntry,
173  const string& str
174 )
175 {
176  thisEntry.read(parentDict, IStringStream(str)());
177  return true;
178 }
179 
180 
181 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
182 
184 (
185  const word& key,
186  const dictionary& dict,
187  Istream& is
188 )
189 :
190  primitiveEntry(key, readLine(is))
191 {}
192 
193 
194 // * * * * * * * * * * * * Member Function Selectors * * * * * * * * * * * * //
195 
197 (
198  const word& functionName,
199  dictionary& parentDict,
200  Istream& is
201 )
202 {
203  is.fatalCheck
204  (
205  "functionEntry::execute"
206  "(const word& functionName, dictionary& parentDict, Istream&)"
207  );
208 
209  if (!executedictionaryIstreamMemberFunctionTablePtr_)
210  {
211  cerr<< "functionEntry::execute"
212  << "(const word&, dictionary&, Istream&)"
213  << " not yet initialised, function = "
214  << functionName.c_str() << std::endl;
215 
216  // Return true to keep reading
217  return true;
218  }
219 
220  executedictionaryIstreamMemberFunctionTable::iterator mfIter =
221  executedictionaryIstreamMemberFunctionTablePtr_->find(functionName);
222 
223  if (mfIter == executedictionaryIstreamMemberFunctionTablePtr_->end())
224  {
226  << "Unknown functionEntry '" << functionName
227  << "' in " << is.name() << " at line " << is.lineNumber()
228  << nl << nl
229  << "Valid functionEntries are :" << endl
230  << executedictionaryIstreamMemberFunctionTablePtr_->toc()
231  << exit(FatalError);
232  }
233 
234  return mfIter()(parentDict, is);
235 }
236 
237 
239 (
240  const word& functionName,
241  const dictionary& parentDict,
243  Istream& is
244 )
245 {
246  is.fatalCheck
247  (
248  "functionEntry::execute"
249  "(const word&, const dictionary&, primitiveEntry&, Istream&)"
250  );
251 
252  if (!executeprimitiveEntryIstreamMemberFunctionTablePtr_)
253  {
254  cerr<< "functionEntry::execute"
255  << "(const word&, const dictionary&, primitiveEntry&, Istream&)"
256  << " not yet initialised, function = "
257  << functionName.c_str() << std::endl;
258 
259  // return true to keep reading anyhow
260  return true;
261  }
262 
263  executeprimitiveEntryIstreamMemberFunctionTable::iterator mfIter =
264  executeprimitiveEntryIstreamMemberFunctionTablePtr_->find(functionName);
265 
266  if (mfIter == executeprimitiveEntryIstreamMemberFunctionTablePtr_->end())
267  {
269  << "Unknown functionEntry '" << functionName
270  << "' in " << is.name() << " at line " << is.lineNumber()
271  << nl << nl
272  << "Valid functionEntries are :" << endl
273  << executeprimitiveEntryIstreamMemberFunctionTablePtr_->toc()
274  << exit(FatalError);
275  }
276 
277  return mfIter()(parentDict, entry, is);
278 }
279 
280 
282 {
283  writeKeyword(os, keyword());
284 
285  if (size() == 1)
286  {
287  os << operator[](0) << endl;
288  }
289  else
290  {
292  << "Incorrect number of tokens in functionEntry, "
293  "should be a single word."
294  << exit(FatalIOError);
295  }
296 }
297 
298 
299 // ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
label lineNumber() const
Return current stream line number.
Definition: IOstream.H:450
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:105
Generic input stream.
Definition: ISstream.H:55
Istream & readList(string &)
Read a '(...)' delimited set of characters into a string.
Definition: ISstream.C:770
ISstream & putback(const char &)
Low-level putback character function.
Definition: ISstreamI.H:78
Input from memory buffer stream.
Definition: IStringStream.H:52
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
void putBack(const token &)
Put back token.
Definition: Istream.C:30
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:66
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:111
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:68
A functionEntry causes entries to be added/manipulated on the specified dictionary given an input str...
Definition: functionEntry.H:66
virtual void write(Ostream &) const
Write.
static bool insert(dictionary &parentDict, const string &)
Insert the given string in a sub-dict context.
static bool execute(const word &functionName, dictionary &parentDict, Istream &)
Execute the functionEntry in a sub-dict context.
static Tuple2< string, label > readFuncNameArgs(Istream &is)
Read the function name and optional argument list.
Definition: functionEntry.C:70
functionEntry(const word &, const dictionary &, Istream &)
Construct from keyword, parent dictionary and Istream.
A functionName is a word starting with '#'.
Definition: functionName.H:60
A keyword and a list of tokens is a 'primitiveEntry'. An primitiveEntry can be read,...
virtual bool read(const dictionary &, Istream &)
Read tokens from the given stream.
A class for handling character strings derived from std::string.
Definition: string.H:79
A token holds items read from Istream.
Definition: token.H:73
bool isPunctuation() const
Definition: tokenI.H:280
@ BEGIN_LIST
Definition: token.H:109
const string & stringToken() const
Definition: tokenI.H:357
punctuationToken pToken() const
Definition: tokenI.H:285
const string & anyStringToken() const
Definition: tokenI.H:400
bool isString() const
Definition: tokenI.H:352
bool isWord() const
Definition: tokenI.H:298
const word & wordToken() const
Definition: tokenI.H:303
A class for handling words, derived from string.
Definition: word.H:62
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
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:258
IOerror FatalIOError
error FatalError
Ostream & writeKeyword(Foam::Ostream &os, const keyType &kw)
Write the keyword to the Ostream with the current level of indentation.
Definition: keyType.C:155
defineMemberFunctionSelectionTable(edgeMesh, write, fileExtension)
static const char nl
Definition: Ostream.H:267
dictionary dict