Loading...
Searching...
No Matches
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-2023 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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 ':+'
38static inline char findParameterAlternative
39(
40 const std::string& s,
41 std::string::size_type& pos,
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 char 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
75bool Foam::primitiveEntry::expandVariable
76(
77 const string& varName,
78 const dictionary& dict
79)
80{
81 char altType = 0; // Type ('-' or '+') for ":-" or ":+" alternatives
82 word expanded;
83 string altValue;
84
85 // Any ${{ expr }} entries have been trapped and processed elsewhere
86
87 if (varName[0] == token::BEGIN_BLOCK && varName.size() > 1)
88 {
89 // Replace content between {} with string expansion and
90 // handle ${parameter:-word} or ${parameter:+word}
91
92 // Copy into a word without stripping
93 expanded.assign(varName, 1, varName.size()-2);
94
95 // Substitute dictionary and environment variables.
96 // - Allow environment.
97 // - No empty substitutions.
98 // - No sub-dictionary lookups
99
100 stringOps::inplaceExpand(expanded, dict, true, false, false);
101
102 // Position of ":-" or ":+" alternative values
103 std::string::size_type altPos = 0;
104
105 // Check for parameter:-word or parameter:+word
106 altType = findParameterAlternative(expanded, altPos);
107
108 if (altType)
109 {
110 altValue = expanded.substr(altPos + 2);
111 expanded.erase(altPos);
112 }
113
114 // Catch really bad expansions and let them die soon after.
115 // Eg, ${:-other} should not be allowed.
116 if (expanded.empty())
117 {
118 altType = 0;
119 altValue.clear();
120 }
121
122 // Fallthrough for further processing
124
125
126 // Lookup variable name in the given dictionary WITHOUT pattern matching.
127 // Having a pattern match means that in this example:
128 // {
129 // internalField XXX;
130 // boundaryField { ".*" {YYY;} movingWall {value $internalField;}
131 // }
132 // The $internalField would be matched by the ".*" !!!
134 // Recursive, non-patterns
135
136 const word& lookupName = (expanded.empty() ? varName : expanded);
137
138 const entry* eptr =
139 dict.findScoped(lookupName, keyType::LITERAL_RECURSIVE);
140
141 if (!eptr)
142 {
143 // Not found - revert to environment variable
144 // and parse into a series of tokens.
145
146 // We wish to fail if the environment variable returns
147 // an empty string and there is no alternative given.
148 //
149 // Always allow empty strings as alternative parameters,
150 // since the user provided them for a reason.
151
152 string str(Foam::getEnv(lookupName));
153
154 if (str.empty() ? (altType == '-') : (altType == '+'))
155 {
156 // Not found or empty: use ":-" alternative value
157 // Found and not empty: use ":+" alternative value
158 str = std::move(altValue);
159 }
160 else if (str.empty())
161 {
163 << "Illegal dictionary entry or environment variable name "
164 << lookupName << nl
165 << "Known dictionary entries: " << dict.toc() << nl
166 << exit(FatalIOError);
167
168 return false;
169 }
170
171 // Parse string into a series of tokens
172
173 tokenList toks(ITstream::parse(str)); // ASCII
174
175 ITstream::add_tokens(std::move(toks)); // Add at tokenIndex
176 }
177 else if (eptr->isDict())
178 {
179 // Found dictionary entry
180
181 tokenList toks(eptr->dict().tokens());
182
183 if (toks.empty() ? (altType == '-') : (altType == '+'))
184 {
185 // Not found or empty: use ":-" alternative value
186 // Found and not empty: use ":+" alternative value
187
188 toks = ITstream::parse(altValue); // ASCII
189 }
190
191 ITstream::add_tokens(std::move(toks)); // Add at tokenIndex
192 }
193 else
194 {
195 // Found primitive entry - copy tokens
196
197 if (eptr->stream().empty() ? (altType == '-') : (altType == '+'))
198 {
199 // Not found or empty: use ":-" alternative value
200 // Found and not empty: use ":+" alternative value
201
202 tokenList toks(ITstream::parse(altValue)); // ASCII
203
204 ITstream::add_tokens(std::move(toks)); // Add at tokenIndex
205 }
206 else
207 {
208 ITstream::add_tokens(eptr->stream()); // Add at tokenIndex
209 }
210 }
212 return true;
213}
214
215
216// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
217
219:
220 entry(key),
221 ITstream(Foam::zero{}, key)
222{}
223
224
226:
227 entry(key),
228 ITstream(key, tokenList(Foam::one{}, tok))
229{}
230
231
233:
234 entry(key),
235 ITstream(key, tokenList(Foam::one{}, std::move(tok)))
236{}
237
238
240(
241 const keyType& key,
242 const UList<token>& tokens
244:
245 entry(key),
246 ITstream(key, tokens)
247{}
248
249
251(
252 const keyType& key,
253 List<token>&& tokens
255:
256 entry(key),
257 ITstream(key, std::move(tokens))
258{}
259
260
262(
263 const keyType& key,
264 const ITstream& is
265)
266:
267 entry(key),
268 ITstream(is)
271}
272
273
274// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
275
278 ITstream* ptr = const_cast<primitiveEntry*>(this);
279 ptr->seek(0);
280 return ptr;
281}
282
283
286 ITstream& is = const_cast<primitiveEntry&>(*this);
287 is.seek(0);
288 return is;
289}
290
291
293{
295 << "Attempt to return primitive entry " << info()
296 << " as a sub-dictionary"
297 << abort(FatalError);
298
299 return dictionary::null;
300}
301
302
304{
306 << "Attempt to return primitive entry " << info()
307 << " as a sub-dictionary"
308 << abort(FatalError);
309
310 return const_cast<dictionary&>(dictionary::null);
311}
312
313
314// ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
An input stream of tokens.
Definition ITstream.H:56
virtual const fileName & name() const override
The name of the input token stream.
Definition ITstream.H:317
static tokenList parse(const UList< char > &input, IOstreamOption streamOpt=IOstreamOption())
Create token list by parsing the input character sequence until no good tokens remain.
Definition ITstream.H:268
void add_tokens(const token &tok)
Copy append a token at the current tokenIndex, incrementing the index.
Definition ITstream.C:709
void seek(label pos) noexcept
Move tokenIndex to the specified position and adjust the stream status (open/good/eof ....
Definition ITstream.C:353
const tokenList & tokens() const noexcept
The token contents (read-only access).
Definition ITstream.H:346
ITstream(const ITstream &is)
Copy construct.
Definition ITstream.C:148
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
tokenList tokens() const
Return the dictionary as a list of tokens.
Definition dictionary.C:234
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Definition dictionary.H:487
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66
entry(const keyType &keyword)
Construct from keyword.
Definition entry.C:62
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
virtual bool isDict() const noexcept
True if this entry is a dictionary.
Definition entry.H:284
virtual const dictionary & dict() const =0
Return dictionary, if entry is a dictionary, otherwise Fatal.
static fileName concat(const std::string &s1, const std::string &s2, const char delim='/')
Join two strings with a path separator ('/' by default).
Definition fileName.C:211
A class for handling keywords in dictionaries.
Definition keyType.H:69
@ LITERAL_RECURSIVE
Definition keyType.H:87
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition one.H:57
primitiveEntry(const keyType &key)
Construct from keyword and no tokens.
virtual ITstream * streamPtr() const noexcept
Return pointer to token stream for this primitive entry.
InfoProxy< primitiveEntry > info() const noexcept
Return info proxy, to print token information to a stream.
virtual ITstream & stream() const
Return token stream for this primitive entry.
virtual const dictionary & dict() const
This entry is not a dictionary, calling this function generates a FatalError.
A token holds an item read from Istream.
Definition token.H:70
@ BEGIN_BLOCK
Begin block [isseparator].
Definition token.H:178
A class for handling words, derived from Foam::string.
Definition word.H:66
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
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))
void inplaceExpand(std::string &s, const HashTable< string > &mapping, const char sigil='$')
Inplace expand occurrences of variables according to the mapping. Does not use environment values.
Namespace for OpenFOAM.
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition POSIX.C:341
errorManip< error > abort(error &err)
Definition errorManip.H:139
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
List< token > tokenList
List of token, used for dictionary primitive entry (for example).
Definition tokenList.H:32
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
static char findParameterAlternative(const std::string &s, std::string::size_type &pos, std::string::size_type endPos=std::string::npos)
dictionary dict