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 
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 
95  keyType keyword;
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  (
106  !disableFunctionEntries
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  (
115  !disableFunctionEntries
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  (
175  !disableFunctionEntries
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 
260  keyType keyword;
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 // ************************************************************************* //
Foam::functionEntry::execute
static bool execute(const word &functionName, dictionary &parentDict, Istream &)
Execute the functionEntry in a sub-dict context.
Definition: functionEntry.C:51
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:65
Foam::dictionaryEntry
A keyword and a list of tokens is a 'dictionaryEntry'.
Definition: dictionaryEntry.H:57
Foam::functionEntries::inputModeEntry::overwrite
static bool overwrite()
Return true if the inputMode is overwrite.
Definition: inputModeEntry.C:121
Foam::token::END_STATEMENT
@ END_STATEMENT
Definition: token.H:99
inputModeEntry.H
Foam::IOstream::fatalCheck
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:105
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Foam::primitiveEntry
A keyword and a list of tokens is a 'primitiveEntry'. An primitiveEntry can be read,...
Definition: primitiveEntry.H:62
primitiveEntry.H
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::entry::stream
virtual ITstream & stream() const =0
Return token stream if this entry is a primitive entry.
Foam::entry::keyword
const keyType & keyword() const
Return keyword.
Definition: entry.H:120
Foam::functionEntries::inputModeEntry::protect
static bool protect()
Return true if the inputMode is protect.
Definition: inputModeEntry.C:127
Foam::functionEntries::inputModeEntry::error
static bool error()
Return true if the inputMode is error.
Definition: inputModeEntry.C:132
Foam::IOstream::eof
bool eof() const
Return true if end of input seen.
Definition: IOstream.H:339
Foam::token::wordToken
const word & wordToken() const
Definition: tokenI.H:226
Foam::token::isString
bool isString() const
Definition: tokenI.H:244
Foam::functionEntries::includeEntry::execute
static bool execute(dictionary &parentDict, Istream &)
Execute the functionEntry in a sub-dict context.
Definition: includeEntry.C:120
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::token
A token holds items read from Istream.
Definition: token.H:67
functionEntry.H
Foam::token::good
bool good() const
Definition: tokenI.H:188
Foam::token::stringToken
const string & stringToken() const
Definition: tokenI.H:249
Foam::keyType
A class for handling keywords in dictionaries.
Definition: keyType.H:56
Foam::entry::isDict
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:153
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:57
Foam::operator<<
Ostream & operator<<(Ostream &, const edgeMesh &)
Definition: edgeMeshIO.C:130
Foam::dictionary::lookupScopedEntryPtr
const entry * lookupScopedEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:460
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Foam::token::isWord
bool isWord() const
Definition: tokenI.H:221
Foam::IOstream::bad
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:351
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::entry::dict
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
s
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))
dictionaryEntry.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::dictionary::substituteScopedKeyword
bool substituteScopedKeyword(const word &keyword)
Substitute the given scoped keyword prepended by '$' with the.
Definition: dictionary.C:576
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
Foam::dictionary::lookupEntryPtr
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:343
Foam::token::END_BLOCK
@ END_BLOCK
Definition: token.H:105
Foam::Istream::putBack
void putBack(const token &)
Put back token.
Definition: Istream.C:30
includeEntry.H
Foam::token::BEGIN_BLOCK
@ BEGIN_BLOCK
Definition: token.H:104
Foam::entry::New
static bool New(dictionary &parentDict, Istream &)
Construct from Istream and insert into dictionary.
Definition: entryIO.C:91
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:330
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:53
Foam::entry::getKeyword
static bool getKeyword(keyType &, Istream &)
Get the next valid keyword otherwise return false.
Definition: entryIO.C:37
stringOps.H
Foam::dictionary::clear
void clear()
Clear the dictionary.
Definition: dictionary.C:1050
Foam::stringOps::inplaceExpand
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
Foam::IOstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
Foam::dictionary::null
static const dictionary null
Null dictionary.
Definition: dictionary.H:193
Foam::dictionary::add
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:729
Foam::functionEntries::inputModeEntry::merge
static bool merge()
Return true if the inputMode is merge.
Definition: inputModeEntry.C:115
Foam::Istream::read
virtual Istream & read(token &)=0
Return next token from stream.