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-2013 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  (
161  "entry::New(const dictionary& parentDict, Istream&)",
162  is
163  )
164  << "Attempt to use undefined variable " << varName
165  << " as keyword"
166  << exit(FatalIOError);
167  return false;
168  }
169  }
170  else
171  {
172  parentDict.substituteScopedKeyword(keyword);
173  }
174 
175  return true;
176  }
177  else if
178  (
180  && keyword == "include"
181  ) // ... For backward compatibility
182  {
183  return functionEntries::includeEntry::execute(parentDict, is);
184  }
185  else // ... Data entries
186  {
187  token nextToken(is);
188  is.putBack(nextToken);
189 
190  // Deal with duplicate entries
191  bool mergeEntry = false;
192 
193  // See (using exact match) if entry already present
194  entry* existingPtr = parentDict.lookupEntryPtr
195  (
196  keyword,
197  false,
198  false
199  );
200 
201  if (existingPtr)
202  {
204  {
205  mergeEntry = true;
206  }
208  {
209  // clear dictionary so merge acts like overwrite
210  if (existingPtr->isDict())
211  {
212  existingPtr->dict().clear();
213  }
214  mergeEntry = true;
215  }
217  {
218  // read and discard the entry
219  if (nextToken == token::BEGIN_BLOCK)
220  {
221  dictionaryEntry dummy(keyword, parentDict, is);
222  }
223  else
224  {
225  primitiveEntry dummy(keyword, parentDict, is);
226  }
227  return true;
228  }
230  {
232  (
233  "entry::New(const dictionary& parentDict, Istream&)",
234  is
235  )
236  << "ERROR! duplicate entry: " << keyword
237  << exit(FatalIOError);
238 
239  return false;
240  }
241  }
242 
243  if (nextToken == token::BEGIN_BLOCK)
244  {
245  return parentDict.add
246  (
247  new dictionaryEntry(keyword, parentDict, is),
248  mergeEntry
249  );
250  }
251  else
252  {
253  return parentDict.add
254  (
255  new primitiveEntry(keyword, parentDict, is),
256  mergeEntry
257  );
258  }
259  }
260  }
261 }
262 
263 
265 {
266  is.fatalCheck("entry::New(Istream&)");
267 
269 
270  // Get the next keyword and if invalid return false
271  if (!getKeyword(keyword, is))
272  {
273  return autoPtr<entry>(NULL);
274  }
275  else // Keyword starts entry ...
276  {
277  token nextToken(is);
278  is.putBack(nextToken);
279 
280  if (nextToken == token::BEGIN_BLOCK)
281  {
282  return autoPtr<entry>
283  (
284  new dictionaryEntry(keyword, dictionary::null, is)
285  );
286  }
287  else
288  {
289  return autoPtr<entry>
290  (
291  new primitiveEntry(keyword, is)
292  );
293  }
294  }
295 }
296 
297 
298 // * * * * * * * * * * * * * Ostream operator * * * * * * * * * * * * * * * //
299 
301 {
302  e.write(os);
303  return os;
304 }
305 
306 
307 // ************************************************************************* //
static bool New(dictionary &parentDict, Istream &)
Construct from Istream and insert into dictionary.
Definition: entryIO.C:91
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:153
static bool overwrite()
Return true if the inputMode is overwrite.
static bool execute(dictionary &parentDict, Istream &)
Execute the functionEntry in a sub-dict context.
Definition: includeEntry.C:120
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 bool protect()
Return true if the inputMode is protect.
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
static bool merge()
Return true if the inputMode is merge.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
const entry * lookupScopedEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:463
bool substituteScopedKeyword(const word &keyword)
Substitute the given scoped keyword prepended by &#39;$&#39; with the.
Definition: dictionary.C:583
A class for handling words, derived from string.
Definition: word.H:59
static bool execute(const word &functionName, dictionary &parentDict, Istream &)
Execute the functionEntry in a sub-dict context.
Definition: functionEntry.C:51
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
Ostream & operator<<(Ostream &, const edgeMesh &)
Definition: edgeMeshIO.C:133
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:86
A class for handling keywords in dictionaries.
Definition: keyType.H:56
const keyType & keyword() const
Return keyword.
Definition: entry.H:120
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:345
static const dictionary null
Null dictionary.
Definition: dictionary.H:193
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
const double e
Elementary charge.
Definition: doubleFloat.H:78
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
IOerror FatalIOError
void putBack(const token &)
Put back token.
Definition: Istream.C:30
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:107
A token holds items read from Istream.
Definition: token.H:67
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:739
static bool error()
Return true if the inputMode is error.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:65
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
static int disableFunctionEntries
Definition: entry.H:83
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
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.
void clear()
Clear the dictionary.
Definition: dictionary.C:1062
virtual void write(Ostream &) const =0
Write.
#define FatalIOErrorIn(functionName, ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:325
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117