printDictionary.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) 2026 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 \*---------------------------------------------------------------------------*/
25 
26 #include "printDictionary.H"
27 #include "dictionary.H"
28 #include "stringOps.H"
29 
30 // * * * * * * * * * * * * Private Static Data Members * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  HashTable<Tuple2<const dictionary*, label>, fileName, Hash<fileName>>
35  printDictionary::dictNameToDictPtrAndCount_;
36 
37  HashTable<tmpNrc<dictionary>, const dictionary*, Hash<void*>>
38  printDictionary::dictPtrToDefaults_;
39 }
40 
41 
42 // * * * * * * * * * * * Private Static Member Functions * * * * * * * * * * //
43 
44 void Foam::printDictionary::removeDefaults
45 (
46  const dictionary* dictPtr,
47  HashSet<const dictionary*, Hash<void*>>& removeDictPtrs
48 )
49 {
50  typedef
51  HashTable<tmpNrc<dictionary>, const dictionary*, Hash<void*>>
52  dictPtrToDefaultsType;
53 
54  if (!dictPtrToDefaults_.found(dictPtr)) return;
55 
56  const dictionary& defaults = dictPtrToDefaults_[dictPtr]();
57 
58  forAllConstIter(dictionary, defaults, iter)
59  {
60  if (!iter().isDict()) continue;
61 
62  const dictionary& subDefaults = iter().dict();
63 
64  forAllConstIter(dictPtrToDefaultsType, dictPtrToDefaults_, jter)
65  {
66  if (&jter()() == &subDefaults)
67  {
68  removeDefaults(jter.key(), removeDictPtrs);
69  break;
70  }
71  }
72  }
73 
74  removeDictPtrs.insert(dictPtr);
75 }
76 
77 
78 void Foam::printDictionary::removeDefaults(const dictionary* dictPtr)
79 {
80  typedef
81  HashSet<const dictionary*, Hash<void*>>
82  removeDictPtrsType;
83 
84  removeDictPtrsType removeDictPtrs;
85 
86  removeDefaults(dictPtr, removeDictPtrs);
87 
88  forAllConstIter(removeDictPtrsType, removeDictPtrs, iter)
89  {
90  dictPtrToDefaults_.erase(iter.key());
91  }
92 }
93 
94 
95 void Foam::printDictionary::setDefaults(const dictionary& dict)
96 {
97  removeDefaults(&dict);
98 
99  dictPtrToDefaults_.set
100  (
101  &dict,
102  tmpNrc<dictionary>(new dictionary(dict.parent(), dictionary()))
103  );
104 
105  setSubDefaults(dict, printDictionary::defaults(dict));
106 }
107 
108 
109 void Foam::printDictionary::setSubDefaults
110 (
111  const dictionary& dict,
112  dictionary& defaults
113 )
114 {
115  forAllConstIter(dictionary, dict, iter)
116  {
117  if (!iter().isDict()) continue;
118 
119  const dictionary& subDict = iter().dict();
120 
121  defaults.set(iter().keyword(), dictionary());
122 
123  dictionary& subDefaults = defaults.subDict(iter().keyword());
124 
125  if (!dictPtrToDefaults_.found(&subDict))
126  {
127  dictPtrToDefaults_.set
128  (
129  &subDict,
130  tmpNrc<dictionary>(subDefaults)
131  );
132  }
133 
134  setSubDefaults(subDict, subDefaults);
135  }
136 }
137 
138 
139 void Foam::printDictionary::print
140 (
141  const dictionary& dict,
142  const dictionary& defaults
143 )
144 {
146 
147  forAllConstIter(dictionary, dict, iter)
148  {
149  if (!iter().isDict())
150  {
151  Info<< iter();
152  }
153  else if (defaults.isDict(iter().keyword()))
154  {
155  Info<< indent << iter().keyword();
156  print(iter().dict(), defaults.subDict(iter().keyword()));
157  }
158  else
159  {
160  Info<< indent << iter().keyword()
161  << nl << indent << token::BEGIN_BLOCK << nl << incrIndent;
162 
163  iter().dict().write(Info, false);
164 
165  OStringStream oss;
166  oss << "/* #print must be specified after the " << iter().keyword()
167  << " sub-dictionary in order for its defaults to be printed */";
168 
169  Info<<
171  (
172  oss.str(),
173  80,
174  Info().indentSize()
175  ).c_str() << endl
176  << decrIndent << indent << token::END_BLOCK << nl;
177  }
178  }
179 
180  label nDefaultsEntries = 0;
181  forAllConstIter(dictionary, defaults, iter)
182  {
183  nDefaultsEntries += !iter().isDict();
184  }
185 
186  if (nDefaultsEntries) Info<< indent << "/* defaults */" << endl;
187 
188  forAllConstIter(dictionary, defaults, iter)
189  {
190  if (!iter().isDict())
191  {
192  Info<< iter();
193  }
194  }
195 
197 }
198 
199 
200 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
201 
202 void Foam::printDictionary::add(const dictionary& dict)
203 {
204  if (dictNameToDictPtrAndCount_.found(dict.name()))
205  {
206  dicts_.append(&dict);
207  dictNames_.append(fileName::null);
208 
209  dictNameToDictPtrAndCount_[dict.name()].second() ++;
210 
211  setDefaults(dict);
212  }
213 }
214 
215 
216 void Foam::printDictionary::add(const fileName& dictName)
217 {
218  dicts_.append(nullptr);
219  dictNames_.append(dictName);
220 
221  dictNameToDictPtrAndCount_.set
222  (
223  dictName,
224  Tuple2<const dictionary*, label>(nullptr, 1)
225  );
226 }
227 
228 
229 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
230 
231 Foam::printDictionary::printDictionary()
232 :
233  dicts_(),
234  dictNames_()
235 {
236  Info<< incrIndent;
237 }
238 
239 
240 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
241 
243 {
244  forAll(dicts_, i)
245  {
246  const word& dictName =
247  dicts_.set(i) ? dicts_[i].name() : dictNames_[i];
248 
249  if (!dictNameToDictPtrAndCount_.found(dictName)) continue;
250 
251  Tuple2<const dictionary*, label>& dictPtrAndCount =
252  dictNameToDictPtrAndCount_[dictName];
253  const dictionary* dictPtr = dictPtrAndCount.first();
254  label& count = dictPtrAndCount.second();
255 
256  count --;
257 
258  if (!dictPtrToDefaults_.found(dictPtr)) continue;
259 
260  if (dictPtr && count == 0 && dictPtrToDefaults_[dictPtr].isTmp())
261  {
262  Info<< indent << dictPtr->name().relativePath().c_str();
263 
264  print(*dictPtr, dictPtrToDefaults_[dictPtr]());
265  }
266  }
267 
268  Info<< decrIndent;
269 }
270 
271 
272 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
273 
275 {
276  if (dictNameToDictPtrAndCount_.found(dict.name()))
277  {
278  setDefaults(dict);
279  }
280 
281  const label count =
282  dictNameToDictPtrAndCount_.found(dict.name())
283  ? dictNameToDictPtrAndCount_[dict.name()].second()
284  : 0;
285 
286  dictNameToDictPtrAndCount_.set
287  (
288  dict.name(),
290  );
291 }
292 
293 
294 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
virtual Ostream & write(const token &)
Write token.
Definition: Ostream.C:51
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:66
const Type2 & second() const
Return second.
Definition: Tuple2.H:131
const Type1 & first() const
Return first.
Definition: Tuple2.H:119
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:111
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
const dictionary & parent() const
Return the parent dictionary.
Definition: dictionary.H:348
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:778
static const fileName null
An empty fileName.
Definition: fileName.H:97
string relativePath() const
Return file name part relative to FOAM_CASE.
Definition: fileName.C:229
static dictionary & defaults(const dictionary &dict)
Return the dictionary to add defaults to for a given dictionary.
~printDictionary()
Destructor.
static void set(const dictionary &dict)
Set the dictionary to be printed.
@ BEGIN_BLOCK
Definition: token.H:114
@ END_BLOCK
Definition: token.H:115
A class for handling words, derived from string.
Definition: word.H:63
string breakIntoIndentedLines(const string &str, const string::size_type nLength=80, const string::size_type nIndent=0)
Break a string up into indented lines.
Definition: stringOps.C:963
Namespace for OpenFOAM.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:272
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:265
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:243
static const char nl
Definition: Ostream.H:297
dictionary dict