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