dictionary.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-2019 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 "dictionary.H"
27 #include "primitiveEntry.H"
28 #include "dictionaryEntry.H"
29 #include "regExp.H"
30 #include "OSHA1stream.H"
31 #include "DynamicList.H"
32 
33 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(dictionary, 0);
38  const dictionary dictionary::null;
39 
40  bool dictionary::writeOptionalEntries
41  (
42  debug::infoSwitch("writeOptionalEntries", 0)
43  );
44 }
45 
46 
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
48 
49 const Foam::entry* Foam::dictionary::lookupScopedSubEntryPtr
50 (
51  const word& keyword,
52  bool recursive,
53  bool patternMatch
54 ) const
55 {
56  string::size_type dotPos = keyword.find('.');
57 
58  if (dotPos == string::npos)
59  {
60  // Non-scoped lookup
61  return lookupEntryPtr(keyword, recursive, patternMatch);
62  }
63  else
64  {
65  if (dotPos == 0)
66  {
67  // Starting with a '.'. Go up for every 2nd '.' found
68 
69  const dictionary* dictPtr = this;
70 
71  string::size_type begVar = dotPos + 1;
72  string::const_iterator iter = keyword.begin() + begVar;
73  string::size_type endVar = begVar;
74  while (iter != keyword.end() && *iter == '.')
75  {
76  ++iter;
77  ++endVar;
78 
79  // Go to parent
80  if (&dictPtr->parent_ == &dictionary::null)
81  {
83  (
84  *this
85  ) << "No parent of current dictionary"
86  << " when searching for "
87  << keyword.substr(begVar, keyword.size()-begVar)
88  << exit(FatalIOError);
89  }
90  dictPtr = &dictPtr->parent_;
91  }
92 
93  return dictPtr->lookupScopedSubEntryPtr
94  (
95  keyword.substr(endVar),
96  false,
97  patternMatch
98  );
99  }
100  else
101  {
102  // Extract the first word
103  word firstWord = keyword.substr(0, dotPos);
104 
105  const entry* entPtr = lookupScopedSubEntryPtr
106  (
107  firstWord,
108  false, // recursive
109  patternMatch
110  );
111 
112  if (!entPtr)
113  {
114  // Fall back to finding key with '.' so e.g. if keyword is
115  // a.b.c.d it would try
116  // a.b, a.b.c, a.b.c.d
117 
118  string::size_type nextDotPos = keyword.find
119  (
120  '.',
121  dotPos+1
122  );
123 
124  while (true)
125  {
126  const entry* subEntPtr = lookupEntryPtr
127  (
128  keyword.substr(0, nextDotPos),
129  false, // recursive,
130  patternMatch
131  );
132  if (nextDotPos == string::npos)
133  {
134  // Parsed the whole word. Return entry or null.
135  return subEntPtr;
136  }
137 
138  if (subEntPtr && subEntPtr->isDict())
139  {
140  return subEntPtr->dict().lookupScopedSubEntryPtr
141  (
142  keyword.substr
143  (
144  nextDotPos,
145  keyword.size()-nextDotPos
146  ),
147  false,
148  patternMatch
149  );
150  }
151 
152  nextDotPos = keyword.find('.', nextDotPos+1);
153  }
154  }
155 
156  if (entPtr->isDict())
157  {
158  return entPtr->dict().lookupScopedSubEntryPtr
159  (
160  keyword.substr(dotPos, keyword.size()-dotPos),
161  false,
162  patternMatch
163  );
164  }
165  else
166  {
167  return nullptr;
168  }
169  }
170  }
171 }
172 
173 
174 bool Foam::dictionary::findInPatterns
175 (
176  const bool patternMatch,
177  const word& Keyword,
179  DLList<autoPtr<regExp>>::const_iterator& reLink
180 ) const
181 {
182  if (patternEntries_.size())
183  {
184  while (wcLink != patternEntries_.end())
185  {
186  if
187  (
188  patternMatch
189  ? reLink()->match(Keyword)
190  : wcLink()->keyword() == Keyword
191  )
192  {
193  return true;
194  }
195 
196  ++reLink;
197  ++wcLink;
198  }
199  }
200 
201  return false;
202 }
203 
204 
205 bool Foam::dictionary::findInPatterns
206 (
207  const bool patternMatch,
208  const word& Keyword,
209  DLList<entry*>::iterator& wcLink,
210  DLList<autoPtr<regExp>>::iterator& reLink
211 )
212 {
213  if (patternEntries_.size())
214  {
215  while (wcLink != patternEntries_.end())
216  {
217  if
218  (
219  patternMatch
220  ? reLink()->match(Keyword)
221  : wcLink()->keyword() == Keyword
222  )
223  {
224  return true;
225  }
226 
227  ++reLink;
228  ++wcLink;
229  }
230  }
231 
232  return false;
233 }
234 
235 
236 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
237 
239 :
240  parent_(dictionary::null)
241 {}
242 
243 
245 :
246  dictionaryName(name),
247  parent_(dictionary::null)
248 {}
249 
250 
252 (
253  const dictionary& parentDict,
254  const dictionary& dict
255 )
256 :
257  dictionaryName(dict.name()),
258  IDLList<entry>(dict, *this),
259  parent_(parentDict)
260 {
261  forAllIter(IDLList<entry>, *this, iter)
262  {
263  hashedEntries_.insert(iter().keyword(), &iter());
264 
265  if (iter().keyword().isPattern())
266  {
267  patternEntries_.insert(&iter());
268  patternRegexps_.insert
269  (
270  autoPtr<regExp>(new regExp(iter().keyword()))
271  );
272  }
273  }
274 }
275 
276 
278 (
279  const dictionary& dict
280 )
281 :
282  dictionaryName(dict.name()),
283  IDLList<entry>(dict, *this),
284  parent_(dictionary::null)
285 {
286  forAllIter(IDLList<entry>, *this, iter)
287  {
288  hashedEntries_.insert(iter().keyword(), &iter());
289 
290  if (iter().keyword().isPattern())
291  {
292  patternEntries_.insert(&iter());
293  patternRegexps_.insert
294  (
295  autoPtr<regExp>(new regExp(iter().keyword()))
296  );
297  }
298  }
299 }
300 
301 
303 (
304  dictionary&& dict
305 )
306 :
307  dictionaryName(move(dict.name())),
308  IDLList<entry>(move(dict)),
309  hashedEntries_(move(dict.hashedEntries_)),
310  parent_(dict.parent_),
311  patternEntries_(move(dict.patternEntries_)),
312  patternRegexps_(move(dict.patternRegexps_))
313 {}
314 
315 
317 (
318  const dictionary* dictPtr
319 )
320 :
321  parent_(dictionary::null)
322 {
323  if (dictPtr)
324  {
325  operator=(*dictPtr);
326  }
327 }
328 
329 
331 (
332  const dictionary& parentDict,
333  dictionary&& dict
334 )
335 :
336  dictionaryName(move(dict.name())),
337  IDLList<entry>(move(dict)),
338  hashedEntries_(move(dict.hashedEntries_)),
339  parent_(parentDict),
340  patternEntries_(move(dict.patternEntries_)),
341  patternRegexps_(move(dict.patternRegexps_))
342 {
343  name() = parentDict.name() + '.' + name();
344 }
345 
346 
348 {
349  return autoPtr<dictionary>(new dictionary(*this));
350 }
351 
352 
353 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
354 
356 {
357  // cerr<< "~dictionary() " << name() << " " << long(this) << std::endl;
358 }
359 
360 
361 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
362 
364 {
365  const dictionary& p = parent();
366 
367  if (&p != this && !p.name().empty())
368  {
369  return p.topDict();
370  }
371  else
372  {
373  return *this;
374  }
375 }
376 
377 
379 {
380  if (size())
381  {
382  return first()->startLineNumber();
383  }
384  else
385  {
386  return -1;
387  }
388 }
389 
390 
392 {
393  if (size())
394  {
395  return last()->endLineNumber();
396  }
397  else
398  {
399  return -1;
400  }
401 }
402 
403 
405 {
406  OSHA1stream os;
407 
408  // Process entries
409  forAllConstIter(IDLList<entry>, *this, iter)
410  {
411  os << *iter;
412  }
413 
414  return os.digest();
415 }
416 
417 
419 {
420  // Serialize dictionary into a string
421  OStringStream os;
422  write(os, false);
423  IStringStream is(os.str());
424 
425  // Parse string as tokens
427  token t;
428  while (is.read(t))
429  {
430  tokens.append(t);
431  }
432 
433  return tokenList(move(tokens));
434 }
435 
436 
438 (
439  const word& keyword,
440  bool recursive,
441  bool patternMatch
442 ) const
443 {
444  if (hashedEntries_.found(keyword))
445  {
446  return true;
447  }
448  else
449  {
450  if (patternMatch && patternEntries_.size())
451  {
453  patternEntries_.begin();
455  patternRegexps_.begin();
456 
457  // Find in patterns using regular expressions only
458  if (findInPatterns(patternMatch, keyword, wcLink, reLink))
459  {
460  return true;
461  }
462  }
463 
464  if (recursive && &parent_ != &dictionary::null)
465  {
466  return parent_.found(keyword, recursive, patternMatch);
467  }
468  else
469  {
470  return false;
471  }
472  }
473 }
474 
475 
477 (
478  const word& keyword,
479  bool recursive,
480  bool patternMatch
481 ) const
482 {
483  HashTable<entry*>::const_iterator iter = hashedEntries_.find(keyword);
484 
485  if (iter == hashedEntries_.end())
486  {
487  if (patternMatch && patternEntries_.size())
488  {
490  patternEntries_.begin();
492  patternRegexps_.begin();
493 
494  // Find in patterns using regular expressions only
495  if (findInPatterns(patternMatch, keyword, wcLink, reLink))
496  {
497  return wcLink();
498  }
499  }
500 
501  if (recursive && &parent_ != &dictionary::null)
502  {
503  return parent_.lookupEntryPtr(keyword, recursive, patternMatch);
504  }
505  else
506  {
507  return nullptr;
508  }
509  }
510 
511  return iter();
512 }
513 
514 
516 (
517  const word& keyword,
518  bool recursive,
519  bool patternMatch
520 )
521 {
522  HashTable<entry*>::iterator iter = hashedEntries_.find(keyword);
523 
524  if (iter == hashedEntries_.end())
525  {
526  if (patternMatch && patternEntries_.size())
527  {
528  DLList<entry*>::iterator wcLink =
529  patternEntries_.begin();
531  patternRegexps_.begin();
532 
533  // Find in patterns using regular expressions only
534  if (findInPatterns(patternMatch, keyword, wcLink, reLink))
535  {
536  return wcLink();
537  }
538  }
539 
540  if (recursive && &parent_ != &dictionary::null)
541  {
542  return const_cast<dictionary&>(parent_).lookupEntryPtr
543  (
544  keyword,
545  recursive,
546  patternMatch
547  );
548  }
549  else
550  {
551  return nullptr;
552  }
553  }
554 
555  return iter();
556 }
557 
558 
560 (
561  const word& keyword,
562  bool recursive,
563  bool patternMatch
564 ) const
565 {
566  const entry* entryPtr = lookupEntryPtr(keyword, recursive, patternMatch);
567 
568  if (entryPtr == nullptr)
569  {
571  (
572  *this
573  ) << "keyword " << keyword << " is undefined in dictionary "
574  << name()
575  << exit(FatalIOError);
576  }
577 
578  return *entryPtr;
579 }
580 
581 
583 (
584  const word& keyword,
585  bool recursive,
586  bool patternMatch
587 ) const
588 {
589  return lookupEntry(keyword, recursive, patternMatch).stream();
590 }
591 
592 
594 (
595  const word& keyword,
596  bool recursive,
597  bool patternMatch
598 ) const
599 {
600  if (keyword[0] == ':')
601  {
602  // Go up to top level
603  const dictionary* dictPtr = this;
604  while (&dictPtr->parent_ != &dictionary::null)
605  {
606  dictPtr = &dictPtr->parent_;
607  }
608 
609  // At top. Recurse to find entries
610  return dictPtr->lookupScopedSubEntryPtr
611  (
612  keyword.substr(1, keyword.size()-1),
613  false,
614  patternMatch
615  );
616  }
617  else
618  {
619  return lookupScopedSubEntryPtr
620  (
621  keyword,
622  recursive,
623  patternMatch
624  );
625  }
626 }
627 
628 
630 {
631  word varName = keyword(1, keyword.size()-1);
632 
633  // Lookup the variable name in the given dictionary
634  const entry* ePtr = lookupScopedEntryPtr(varName, true, true);
635 
636  // If defined insert its entries into this dictionary
637  if (ePtr != nullptr)
638  {
639  const dictionary& addDict = ePtr->dict();
640 
641  forAllConstIter(IDLList<entry>, addDict, iter)
642  {
643  add(iter());
644  }
645 
646  return true;
647  }
648 
649  return false;
650 }
651 
652 
653 bool Foam::dictionary::isDict(const word& keyword) const
654 {
655  // Find non-recursive with patterns
656  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
657 
658  if (entryPtr)
659  {
660  return entryPtr->isDict();
661  }
662  else
663  {
664  return false;
665  }
666 }
667 
668 
670 {
671  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
672 
673  if (entryPtr)
674  {
675  return &entryPtr->dict();
676  }
677  else
678  {
679  return nullptr;
680  }
681 }
682 
683 
685 {
686  entry* entryPtr = lookupEntryPtr(keyword, false, true);
687 
688  if (entryPtr)
689  {
690  return &entryPtr->dict();
691  }
692  else
693  {
694  return nullptr;
695  }
696 }
697 
698 
699 const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const
700 {
701  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
702 
703  if (entryPtr == nullptr)
704  {
706  (
707  *this
708  ) << "keyword " << keyword << " is undefined in dictionary "
709  << name()
710  << exit(FatalIOError);
711  }
712  return entryPtr->dict();
713 }
714 
715 
717 {
718  entry* entryPtr = lookupEntryPtr(keyword, false, true);
719 
720  if (entryPtr == nullptr)
721  {
723  (
724  *this
725  ) << "keyword " << keyword << " is undefined in dictionary "
726  << name()
727  << exit(FatalIOError);
728  }
729  return entryPtr->dict();
730 }
731 
732 
734 (
735  const word& keyword,
736  const bool mustRead
737 ) const
738 {
739  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
740 
741  if (entryPtr == nullptr)
742  {
743  if (mustRead)
744  {
746  (
747  *this
748  ) << "keyword " << keyword << " is undefined in dictionary "
749  << name()
750  << exit(FatalIOError);
751  return entryPtr->dict();
752  }
753  else
754  {
755  return dictionary(*this, dictionary(name() + '.' + keyword));
756  }
757  }
758  else
759  {
760  return entryPtr->dict();
761  }
762 }
763 
764 
766 (
767  const word& keyword
768 ) const
769 {
770  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
771 
772  if (entryPtr)
773  {
774  return entryPtr->dict();
775  }
776  else
777  {
778  return *this;
779  }
780 }
781 
782 
784 {
785  wordList keys(size());
786 
787  label nKeys = 0;
788  forAllConstIter(IDLList<entry>, *this, iter)
789  {
790  keys[nKeys++] = iter().keyword();
791  }
792 
793  return keys;
794 }
795 
796 
798 {
799  return hashedEntries_.sortedToc();
800 }
801 
802 
804 {
805  List<keyType> keys(size());
806 
807  label nKeys = 0;
808  forAllConstIter(IDLList<entry>, *this, iter)
809  {
810  if (iter().keyword().isPattern() ? patterns : !patterns)
811  {
812  keys[nKeys++] = iter().keyword();
813  }
814  }
815  keys.setSize(nKeys);
816 
817  return keys;
818 }
819 
820 
821 bool Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
822 {
823  HashTable<entry*>::iterator iter = hashedEntries_.find
824  (
825  entryPtr->keyword()
826  );
827 
828  if (mergeEntry && iter != hashedEntries_.end())
829  {
830  // Merge dictionary with dictionary
831  if (iter()->isDict() && entryPtr->isDict())
832  {
833  iter()->dict().merge(entryPtr->dict());
834  delete entryPtr;
835 
836  return true;
837  }
838  else
839  {
840  // Replace existing dictionary with entry or vice versa
841  IDLList<entry>::replace(iter(), entryPtr);
842  delete iter();
843  hashedEntries_.erase(iter);
844 
845  if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
846  {
847  entryPtr->name() = name() + '.' + entryPtr->keyword();
848 
849  if (entryPtr->keyword().isPattern())
850  {
851  patternEntries_.insert(entryPtr);
852  patternRegexps_.insert
853  (
854  autoPtr<regExp>(new regExp(entryPtr->keyword()))
855  );
856  }
857 
858  return true;
859  }
860  else
861  {
862  IOWarningInFunction((*this))
863  << "problem replacing entry "<< entryPtr->keyword()
864  << " in dictionary " << name() << endl;
865 
866  IDLList<entry>::remove(entryPtr);
867  delete entryPtr;
868  return false;
869  }
870  }
871  }
872 
873  if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
874  {
875  entryPtr->name() = name() + '.' + entryPtr->keyword();
876  IDLList<entry>::append(entryPtr);
877 
878  if (entryPtr->keyword().isPattern())
879  {
880  patternEntries_.insert(entryPtr);
881  patternRegexps_.insert
882  (
883  autoPtr<regExp>(new regExp(entryPtr->keyword()))
884  );
885  }
886 
887  return true;
888  }
889  else
890  {
891  IOWarningInFunction((*this))
892  << "attempt to add entry "<< entryPtr->keyword()
893  << " which already exists in dictionary " << name()
894  << endl;
895 
896  delete entryPtr;
897  return false;
898  }
899 }
900 
901 
902 void Foam::dictionary::add(const entry& e, bool mergeEntry)
903 {
904  add(e.clone(*this).ptr(), mergeEntry);
905 }
906 
907 
908 void Foam::dictionary::add(const keyType& k, const word& w, bool overwrite)
909 {
910  add(new primitiveEntry(k, token(w)), overwrite);
911 }
912 
913 
915 (
916  const keyType& k,
917  const Foam::string& s,
918  bool overwrite
919 )
920 {
921  add(new primitiveEntry(k, token(s)), overwrite);
922 }
923 
924 
925 void Foam::dictionary::add(const keyType& k, const label l, bool overwrite)
926 {
927  add(new primitiveEntry(k, token(l)), overwrite);
928 }
929 
930 
931 void Foam::dictionary::add(const keyType& k, const scalar s, bool overwrite)
932 {
933  add(new primitiveEntry(k, token(s)), overwrite);
934 }
935 
936 
938 (
939  const keyType& k,
940  const dictionary& d,
941  bool mergeEntry
942 )
943 {
944  add(new dictionaryEntry(k, *this, d), mergeEntry);
945 }
946 
947 
949 {
950  entry* existingPtr = lookupEntryPtr(entryPtr->keyword(), false, true);
951 
952  // Clear dictionary so merge acts like overwrite
953  if (existingPtr && existingPtr->isDict())
954  {
955  existingPtr->dict().clear();
956  }
957  add(entryPtr, true);
958 }
959 
960 
962 {
963  set(e.clone(*this).ptr());
964 }
965 
966 
967 void Foam::dictionary::set(const keyType& k, const dictionary& d)
968 {
969  set(new dictionaryEntry(k, *this, d));
970 }
971 
972 
973 bool Foam::dictionary::remove(const word& Keyword)
974 {
975  HashTable<entry*>::iterator iter = hashedEntries_.find(Keyword);
976 
977  if (iter != hashedEntries_.end())
978  {
979  // Delete from patterns first
980  DLList<entry*>::iterator wcLink =
981  patternEntries_.begin();
983  patternRegexps_.begin();
984 
985  // Find in pattern using exact match only
986  if (findInPatterns(false, Keyword, wcLink, reLink))
987  {
988  patternEntries_.remove(wcLink);
989  patternRegexps_.remove(reLink);
990  }
991 
992  IDLList<entry>::remove(iter());
993  delete iter();
994  hashedEntries_.erase(iter);
995 
996  return true;
997  }
998  else
999  {
1000  return false;
1001  }
1002 }
1003 
1004 
1007  const keyType& oldKeyword,
1008  const keyType& newKeyword,
1009  bool forceOverwrite
1010 )
1011 {
1012  // No change
1013  if (oldKeyword == newKeyword)
1014  {
1015  return false;
1016  }
1017 
1018  HashTable<entry*>::iterator iter = hashedEntries_.find(oldKeyword);
1019 
1020  // oldKeyword not found - do nothing
1021  if (iter == hashedEntries_.end())
1022  {
1023  return false;
1024  }
1025 
1026  if (iter()->keyword().isPattern())
1027  {
1029  (
1030  *this
1031  ) << "Old keyword "<< oldKeyword
1032  << " is a pattern."
1033  << "Pattern replacement not yet implemented."
1034  << exit(FatalIOError);
1035  }
1036 
1037 
1038  HashTable<entry*>::iterator iter2 = hashedEntries_.find(newKeyword);
1039 
1040  // newKeyword already exists
1041  if (iter2 != hashedEntries_.end())
1042  {
1043  if (forceOverwrite)
1044  {
1045  if (iter2()->keyword().isPattern())
1046  {
1047  // Delete from patterns first
1048  DLList<entry*>::iterator wcLink =
1049  patternEntries_.begin();
1051  patternRegexps_.begin();
1052 
1053  // Find in patterns using exact match only
1054  if (findInPatterns(false, iter2()->keyword(), wcLink, reLink))
1055  {
1056  patternEntries_.remove(wcLink);
1057  patternRegexps_.remove(reLink);
1058  }
1059  }
1060 
1061  IDLList<entry>::replace(iter2(), iter());
1062  delete iter2();
1063  hashedEntries_.erase(iter2);
1064 
1065  }
1066  else
1067  {
1069  (
1070  *this
1071  ) << "cannot rename keyword "<< oldKeyword
1072  << " to existing keyword " << newKeyword
1073  << " in dictionary " << name() << endl;
1074  return false;
1075  }
1076  }
1077 
1078  // Change name and HashTable, but leave DL-List untouched
1079  iter()->keyword() = newKeyword;
1080  iter()->name() = name() + '.' + newKeyword;
1081  hashedEntries_.erase(oldKeyword);
1082  hashedEntries_.insert(newKeyword, iter());
1083 
1084  if (newKeyword.isPattern())
1085  {
1086  patternEntries_.insert(iter());
1087  patternRegexps_.insert
1088  (
1089  autoPtr<regExp>(new regExp(newKeyword))
1090  );
1091  }
1092 
1093  return true;
1094 }
1095 
1096 
1098 {
1099  // Check for assignment to self
1100  if (this == &dict)
1101  {
1102  FatalIOErrorInFunction(*this)
1103  << "attempted merge to self for dictionary " << name()
1104  << abort(FatalIOError);
1105  }
1106 
1107  bool changed = false;
1108 
1109  forAllConstIter(IDLList<entry>, dict, iter)
1110  {
1111  HashTable<entry*>::iterator fnd = hashedEntries_.find(iter().keyword());
1112 
1113  if (fnd != hashedEntries_.end())
1114  {
1115  // Recursively merge sub-dictionaries
1116  // TODO: merge without copying
1117  if (fnd()->isDict() && iter().isDict())
1118  {
1119  if (fnd()->dict().merge(iter().dict()))
1120  {
1121  changed = true;
1122  }
1123  }
1124  else
1125  {
1126  add(iter().clone(*this).ptr(), true);
1127  changed = true;
1128  }
1129  }
1130  else
1131  {
1132  // Not found - just add
1133  add(iter().clone(*this).ptr());
1134  changed = true;
1135  }
1136  }
1137 
1138  return changed;
1139 }
1140 
1141 
1143 {
1145  hashedEntries_.clear();
1146  patternEntries_.clear();
1147  patternRegexps_.clear();
1148 }
1149 
1150 
1152 {
1153  // Changing parents probably doesn't make much sense,
1154  // but what about the names?
1155  name() = dict.name();
1156 
1158  hashedEntries_.transfer(dict.hashedEntries_);
1159  patternEntries_.transfer(dict.patternEntries_);
1160  patternRegexps_.transfer(dict.patternRegexps_);
1161 }
1162 
1163 
1164 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1165 
1167 {
1168  return lookup(keyword);
1169 }
1170 
1171 
1173 {
1174  // Check for assignment to self
1175  if (this == &rhs)
1176  {
1177  FatalIOErrorInFunction(*this)
1178  << "attempted assignment to self for dictionary " << name()
1179  << abort(FatalIOError);
1180  }
1181 
1182  name() = rhs.name();
1183  clear();
1184 
1185  // Create clones of the entries in the given dictionary
1186  // resetting the parentDict to this dictionary
1187 
1188  forAllConstIter(IDLList<entry>, rhs, iter)
1189  {
1190  add(iter().clone(*this).ptr());
1191  }
1192 }
1193 
1194 
1196 {
1197  // Check for assignment to self
1198  if (this == &rhs)
1199  {
1200  FatalIOErrorInFunction(*this)
1201  << "attempted assignment to self for dictionary " << name()
1202  << abort(FatalIOError);
1203  }
1204 
1205  dictionaryName::operator=(move(rhs));
1206  IDLList<entry>::operator=(move(rhs));
1207  hashedEntries_ = move(rhs.hashedEntries_);
1208  patternEntries_ = move(rhs.patternEntries_);
1209  patternRegexps_ = move(rhs.patternRegexps_);
1210 }
1211 
1212 
1214 {
1215  // Check for assignment to self
1216  if (this == &rhs)
1217  {
1218  FatalIOErrorInFunction(*this)
1219  << "attempted addition assignment to self for dictionary " << name()
1220  << abort(FatalIOError);
1221  }
1222 
1223  forAllConstIter(IDLList<entry>, rhs, iter)
1224  {
1225  add(iter().clone(*this).ptr());
1226  }
1227 }
1228 
1229 
1231 {
1232  // Check for assignment to self
1233  if (this == &rhs)
1234  {
1235  FatalIOErrorInFunction(*this)
1236  << "attempted assignment to self for dictionary " << name()
1237  << abort(FatalIOError);
1238  }
1239 
1240  forAllConstIter(IDLList<entry>, rhs, iter)
1241  {
1242  if (!found(iter().keyword()))
1243  {
1244  add(iter().clone(*this).ptr());
1245  }
1246  }
1247 }
1248 
1249 
1251 {
1252  // Check for assignment to self
1253  if (this == &rhs)
1254  {
1255  FatalIOErrorInFunction(*this)
1256  << "attempted assignment to self for dictionary " << name()
1257  << abort(FatalIOError);
1258  }
1259 
1260  forAllConstIter(IDLList<entry>, rhs, iter)
1261  {
1262  set(iter().clone(*this).ptr());
1263  }
1264 }
1265 
1266 
1267 /* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
1268 
1269 Foam::dictionary Foam::operator+
1271  const dictionary& dict1,
1272  const dictionary& dict2
1273 )
1274 {
1275  dictionary sum(dict1);
1276  sum += dict2;
1277  return sum;
1278 }
1279 
1280 
1281 Foam::dictionary Foam::operator|
1283  const dictionary& dict1,
1284  const dictionary& dict2
1285 )
1286 {
1287  dictionary sum(dict1);
1288  sum |= dict2;
1289  return sum;
1290 }
1291 
1292 
1293 // ************************************************************************* //
Template class for intrusive linked lists.
Definition: ILList.H:50
void write(Ostream &, const bool subDict=true) const
Write dictionary, normally with sub-dictionary formatting.
Definition: dictionaryIO.C:180
A class for handling keywords in dictionaries.
Definition: keyType.H:64
virtual autoPtr< entry > clone(const dictionary &parentDict) const =0
Construct on freestore as copy with reference to the.
dictionary dict
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:438
bool remove(const word &)
Remove an entry specified by keyword.
Definition: dictionary.C:973
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
A class for handling file names.
Definition: fileName.H:79
label endLineNumber() const
Return line number of last token in dictionary.
Definition: dictionary.C:391
void operator=(const dictionary &)
Definition: dictionary.C:1172
tokenList tokens() const
Return the dictionary as a list of tokens.
Definition: dictionary.C:418
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:477
const keyType & keyword() const
Return keyword.
Definition: entry.H:123
An STL-conforming const_iterator.
Definition: HashTable.H:481
Wrapper around POSIX extended regular expressions.
Definition: regExp.H:61
SHA1Digest digest() const
Return the SHA1 digest of the dictionary contents.
Definition: dictionary.C:404
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
void operator+=(const dictionary &)
Include entries from the given dictionary.
Definition: dictionary.C:1213
List< token > tokenList
List of tokens, used for a IOdictionary entry.
Definition: tokenList.H:42
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
void transfer(ILList< LListBase, T > &)
Transfer the contents of the argument into this List.
Definition: ILList.C:130
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Template class for non-intrusive linked lists.
Definition: LList.H:51
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
dictionaryName()
Construct dictionaryName null.
Definition: dictionary.H:92
static const dictionary null
Null dictionary.
Definition: dictionary.H:223
An STL-conforming const_iterator.
Definition: LList.H:297
A token holds items read from Istream.
Definition: token.H:69
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
The SHA1 message digest.
Definition: SHA1Digest.H:62
An STL-conforming iterator.
Definition: LList.H:246
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
friend class iterator
Definition: LList.H:82
const entry & lookupEntry(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream if present otherwise error.
Definition: dictionary.C:560
The output stream for calculating SHA1 digests.
Definition: OSHA1stream.H:133
T * last()
Return the last entry.
Definition: UILList.H:121
A keyword and a list of tokens is a &#39;dictionaryEntry&#39;.
void transfer(dictionary &)
Transfer the contents of the argument and annul the argument.
Definition: dictionary.C:1151
autoPtr< dictionary > clone() const
Construct and return clone.
Definition: dictionary.C:347
An STL-conforming const_iterator.
Definition: UILList.H:234
const entry * lookupScopedEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:594
wordList toc() const
Return the table of contents.
Definition: dictionary.C:783
int infoSwitch(const char *name, const int defaultValue=0)
Lookup info switch or add default value.
Definition: debug.C:187
bool isDict(const word &) const
Check if entry is a sub-dictionary.
Definition: dictionary.C:653
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:821
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:699
A keyword and a list of tokens is a &#39;primitiveEntry&#39;. An primitiveEntry can be read, written and printed, and the types and values of its tokens analysed.
dictionary()
Construct top-level dictionary null.
Definition: dictionary.C:238
An STL-conforming iterator.
Definition: HashTable.H:426
bool changeKeyword(const keyType &oldKeyword, const keyType &newKeyword, bool forceOverwrite=false)
Change the keyword for an entry,.
Definition: dictionary.C:1006
void operator<<=(const dictionary &)
Unconditionally include entries from the given dictionary.
Definition: dictionary.C:1250
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:111
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
const dictionary & optionalSubDict(const word &) const
Find and return a sub-dictionary if found.
Definition: dictionary.C:766
A class for handling words, derived from string.
Definition: word.H:59
const dictionary & parent() const
Return the parent dictionary.
Definition: dictionary.H:282
void clear()
Clear the contents of the list.
Definition: ILList.C:117
An STL-conforming iterator.
Definition: UILList.H:185
const dictionary & topDict() const
Return the top of the tree.
Definition: dictionary.C:363
T * remove(T *p)
Remove and return element.
Definition: UILList.H:142
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
errorManip< error > abort(error &err)
Definition: errorManip.H:131
rAUs append(new volScalarField(IOobject::groupName("rAU", phase1.name()), 1.0/(U1Eqn.A()+byDt(max(phase1.residualAlpha() - alpha1, scalar(0)) *rho1))))
const dictionary * subDictPtr(const word &) const
Find and return a sub-dictionary pointer if present.
Definition: dictionary.C:669
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:156
defineTypeNameAndDebug(combustionModel, 0)
LList< DLListBase, T > DLList
Definition: DLList.H:43
List< keyType > keys(bool patterns=false) const
Return the list of available keys or patterns.
Definition: dictionary.C:803
friend class const_iterator
Definition: LList.H:85
void setSize(const label)
Reset size of List.
Definition: List.C:281
void operator|=(const dictionary &)
Conditionally include entries from the given dictionary.
Definition: dictionary.C:1230
ITstream & operator[](const word &) const
Find and return entry.
Definition: dictionary.C:1166
void operator=(const dictionaryName &name)
Definition: dictionary.H:142
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:331
Input from memory buffer stream.
Definition: IStringStream.H:49
string str() const
Return the string.
virtual const fileName & name() const =0
Return the dictionary name.
virtual ~dictionary()
Destructor.
Definition: dictionary.C:355
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:948
bool substituteScopedKeyword(const word &keyword)
Substitute the given scoped keyword prepended by &#39;$&#39; with the.
Definition: dictionary.C:629
bool merge(const dictionary &)
Merge entries from the given dictionary.
Definition: dictionary.C:1097
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:98
volScalarField & p
T * first()
Return the first entry.
Definition: UILList.H:109
void clear()
Clear the dictionary.
Definition: dictionary.C:1142
virtual ITstream & stream() const =0
Return token stream if this entry is a primitive entry.
void operator=(const ILList< LListBase, T > &)
Assignment operator.
Definition: ILList.C:140
A class for handling character strings derived from std::string.
Definition: string.H:74
Output to memory buffer stream.
Definition: OStringStream.H:49
label startLineNumber() const
Return line number of first token in dictionary.
Definition: dictionary.C:378
wordList sortedToc() const
Return the sorted table of contents.
Definition: dictionary.C:797
Input token stream.
Definition: ITstream.H:49
dictionary subOrEmptyDict(const word &, const bool mustRead=false) const
Find and return a sub-dictionary as a copy, or.
Definition: dictionary.C:734
Foam::SHA1Digest digest()
Return SHA1::Digest for the data processed until now.
Definition: OSHA1stream.H:178
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:65
bool isPattern() const
Should be treated as a match rather than a literal string.
Definition: keyTypeI.H:76
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:583
IOerror FatalIOError