debug.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 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 Description
25  Class for handling debugging switches.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "debug.H"
30 #include "dictionary.H"
31 #include "IFstream.H"
32 #include "etcFiles.H"
33 #include "Ostream.H"
34 #include "demandDrivenData.H"
35 #include "simpleObjectRegistry.H"
36 #include "IOobject.H"
37 #include "HashSet.H"
38 
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
43 namespace debug
44 {
45 
47 //- Skip documentation : local scope only
48 
49 dictionary* controlDictPtr_(nullptr);
50 dictionary* debugSwitchesPtr_(nullptr);
51 dictionary* infoSwitchesPtr_(nullptr);
52 dictionary* optimisationSwitchesPtr_(nullptr);
53 
54 // Debug switch read and write callback tables.
55 simpleObjectRegistry* debugObjectsPtr_(nullptr);
56 simpleObjectRegistry* infoObjectsPtr_(nullptr);
57 simpleObjectRegistry* optimisationObjectsPtr_(nullptr);
58 simpleObjectRegistry* dimensionSetObjectsPtr_(nullptr);
59 simpleObjectRegistry* dimensionedConstantObjectsPtr_(nullptr);
60 
61 
62 // To ensure controlDictPtr_ is deleted at the end of the run
63 class deleteControlDictPtr
64 {
65 public:
66 
67  deleteControlDictPtr()
68  {}
69 
70  ~deleteControlDictPtr()
71  {
72  deleteDemandDrivenData(debugObjectsPtr_);
73  deleteDemandDrivenData(infoObjectsPtr_);
74  deleteDemandDrivenData(optimisationObjectsPtr_);
75  deleteDemandDrivenData(dimensionSetObjectsPtr_);
76  deleteDemandDrivenData(dimensionedConstantObjectsPtr_);
77 
78  debugSwitchesPtr_ = nullptr;
79  infoSwitchesPtr_ = nullptr;
80  optimisationSwitchesPtr_ = nullptr;
81  deleteDemandDrivenData(controlDictPtr_);
82  }
83 };
84 
85 deleteControlDictPtr deleteControlDictPtr_;
87 
88 
89 } // End namespace debug
90 } // End namespace Foam
91 
92 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
93 
95 {
96  if (!controlDictPtr_)
97  {
98  string controlDictString(getEnv("FOAM_CONTROLDICT"));
99  if (!controlDictString.empty())
100  {
101  // Read from environment
102  IStringStream is(controlDictString);
103  controlDictPtr_ = new dictionary(is);
104  }
105  else
106  {
107  fileNameList controlDictFiles = findEtcFiles("controlDict", true);
108  controlDictPtr_ = new dictionary();
109  forAllReverse(controlDictFiles, cdfi)
110  {
111  IFstream ifs(controlDictFiles[cdfi]);
112 
113  if (!ifs.good())
114  {
116  (
117  ifs,
118  "Cannot open controlDict"
119  );
120  }
121  controlDictPtr_->merge(dictionary(ifs));
122  }
123  }
124  }
125 
126  return *controlDictPtr_;
127 }
128 
129 
131 (
132  const char* subDictName,
133  dictionary*& subDictPtr
134 )
135 {
136  if (!subDictPtr)
137  {
139  (
140  subDictName, false, false
141  );
142 
143  if (!ePtr || !ePtr->isDict())
144  {
145  cerr<< "debug::switchSet(const char*, dictionary*&):\n"
146  << " Cannot find " << subDictName << " in dictionary "
147  << controlDict().name().c_str()
148  << std::endl << std::endl;
149 
150  ::exit(1);
151  }
152 
153  subDictPtr = &ePtr->dict();
154  }
155 
156  return *subDictPtr;
157 }
158 
159 
161 {
162  return switchSet("DebugSwitches", debugSwitchesPtr_);
163 }
164 
165 
167 {
168  return switchSet("InfoSwitches", infoSwitchesPtr_);
169 }
170 
171 
173 {
174  return switchSet("OptimisationSwitches", optimisationSwitchesPtr_);
175 }
176 
177 
178 int Foam::debug::debugSwitch(const char* name, const int defaultValue)
179 {
181  (
182  name, defaultValue, false, false
183  );
184 }
185 
186 
187 int Foam::debug::infoSwitch(const char* name, const int defaultValue)
188 {
190  (
191  name, defaultValue, false, false
192  );
193 }
194 
195 
196 int Foam::debug::optimisationSwitch(const char* name, const int defaultValue)
197 {
199  (
200  name, defaultValue, false, false
201  );
202 }
203 
204 
206 (
207  const char* name,
208  const float defaultValue
209 )
210 {
212  (
213  name, defaultValue, false, false
214  );
215 }
216 
217 
218 void Foam::debug::addDebugObject(const char* name, simpleRegIOobject* obj)
219 {
221  if (ptr)
222  {
223  ptr->append(obj);
224  }
225  else
226  {
228  (
229  name,
231  (
233  )
234  );
235  }
236 }
237 
238 
239 void Foam::debug::addInfoObject(const char* name, simpleRegIOobject* obj)
240 {
242  if (ptr)
243  {
244  ptr->append(obj);
245  }
246  else
247  {
249  (
250  name,
252  (
254  )
255  );
256  }
257 }
258 
259 
261 (
262  const char* name,
263  simpleRegIOobject* obj
264 )
265 {
267  if (ptr)
268  {
269  ptr->append(obj);
270  }
271  else
272  {
274  (
275  name,
277  (
279  )
280  );
281  }
282 }
283 
284 
286 (
287  const char* name,
288  simpleRegIOobject* obj
289 )
290 {
292  if (ptr)
293  {
294  ptr->append(obj);
295  }
296  else
297  {
299  (
300  name,
302  (
304  )
305  );
306  }
307 }
308 
309 
311 (
312  const char* name,
313  simpleRegIOobject* obj
314 )
315 {
317  (
318  name
319  );
320  if (ptr)
321  {
322  ptr->append(obj);
323  }
324  else
325  {
327  (
328  name,
330  (
332  )
333  );
334  }
335 }
336 
337 
339 {
340  if (!debugObjectsPtr_)
341  {
342  debugObjectsPtr_ = new simpleObjectRegistry(1000);
343  }
344 
345  return *debugObjectsPtr_;
346 }
347 
348 
350 {
351  if (!infoObjectsPtr_)
352  {
353  infoObjectsPtr_ = new simpleObjectRegistry(100);
354  }
355 
356  return *infoObjectsPtr_;
357 }
358 
359 
361 {
362  if (!optimisationObjectsPtr_)
363  {
364  optimisationObjectsPtr_ = new simpleObjectRegistry(100);
365  }
366 
367  return *optimisationObjectsPtr_;
368 }
369 
370 
372 {
373  if (!dimensionSetObjectsPtr_)
374  {
375  dimensionSetObjectsPtr_ = new simpleObjectRegistry(100);
376  }
377 
378  return *dimensionSetObjectsPtr_;
379 }
380 
381 
383 {
384  if (!dimensionedConstantObjectsPtr_)
385  {
386  dimensionedConstantObjectsPtr_ = new simpleObjectRegistry(100);
387  }
388 
389  return *dimensionedConstantObjectsPtr_;
390 }
391 
392 
393 namespace Foam
394 {
395 
396 void listSwitches
397 (
398  const wordList& debugSwitches,
399  const wordList& infoSwitches,
400  const wordList& optSwitches,
401  const bool unset
402 )
403 {
404  if (unset)
405  {
406  fileNameList controlDictFiles = findEtcFiles("controlDict", true);
408  forAllReverse(controlDictFiles, cdfi)
409  {
410  controlDict.merge(dictionary(IFstream(controlDictFiles[cdfi])()));
411  }
412 
413  wordHashSet controlDictDebug
414  (
415  controlDict.subDict("DebugSwitches").sortedToc()
416  );
417 
418  wordHashSet controlDictInfo
419  (
420  controlDict.subDict("InfoSwitches").sortedToc()
421  );
422 
423  wordHashSet controlDictOpt
424  (
425  controlDict.subDict("OptimisationSwitches").sortedToc()
426  );
427 
428 
430 
431  wordHashSet hashset;
432  hashset = debugSwitches;
433  hashset -= controlDictDebug;
434  Info<< "Unset DebugSwitches" << hashset.sortedToc() << endl;
435 
436  hashset = infoSwitches;
437  hashset -= controlDictInfo;
438  Info<< "Unset InfoSwitches" << hashset.sortedToc() << endl;
439 
440  hashset = optSwitches;
441  hashset -= controlDictOpt;
442  Info<< "Unset OptimisationSwitches" << hashset.sortedToc() << endl;
443  }
444  else
445  {
447  Info<< "DebugSwitches" << debugSwitches << endl;
448  Info<< "InfoSwitches" << infoSwitches << endl;
449  Info<< "OptimisationSwitches" << optSwitches << endl;
450  }
451 }
452 
453 }
454 
455 
456 void Foam::debug::listSwitches(const bool unset)
457 {
459  (
460  debug::debugSwitches().sortedToc(),
461  debug::infoSwitches().sortedToc(),
462  debug::optimisationSwitches().sortedToc(),
463  unset
464  );
465 }
466 
467 
469 {
471  (
472  debug::debugObjects().sortedToc(),
473  debug::infoObjects().sortedToc(),
474  debug::optimisationObjects().sortedToc(),
475  unset
476  );
477 }
478 
479 
480 // ************************************************************************* //
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:97
Abstract base class for registered object with I/O. Used in debug symbol registration.
A HashTable with keys but without contents.
Definition: HashSet.H:59
void addInfoObject(const char *name, simpleRegIOobject *obj)
Register info switch read/write object.
Definition: debug.C:239
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:706
float floatOptimisationSwitch(const char *name, const float defaultValue=0)
Lookup optimisation switch or add default value.
Definition: debug.C:206
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dictionary & switchSet(const char *subDictName, dictionary *&subDictPtr)
Internal function to lookup a sub-dictionary from controlDict.
Definition: debug.C:131
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
T lookupOrAddDefault(const word &, const T &, bool recursive=false, bool patternMatch=true)
Find and return a T, if not found return the given.
static Stream & writeDivider(Stream &os)
Write the standard file section divider.
Definition: IOobjectI.H:113
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:446
int optimisationSwitch(const char *name, const int defaultValue=0)
Lookup optimisation switch or add default value.
Definition: debug.C:196
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
const T * lookupPtr(const word &) const
Find and return an entry if present, otherwise return nullptr.
void append(const word &, T *)
Add at tail of dictionary.
simpleObjectRegistry & debugObjects()
Get access to registered debug switch objects.
Definition: debug.C:338
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
int infoSwitch(const char *name, const int defaultValue=0)
Lookup info switch or add default value.
Definition: debug.C:187
simpleObjectRegistry & optimisationObjects()
Get access to registered optimisation switch objects.
Definition: debug.C:360
fileNameList findEtcFiles(const fileName &, bool mandatory=false, bool findFirst=false)
Search for files from user/group/shipped directories.
Definition: etcFiles.C:119
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:934
void addDimensionedConstantObject(const char *name, simpleRegIOobject *)
Register DimensionedConstant read/write object.
Definition: debug.C:311
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:111
Functions to search &#39;etc&#39; directories for configuration files etc.
dictionary & infoSwitches()
The InfoSwitches sub-dictionary in the central controlDict.
Definition: debug.C:166
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
int debugSwitch(const char *name, const int defaultValue=0)
Lookup debug switch or add default value.
Definition: debug.C:178
void listSwitches(const bool unset)
List debug switches.
Definition: debug.C:456
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:156
void listRegisteredSwitches(const bool unset)
List registered debug switches.
Definition: debug.C:468
simpleObjectRegistry & infoObjects()
Get access to registered info switch objects.
Definition: debug.C:349
Input from file stream.
Definition: IFstream.H:81
simpleObjectRegistry & dimensionSetObjects()
Get access to registered dimensionSets switch objects.
Definition: debug.C:371
Template functions to aid in the implementation of demand driven data.
Object registry for simpleRegIOobject. Maintains ordering.
Input from memory buffer stream.
Definition: IStringStream.H:49
simpleObjectRegistry & dimensionedConstantObjects()
Get access to registered dimensionedConstant switch objects.
Definition: debug.C:382
List< Key > sortedToc() const
Return the table of contents as a sorted list.
Definition: HashTable.C:217
messageStream Info
bool merge(const dictionary &)
Merge entries from the given dictionary.
Definition: dictionary.C:1343
dictionary & optimisationSwitches()
The OptimisationSwitches sub-dictionary in the central controlDict.
Definition: debug.C:172
void addDimensionSetObject(const char *name, simpleRegIOobject *obj)
Register DimensionSets read/write object.
Definition: debug.C:286
void addOptimisationObject(const char *name, simpleRegIOobject *obj)
Register optimisation switch read/write object.
Definition: debug.C:261
dictionary & debugSwitches()
The DebugSwitches sub-dictionary in the central controlDict.
Definition: debug.C:160
void addDebugObject(const char *name, simpleRegIOobject *obj)
Register debug switch read/write object.
Definition: debug.C:218
dictionary & controlDict()
The central control dictionary.
Definition: debug.C:94
void deleteDemandDrivenData(DataPtr &dataPtr)
wordList sortedToc() const
Return the sorted table of contents.
Definition: dictionary.C:1032
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:65
#define SafeFatalIOErrorInFunction(ios, msg)
Report an error message using Foam::FatalIOError.
Definition: error.H:346