Loading...
Searching...
No Matches
debug.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-2018 OpenFOAM Foundation
9 Copyright (C) 2019-2022 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
27Description
28 Class for handling debugging switches.
29
30Note
31 Included by global/globals.C
32
33\*---------------------------------------------------------------------------*/
34
35#include "debug.H"
36#include "dictionary.H"
37#include "IFstream.H"
38#include "etcFiles.H"
39#include "Ostream.H"
40#include "demandDrivenData.H"
42#include "IOobject.H"
43#include "HashSet.H"
44#include "nullObject.H"
45
46// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47
48namespace Foam
49{
50namespace debug
51{
52
54//- Skip documentation : local scope only
55
56dictionary* controlDictPtr_(nullptr);
57dictionary* debugSwitchesPtr_(nullptr);
58dictionary* infoSwitchesPtr_(nullptr);
59dictionary* optimisationSwitchesPtr_(nullptr);
60
61// Debug switch read and write callback tables.
62simpleObjectRegistry* debugObjectsPtr_(nullptr);
63simpleObjectRegistry* infoObjectsPtr_(nullptr);
64simpleObjectRegistry* optimisationObjectsPtr_(nullptr);
65simpleObjectRegistry* dimensionSetObjectsPtr_(nullptr);
66simpleObjectRegistry* dimensionedConstantObjectsPtr_(nullptr);
67
68
69// To ensure controlDictPtr_ is deleted at the end of the run
70struct deleteControlDictPtr
71{
72 ~deleteControlDictPtr()
73 {
74 deleteDemandDrivenData(debugObjectsPtr_);
75 deleteDemandDrivenData(infoObjectsPtr_);
76 deleteDemandDrivenData(optimisationObjectsPtr_);
77 deleteDemandDrivenData(dimensionSetObjectsPtr_);
78 deleteDemandDrivenData(dimensionedConstantObjectsPtr_);
79
80 debugSwitchesPtr_ = nullptr;
81 infoSwitchesPtr_ = nullptr;
82 optimisationSwitchesPtr_ = nullptr;
83 deleteDemandDrivenData(controlDictPtr_);
84 }
85};
86
87deleteControlDictPtr deleteControlDictPtr_;
88
89
90
91} // End namespace debug
92} // End namespace Foam
93
94
95// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
96
97namespace Foam
98{
100// Like dictionary getOrAdd with LITERAL, but circumventing
101// writeOptionalEntries to avoid extremely noisy output
102template<class T>
103static inline T getOrAdd
104(
106 const char* name,
107 const T deflt
108)
109{
110 const entry* eptr = dict.findEntry(name, keyType::LITERAL);
111
112 if (eptr)
113 {
114 return eptr->get<T>();
115 }
116
117 dict.add(new primitiveEntry(name, deflt));
118 return deflt;
120
121
122// Append object to a registry
123static inline void appendNamedEntry
124(
125 simpleObjectRegistry& obr,
126 const char* name,
127 simpleRegIOobject* obj
128)
129{
130 simpleObjectRegistryEntry* ptr = obr.find(name);
131 if (ptr)
132 {
133 ptr->append(obj);
134 }
135 else
136 {
137 obr.append(name, new simpleObjectRegistryEntry(obj));
138 }
139}
140
141} // End namespace Foam
143
144// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
145
147{
148 if (!controlDictPtr_)
149 {
150 string controlDictString(Foam::getEnv("FOAM_CONTROLDICT"));
151 if (!controlDictString.empty())
152 {
153 // Read from environment
154 IStringStream is(controlDictString);
155 controlDictPtr_ = new dictionary(is);
156 }
157 else
158 {
159 fileNameList controlDictFiles = findEtcFiles("controlDict", true);
160 controlDictPtr_ = new dictionary();
161 forAllReverse(controlDictFiles, i)
162 {
163 IFstream is(controlDictFiles[i]);
164
165 if (!is.good())
166 {
168 (
169 is,
170 "Cannot open controlDict"
171 );
172 }
173 controlDictPtr_->merge(dictionary(is));
174 }
175 }
176 }
177
178 return *controlDictPtr_;
179}
180
181
183(
184 const char* subDictName,
185 dictionary*& subDictPtr
186)
187{
188 if (!subDictPtr)
189 {
190 subDictPtr = controlDict().findDict(subDictName, keyType::LITERAL);
191
192 if (!subDictPtr)
193 {
194 std::cerr
195 << "debug::switchSet(const char*, dictionary*&):\n"
196 << " Cannot find " << subDictName << " in dictionary "
197 << controlDict().name().c_str()
198 << std::endl << std::endl;
199
200 std::exit(1);
201 }
202 }
203
204 return *subDictPtr;
205}
206
207
209{
210 return switchSet("DebugSwitches", debugSwitchesPtr_);
211}
212
213
215{
216 return switchSet("InfoSwitches", infoSwitchesPtr_);
217}
218
219
221{
222 return switchSet("OptimisationSwitches", optimisationSwitchesPtr_);
223}
224
225
226int Foam::debug::debugSwitch(const char* name, const int deflt)
227{
228 return getOrAdd(debugSwitches(), name, deflt);
229}
230
231
232int Foam::debug::infoSwitch(const char* name, const int deflt)
233{
234 return getOrAdd(infoSwitches(), name, deflt);
235}
236
237
238int Foam::debug::optimisationSwitch(const char* name, const int deflt)
239{
241}
242
243
244float Foam::debug::floatOptimisationSwitch(const char* name, const float deflt)
245{
247}
248
249
251{
253}
254
255
257{
259}
260
261
263(
264 const char* name,
266)
267{
269}
270
271
273(
274 const char* name,
276)
277{
286)
287{
289}
290
291
293{
294 if (!debugObjectsPtr_)
295 {
296 debugObjectsPtr_ = new simpleObjectRegistry(128);
297 }
298
299 return *debugObjectsPtr_;
300}
301
302
304{
305 if (!infoObjectsPtr_)
306 {
307 infoObjectsPtr_ = new simpleObjectRegistry(128);
308 }
309
310 return *infoObjectsPtr_;
311}
312
313
315{
316 if (!optimisationObjectsPtr_)
317 {
318 optimisationObjectsPtr_ = new simpleObjectRegistry(128);
319 }
320
321 return *optimisationObjectsPtr_;
322}
323
324
326{
327 if (!dimensionSetObjectsPtr_)
328 {
329 dimensionSetObjectsPtr_ = new simpleObjectRegistry(128);
330 }
331
332 return *dimensionSetObjectsPtr_;
333}
334
335
337{
338 if (!dimensionedConstantObjectsPtr_)
339 {
340 dimensionedConstantObjectsPtr_ = new simpleObjectRegistry(128);
341 }
342
343 return *dimensionedConstantObjectsPtr_;
344}
345
346
347// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
348
349namespace Foam
350{
351
352// Print the switch status
353static inline void printStatus
354(
355 const char * const message,
356 const wordList& list
357)
358{
359 // Use writeList with length = -1 to ensure we always have newlines,
360 // even for short lists
361
362 Info<< message << nl;
363 list.writeList(Info, -1) << nl;
364}
365
366
367// Write the switch names.
369// Use writeList with -1 for the length to ensure we always have newlines,
370// even if the lists are short
371
372static void listSwitches
373(
374 const wordList& debugSwitches,
375 const wordList& infoSwitches,
376 const wordList& optSwitches,
377 const bool unset
378)
379{
381
382 if (unset)
383 {
384 fileNameList controlDictFiles = findEtcFiles("controlDict", true);
386 forAllReverse(controlDictFiles, i)
387 {
388 IFstream is(controlDictFiles[i]);
389
390 controlDict.merge(dictionary(is));
391 }
392
393 // HashSet to track switches that have not been set
394 wordHashSet hashed;
395
396 // DebugSwitches
397 if (notNull(debugSwitches))
398 {
399 hashed = debugSwitches;
400 hashed.unset(controlDict.subDict("DebugSwitches").toc());
401 printStatus("Unset DebugSwitches", hashed.sortedToc());
402 }
403
404 // InfoSwitches
405 if (notNull(infoSwitches))
406 {
407 hashed = infoSwitches;
408 hashed.unset(controlDict.subDict("InfoSwitches").toc());
409 printStatus("Unset InfoSwitches", hashed.sortedToc());
410 }
411
412 // OptimisationSwitches
413 if (notNull(optSwitches))
414 {
415 hashed = optSwitches;
416 hashed.unset(controlDict.subDict("OptimisationSwitches").toc());
417 printStatus("Unset OptimisationSwitches", hashed.sortedToc());
418 }
419 }
420 else
421 {
422 // DebugSwitches
423 if (notNull(debugSwitches))
424 {
425 printStatus("DebugSwitches", debugSwitches);
426 }
427
428 // InfoSwitches
429 if (notNull(infoSwitches))
430 {
431 printStatus("InfoSwitches", infoSwitches);
432 }
433
434 // OptimisationSwitches
435 if (notNull(optSwitches))
436 {
437 printStatus("OptimisationSwitches", optSwitches);
438 }
439 }
440}
441
442} // End namespace Foam
444
445// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
446
447void Foam::debug::listSwitches(const bool unset)
448{
450 (
451 debug::debugSwitches().sortedToc(),
452 debug::infoSwitches().sortedToc(),
453 debug::optimisationSwitches().sortedToc(),
454 unset
455 );
456}
457
458
459void Foam::debug::listDebugSwitches(const bool unset)
460{
462 (
463 debug::debugSwitches().sortedToc(),
466 unset
467 );
468}
469
470
471void Foam::debug::listInfoSwitches(const bool unset)
472{
474 (
476 debug::infoObjects().sortedToc(),
478 unset
479 );
480}
481
482
483void Foam::debug::listOptimisationSwitches(const bool unset)
484{
486 (
489 debug::optimisationSwitches().sortedToc(),
490 unset
491 );
492}
493
494
495void Foam::debug::listRegisteredSwitches(const bool unset)
496{
498 (
499 debug::debugObjects().sortedToc(),
500 debug::infoObjects().sortedToc(),
501 debug::optimisationObjects().sortedToc(),
502 unset
503 );
504}
505
506
507void Foam::debug::listRegisteredDebugSwitches(const bool unset)
508{
510 (
511 debug::debugObjects().sortedToc(),
514 unset
515 );
516}
517
518
519void Foam::debug::listRegisteredInfoSwitches(const bool unset)
520{
522 (
524 debug::infoObjects().sortedToc(),
526 unset
527 );
528}
529
530
532{
534 (
537 debug::optimisationObjects().sortedToc(),
538 unset
539 );
540}
541
542
543// ************************************************************************* //
void append(const word &k, T *ptr)
Add to back of dictionary.
T * find(const word &keyword)
Find and return an entry, nullptr on failure.
bool unset(const Key &key)
Unset the specified key - same as erase.
Definition HashSet.H:247
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition HashTable.C:156
Input from file stream as an ISstream, normally using std::ifstream for the actual input.
Definition IFstream.H:55
static Ostream & writeDivider(Ostream &os)
Write the standard file section divider.
bool good() const noexcept
True if next operation might succeed.
Definition IOstream.H:281
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
void append(const T &val)
Append an element at the end of the list.
Definition List.H:497
static const List< word > & null() noexcept
Definition List.H:138
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition UListIO.C:90
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and it is a dictionary) otherwise return nullptr...
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66
T get() const
Get a T from the stream, FatalIOError if the number of tokens is incorrect.
Definition entry.H:326
@ LITERAL
String literal.
Definition keyType.H:82
A keyword and a list of tokens comprise a primitiveEntry. A primitiveEntry can be read,...
Object registry for simpleRegIOobject. Maintains ordering.
Abstract base class for registered object with I/O. Used in debug symbol registration.
runTime controlDict().readEntry("adjustTimeStep"
Template functions to aid in the implementation of demand driven data.
#define SafeFatalIOErrorInFunction(ios, msg)
Report an error message using Foam::FatalIOError.
Definition error.H:662
Functions to search 'etc' directories for configuration files etc.
auto & name
Namespace for handling debugging switches.
Definition debug.C:45
dictionary & switchSet(const char *subDictName, dictionary *&subDictPtr)
Internal function to lookup a sub-dictionary from controlDict.
Definition debug.C:179
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition debug.C:228
void listDebugSwitches(const bool unset=false)
List debug switches.
Definition debug.C:455
int debugSwitch(const char *name, const int deflt=0)
Lookup debug switch or add default value.
Definition debug.C:222
void addDebugObject(const char *name, simpleRegIOobject *obj)
Register debug switch read/write object.
Definition debug.C:246
void listSwitches(const bool unset=false)
List debug/info/optimisation switches.
Definition debug.C:443
void listRegisteredOptimisationSwitches(const bool unset=false)
List optimisation switches.
Definition debug.C:527
simpleObjectRegistry & infoObjects()
Access to registered InfoSwitch objects.
Definition debug.C:299
simpleObjectRegistry & dimensionSetObjects()
Access to registered DimensionSets objects.
Definition debug.C:321
float floatOptimisationSwitch(const char *name, const float deflt=0)
Lookup optimisation switch or add default value.
Definition debug.C:240
void addDimensionedConstantObject(const char *name, simpleRegIOobject *)
Register DimensionedConstant read/write object.
Definition debug.C:279
simpleObjectRegistry & dimensionedConstantObjects()
Access to registered DimensionedConstants objects.
Definition debug.C:332
dictionary & optimisationSwitches()
The OptimisationSwitches sub-dictionary in the central controlDict(s).
Definition debug.C:216
void listRegisteredSwitches(const bool unset=false)
List registered debug/info/optimisation switches.
Definition debug.C:491
void listRegisteredDebugSwitches(const bool unset=false)
List debug switches.
Definition debug.C:503
void addOptimisationObject(const char *name, simpleRegIOobject *obj)
Register optimisation switch read/write object.
Definition debug.C:259
void listOptimisationSwitches(const bool unset=false)
List optimisation switches.
Definition debug.C:479
void addInfoObject(const char *name, simpleRegIOobject *obj)
Register info switch read/write object.
Definition debug.C:252
dictionary & controlDict()
The central control dictionary, the contents of which are either taken directly from the FOAM_CONTROL...
Definition debug.C:142
void listRegisteredInfoSwitches(const bool unset=false)
List info switches.
Definition debug.C:515
simpleObjectRegistry & optimisationObjects()
Access to registered OptimisationSwitch objects.
Definition debug.C:310
dictionary & infoSwitches()
The InfoSwitches sub-dictionary in the central controlDict(s).
Definition debug.C:210
void listInfoSwitches(const bool unset=false)
List info switches.
Definition debug.C:467
simpleObjectRegistry & debugObjects()
Access to registered DebugSwitch objects.
Definition debug.C:288
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition debug.C:234
void addDimensionSetObject(const char *name, simpleRegIOobject *obj)
Register DimensionSets read/write object.
Definition debug.C:269
dictionary & debugSwitches()
The DebugSwitches sub-dictionary in the central controlDict(s).
Definition debug.C:204
Namespace for OpenFOAM.
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition POSIX.C:341
List< word > wordList
List of word.
Definition fileName.H:60
static void appendNamedEntry(simpleObjectRegistry &obr, const char *name, simpleRegIOobject *obj)
Definition debug.C:120
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition HashSet.H:80
List< fileName > fileNameList
List of fileName.
messageStream Info
Information stream (stdout output on master, null elsewhere).
static void listSwitches(const wordList &debugSwitches, const wordList &infoSwitches, const wordList &optSwitches, const bool unset)
Definition debug.C:369
static void printStatus(const char *const message, const wordList &list)
Definition debug.C:350
static T getOrAdd(dictionary &dict, const char *name, const T deflt)
Definition debug.C:100
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
bool notNull(const T *ptr) noexcept
True if ptr is not a pointer (of type T) to the nullObject.
Definition nullObject.H:267
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
fileNameList findEtcFiles(const fileName &name, const bool mandatory=false, unsigned short location=0777, const bool findFirst=false)
Search for files from user/group/other etc locations.
Definition etcFiles.C:385
void deleteDemandDrivenData(DataPtr &dataPtr)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition stdFoam.H:315