primitiveEntry.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "primitiveEntry.H"
30 #include "dictionary.H"
31 #include "OSspecific.H"
32 #include "stringOps.H"
33 
34 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
35 
36 // Find the type/position of the ":-" or ":+" alternative values
37 // Returns 0, '-', '+' corresponding to not-found or ':-' or ':+'
38 static inline int findParameterAlternative
39 (
40  const std::string& s,
42  std::string::size_type endPos = std::string::npos
43 )
44 {
45  while (pos != std::string::npos)
46  {
47  pos = s.find(':', pos);
48  if (pos != std::string::npos)
49  {
50  if (pos < endPos)
51  {
52  // in-range: check for '+' or '-' following the ':'
53  const int altType = s[pos+1];
54  if (altType == '+' || altType == '-')
55  {
56  return altType;
57  }
58 
59  ++pos; // unknown/unsupported - continue at next position
60  }
61  else
62  {
63  // out-of-range: abort
64  pos = std::string::npos;
65  }
66  }
67  }
68 
69  return 0;
70 }
71 
72 
73 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
74 
75 bool Foam::primitiveEntry::expandVariable
76 (
77  const string& varName,
78  const dictionary& dict
79 )
80 {
81  int altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
82  word expanded;
83  string altValue;
84 
85  if (varName.size() > 1 && varName[0] == token::BEGIN_BLOCK)
86  {
87  // Replace content between {} with string expansion and
88  // handle ${parameter:-word} or ${parameter:+word}
89 
90  // Copy into a word without stripping
91  expanded.assign(varName, 1, varName.size()-2);
92 
93  // Substitute dictionary and environment variables.
94  // - Allow environment.
95  // - No empty substitutions.
96  // - No sub-dictionary lookups
97 
98  stringOps::inplaceExpand(expanded, dict, true, false, false);
99 
100  // Position of ":-" or ":+" alternative values
101  std::string::size_type altPos = 0;
102 
103  // Check for parameter:-word or parameter:+word
104  altType = findParameterAlternative(expanded, altPos);
105 
106  if (altType)
107  {
108  altValue = expanded.substr(altPos + 2);
109  expanded.erase(altPos);
110  }
111 
112  // Catch really bad expansions and let them die soon after.
113  // Eg, ${:-other} should not be allowed.
114  if (expanded.empty())
115  {
116  altType = 0;
117  altValue.clear();
118  }
119 
120  // Fallthrough for further processing
121  }
122 
123 
124  // Lookup variable name in the given dictionary WITHOUT pattern matching.
125  // Having a pattern match means that in this example:
126  // {
127  // internalField XXX;
128  // boundaryField { ".*" {YYY;} movingWall {value $internalField;}
129  // }
130  // The $internalField would be matched by the ".*" !!!
131 
132  // Recursive, non-patterns
133 
134  const word& lookupName = (expanded.empty() ? varName : expanded);
135 
136  const entry* eptr =
138 
139  if (!eptr)
140  {
141  // Not found - revert to environment variable
142  // and parse into a series of tokens.
143 
144  // We wish to fail if the environment variable returns
145  // an empty string and there is no alternative given.
146  //
147  // Always allow empty strings as alternative parameters,
148  // since the user provided them for a reason.
149 
150  string str(Foam::getEnv(lookupName));
151 
152  if (str.empty() ? (altType == '-') : (altType == '+'))
153  {
154  // Not found or empty: use ":-" alternative value
155  // Found and not empty: use ":+" alternative value
156  str = std::move(altValue);
157  }
158  else if (str.empty())
159  {
161  << "Illegal dictionary entry or environment variable name "
162  << lookupName << nl
163  << "Known dictionary entries: " << dict.toc() << nl
164  << exit(FatalIOError);
165 
166  return false;
167  }
168 
169  // Parse string into a series of tokens
170 
172 
173  ITstream::append(std::move(toks), true); // Lazy resizing
174  }
175  else if (eptr->isDict())
176  {
177  // Found dictionary entry
178 
179  tokenList toks(eptr->dict().tokens());
180 
181  if (toks.empty() ? (altType == '-') : (altType == '+'))
182  {
183  // Not found or empty: use ":-" alternative value
184  // Found and not empty: use ":+" alternative value
185 
186  toks = ITstream::parse(altValue, IOstream::ASCII);
187  }
188 
189  ITstream::append(std::move(toks), true); // Lazy resizing
190  }
191  else
192  {
193  // Found primitive entry - copy tokens
194 
195  if (eptr->stream().empty() ? (altType == '-') : (altType == '+'))
196  {
197  // Not found or empty: use ":-" alternative value
198  // Found and not empty: use ":+" alternative value
199 
200  tokenList toks(ITstream::parse(altValue, IOstream::ASCII));
201 
202  ITstream::append(std::move(toks), true); // Lazy resizing
203  }
204  else
205  {
206  ITstream::append(eptr->stream(), true); // Lazy resizing
207  }
208  }
209 
210  return true;
211 }
212 
213 
214 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
215 
217 :
218  entry(key),
219  ITstream(key, tokenList())
220 {}
221 
222 
224 :
225  entry(key),
226  ITstream(key, tokenList(1, tok))
227 {}
228 
229 
231 (
232  const keyType& key,
233  const UList<token>& tokens
234 )
235 :
236  entry(key),
237  ITstream(key, tokens)
238 {}
239 
240 
242 (
243  const keyType& key,
244  List<token>&& tokens
245 )
246 :
247  entry(key),
248  ITstream(key, std::move(tokens))
249 {}
250 
251 
253 :
254  entry(key),
255  ITstream(is)
256 {
257  name() += '.' + key;
258 }
259 
260 
261 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
262 
264 {
265  const tokenList& tokens = *this;
266 
267  if (tokens.size())
268  {
269  return tokens.first().lineNumber();
270  }
271 
272  return -1;
273 }
274 
275 
277 {
278  const tokenList& tokens = *this;
279 
280  if (tokens.size())
281  {
282  return tokens.last().lineNumber();
283  }
284 
285  return -1;
286 }
287 
288 
290 {
291  ITstream& is = const_cast<primitiveEntry&>(*this);
292  is.rewind();
293  return is;
294 }
295 
296 
298 {
300  << "Attempt to return primitive entry " << info()
301  << " as a sub-dictionary"
302  << abort(FatalError);
303 
304  return dictionary::null;
305 }
306 
307 
309 {
311  << "Attempt to return primitive entry " << info()
312  << " as a sub-dictionary"
313  << abort(FatalError);
314 
315  return const_cast<dictionary&>(dictionary::null);
316 }
317 
318 
319 // ************************************************************************* //
Foam::entry::entry
entry(const keyType &keyword)
Construct from keyword.
Definition: entry.C:55
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::ITstream::append
void append(const token &t, const bool lazy)
Definition: ITstream.C:408
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::ITstream::rewind
virtual void rewind()
Rewind the stream so that it may be read again.
Definition: ITstream.C:356
Foam::keyType::LITERAL_RECURSIVE
Definition: keyType.H:78
Foam::primitiveEntry
A keyword and a list of tokens comprise a primitiveEntry. A primitiveEntry can be read,...
Definition: primitiveEntry.H:63
primitiveEntry.H
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.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))
Definition: gmvOutputSpray.H:25
Foam::primitiveEntry::primitiveEntry
primitiveEntry(const keyType &key)
Construct from keyword and no tokens.
Definition: primitiveEntry.C:216
Foam::primitiveEntry::stream
virtual ITstream & stream() const
Return token stream for this primitive entry.
Definition: primitiveEntry.C:289
Foam::FatalIOError
IOerror FatalIOError
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::primitiveEntry::dict
virtual const dictionary & dict() const
This entry is not a dictionary,.
Definition: primitiveEntry.C:297
Foam::getEnv
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
Foam::dictionary::null
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Definition: dictionary.H:385
Foam::keyType
A class for handling keywords in dictionaries.
Definition: keyType.H:60
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:55
Foam::primitiveEntry::endLineNumber
virtual label endLineNumber() const
Return line number of last token in dictionary.
Definition: primitiveEntry.C:276
Foam::primitiveEntry::startLineNumber
virtual label startLineNumber() const
Return line number of first token in dictionary.
Definition: primitiveEntry.C:263
Foam::stringOps::inplaceExpand
void inplaceExpand(std::string &s, const HashTable< string, word, string::hash > &mapping, const char sigil='$')
Definition: stringOps.C:733
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::ITstream::parse
static tokenList parse(const UList< char > &input, streamFormat format=ASCII)
Definition: ITstream.C:56
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::token::BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:126
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::tokenList
List< token > tokenList
List of tokens, used for a IOdictionary entry.
Definition: tokenList.H:44
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::dictionary::findScoped
const entry * findScoped(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for a scoped entry (const access) with the given keyword.
Definition: dictionary.C:394
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
dictionary.H
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::dictionary::toc
wordList toc() const
Return the table of contents.
Definition: dictionary.C:670
stringOps.H
Foam::primitiveEntry::name
virtual const fileName & name() const
Return the dictionary name.
Definition: primitiveEntry.H:146
findParameterAlternative
static int findParameterAlternative(const std::string &s, std::string::size_type &pos, std::string::size_type endPos=std::string::npos)
Definition: primitiveEntry.C:39
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177