entryIO.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 | Copyright (C) 2011-2015 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 "primitiveEntry.H"
27 #include "dictionaryEntry.H"
28 #include "functionEntry.H"
29 #include "includeEntry.H"
30 #include "inputModeEntry.H"
31 #include "stringOps.H"
32 
33 #include "IOstreams.H"
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
38 {
39  token keywordToken;
40 
41  // Read the next valid token discarding spurious ';'s
42  do
43  {
44  if
45  (
46  is.read(keywordToken).bad()
47  || is.eof()
48  || !keywordToken.good()
49  )
50  {
51  return false;
52  }
53  }
54  while (keywordToken == token::END_STATEMENT);
55 
56  // If the token is a valid keyword set 'keyword' return true...
57  if (keywordToken.isWord())
58  {
59  keyword = keywordToken.wordToken();
60  return true;
61  }
62  else if (keywordToken.isString())
63  {
64  // Enable wildcards
65  keyword = keywordToken.stringToken();
66  return true;
67  }
68  // If it is the end of the dictionary or file return false...
69  else if (keywordToken == token::END_BLOCK || is.eof())
70  {
71  return false;
72  }
73  // Otherwise the token is invalid
74  else
75  {
76  cerr<< "--> FOAM Warning : " << std::endl
77  << " From function "
78  << "entry::getKeyword(keyType&, Istream&)" << std::endl
79  << " in file " << __FILE__
80  << " at line " << __LINE__ << std::endl
81  << " Reading " << is.name().c_str() << std::endl
82  << " found " << keywordToken << std::endl
83  << " expected either " << token::END_BLOCK << " or EOF"
84  << std::endl;
85 
86  return false;
87  }
88 }
89 
90 
91 bool Foam::entry::New(dictionary& parentDict, Istream& is)
92 {
93  is.fatalCheck("entry::New(const dictionary& parentDict, Istream&)");
94 
96 
97  // Get the next keyword and if invalid return false
98  if (!getKeyword(keyword, is))
99  {
100  return false;
101  }
102  else // Keyword starts entry ...
103  {
104  if
105  (
107  && keyword[0] == '#'
108  ) // ... Function entry
109  {
110  word functionName = keyword(1, keyword.size()-1);
111  return functionEntry::execute(functionName, parentDict, is);
112  }
113  else if
114  (
116  && keyword[0] == '$'
117  ) // ... Substitution entry
118  {
119  token nextToken(is);
120  is.putBack(nextToken);
121 
122  if (keyword.size() > 2 && keyword[1] == token::BEGIN_BLOCK)
123  {
124  // Recursive substitution mode. Replace between {} with
125  // expansion and then let standard variable expansion deal
126  // with rest.
127  string s(keyword(2, keyword.size()-3));
128  // Substitute dictionary and environment variables. Do not allow
129  // empty substitutions.
130  stringOps::inplaceExpand(s, parentDict, true, false);
131  keyword.std::string::replace(1, keyword.size()-1, s);
132  }
133 
134  if (nextToken == token::BEGIN_BLOCK)
135  {
136  word varName = keyword(1, keyword.size()-1);
137 
138  // lookup the variable name in the given dictionary
139  const entry* ePtr = parentDict.lookupScopedEntryPtr
140  (
141  varName,
142  true,
143  true
144  );
145 
146  if (ePtr)
147  {
148  // Read as primitiveEntry
149  const keyType newKeyword(ePtr->stream());
150 
151  return parentDict.add
152  (
153  new dictionaryEntry(newKeyword, parentDict, is),
154  false
155  );
156  }
157  else
158  {
160  << "Attempt to use undefined variable " << varName
161  << " as keyword"
162  << exit(FatalIOError);
163  return false;
164  }
165  }
166  else
167  {
168  parentDict.substituteScopedKeyword(keyword);
169  }
170 
171  return true;
172  }
173  else if
174  (
176  && keyword == "include"
177  ) // ... For backward compatibility
178  {
179  return functionEntries::includeEntry::execute(parentDict, is);
180  }
181  else // ... Data entries
182  {
183  token nextToken(is);
184  is.putBack(nextToken);
185 
186  // Deal with duplicate entries
187  bool mergeEntry = false;
188 
189  // See (using exact match) if entry already present
190  entry* existingPtr = parentDict.lookupEntryPtr
191  (
192  keyword,
193  false,
194  false
195  );
196 
197  if (existingPtr)
198  {
200  {
201  mergeEntry = true;
202  }
204  {
205  // clear dictionary so merge acts like overwrite
206  if (existingPtr->isDict())
207  {
208  existingPtr->dict().clear();
209  }
210  mergeEntry = true;
211  }
213  {
214  // read and discard the entry
215  if (nextToken == token::BEGIN_BLOCK)
216  {
217  dictionaryEntry dummy(keyword, parentDict, is);
218  }
219  else
220  {
221  primitiveEntry dummy(keyword, parentDict, is);
222  }
223  return true;
224  }
226  {
228  << "ERROR! duplicate entry: " << keyword
229  << exit(FatalIOError);
230 
231  return false;
232  }
233  }
234 
235  if (nextToken == token::BEGIN_BLOCK)
236  {
237  return parentDict.add
238  (
239  new dictionaryEntry(keyword, parentDict, is),
240  mergeEntry
241  );
242  }
243  else
244  {
245  return parentDict.add
246  (
247  new primitiveEntry(keyword, parentDict, is),
248  mergeEntry
249  );
250  }
251  }
252  }
253 }
254 
255 
257 {
258  is.fatalCheck("entry::New(Istream&)");
259 
261 
262  // Get the next keyword and if invalid return false
263  if (!getKeyword(keyword, is))
264  {
265  return autoPtr<entry>(NULL);
266  }
267  else // Keyword starts entry ...
268  {
269  token nextToken(is);
270  is.putBack(nextToken);
271 
272  if (nextToken == token::BEGIN_BLOCK)
273  {
274  return autoPtr<entry>
275  (
276  new dictionaryEntry(keyword, dictionary::null, is)
277  );
278  }
279  else
280  {
281  return autoPtr<entry>
282  (
283  new primitiveEntry(keyword, is)
284  );
285  }
286  }
287 }
288 
289 
290 // * * * * * * * * * * * * * Ostream operator * * * * * * * * * * * * * * * //
291 
293 {
294  e.write(os);
295  return os;
296 }
297 
298 
299 // ************************************************************************* //
A class for handling keywords in dictionaries.
Definition: keyType.H:64
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const double e
Elementary charge.
Definition: doubleFloat.H:78
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
virtual void write(Ostream &) const =0
Write.
static const dictionary null
Null dictionary.
Definition: dictionary.H:193
A token holds items read from Istream.
Definition: token.H:69
static bool New(dictionary &parentDict, Istream &)
Construct from Istream and insert into dictionary.
Definition: entryIO.C:91
void putBack(const token &)
Put back token.
Definition: Istream.C:30
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:345
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
static bool execute(dictionary &parentDict, Istream &)
Execute the functionEntry in a sub-dict context.
Definition: includeEntry.C:120
A keyword and a list of tokens is a &#39;dictionaryEntry&#39;.
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:737
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
A keyword and a list of tokens is a &#39;primitiveEntry&#39;. An primitiveEntry can be read, written and printed, and the types and values of its tokens analysed.
static bool protect()
Return true if the inputMode is protect.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().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))
static int disableFunctionEntries
Definition: entry.H:83
const entry * lookupScopedEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:462
A class for handling words, derived from string.
Definition: word.H:59
const keyType & keyword() const
Return keyword.
Definition: entry.H:120
static bool execute(const word &functionName, dictionary &parentDict, Istream &)
Execute the functionEntry in a sub-dict context.
Definition: functionEntry.C:51
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
static bool merge()
Return true if the inputMode is merge.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:331
Ostream & operator<<(Ostream &, const ensightPart &)
string & inplaceExpand(string &, const HashTable< string, word, string::hash > &mapping, const char sigil= '$')
Inplace expand occurences of variables according to the mapping.
Definition: stringOps.C:87
bool substituteScopedKeyword(const word &keyword)
Substitute the given scoped keyword prepended by &#39;$&#39; with the.
Definition: dictionary.C:578
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:53
static bool overwrite()
Return true if the inputMode is overwrite.
void clear()
Clear the dictionary.
Definition: dictionary.C:1058
static bool error()
Return true if the inputMode is error.
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:105
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:153
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:65
IOerror FatalIOError