All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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-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 \*---------------------------------------------------------------------------*/
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  const dictionary* dictPtr
305 )
306 :
307  parent_(dictionary::null)
308 {
309  if (dictPtr)
310  {
311  operator=(*dictPtr);
312  }
313 }
314 
315 
317 (
318  const dictionary& parentDict,
319  const Xfer<dictionary>& dict
320 )
321 :
322  parent_(parentDict)
323 {
324  transfer(dict());
325  name() = parentDict.name() + '.' + name();
326 }
327 
328 
330 (
331  const Xfer<dictionary>& dict
332 )
333 :
334  parent_(dictionary::null)
335 {
336  transfer(dict());
337 }
338 
339 
341 {
342  return autoPtr<dictionary>(new dictionary(*this));
343 }
344 
345 
346 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
347 
349 {
350  // cerr<< "~dictionary() " << name() << " " << long(this) << std::endl;
351 }
352 
353 
354 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
355 
357 {
358  const dictionary& p = parent();
359 
360  if (&p != this && !p.name().empty())
361  {
362  return p.topDict();
363  }
364  else
365  {
366  return *this;
367  }
368 }
369 
370 
372 {
373  if (size())
374  {
375  return first()->startLineNumber();
376  }
377  else
378  {
379  return -1;
380  }
381 }
382 
383 
385 {
386  if (size())
387  {
388  return last()->endLineNumber();
389  }
390  else
391  {
392  return -1;
393  }
394 }
395 
396 
398 {
399  OSHA1stream os;
400 
401  // Process entries
402  forAllConstIter(IDLList<entry>, *this, iter)
403  {
404  os << *iter;
405  }
406 
407  return os.digest();
408 }
409 
410 
412 {
413  // Serialize dictionary into a string
414  OStringStream os;
415  write(os, false);
416  IStringStream is(os.str());
417 
418  // Parse string as tokens
420  token t;
421  while (is.read(t))
422  {
423  tokens.append(t);
424  }
425 
426  return tokenList(tokens.xfer());
427 }
428 
429 
431 (
432  const word& keyword,
433  bool recursive,
434  bool patternMatch
435 ) const
436 {
437  if (hashedEntries_.found(keyword))
438  {
439  return true;
440  }
441  else
442  {
443  if (patternMatch && patternEntries_.size())
444  {
446  patternEntries_.begin();
448  patternRegexps_.begin();
449 
450  // Find in patterns using regular expressions only
451  if (findInPatterns(patternMatch, keyword, wcLink, reLink))
452  {
453  return true;
454  }
455  }
456 
457  if (recursive && &parent_ != &dictionary::null)
458  {
459  return parent_.found(keyword, recursive, patternMatch);
460  }
461  else
462  {
463  return false;
464  }
465  }
466 }
467 
468 
470 (
471  const word& keyword,
472  bool recursive,
473  bool patternMatch
474 ) const
475 {
476  HashTable<entry*>::const_iterator iter = hashedEntries_.find(keyword);
477 
478  if (iter == hashedEntries_.end())
479  {
480  if (patternMatch && patternEntries_.size())
481  {
483  patternEntries_.begin();
485  patternRegexps_.begin();
486 
487  // Find in patterns using regular expressions only
488  if (findInPatterns(patternMatch, keyword, wcLink, reLink))
489  {
490  return wcLink();
491  }
492  }
493 
494  if (recursive && &parent_ != &dictionary::null)
495  {
496  return parent_.lookupEntryPtr(keyword, recursive, patternMatch);
497  }
498  else
499  {
500  return nullptr;
501  }
502  }
503 
504  return iter();
505 }
506 
507 
509 (
510  const word& keyword,
511  bool recursive,
512  bool patternMatch
513 )
514 {
515  HashTable<entry*>::iterator iter = hashedEntries_.find(keyword);
516 
517  if (iter == hashedEntries_.end())
518  {
519  if (patternMatch && patternEntries_.size())
520  {
521  DLList<entry*>::iterator wcLink =
522  patternEntries_.begin();
524  patternRegexps_.begin();
525 
526  // Find in patterns using regular expressions only
527  if (findInPatterns(patternMatch, keyword, wcLink, reLink))
528  {
529  return wcLink();
530  }
531  }
532 
533  if (recursive && &parent_ != &dictionary::null)
534  {
535  return const_cast<dictionary&>(parent_).lookupEntryPtr
536  (
537  keyword,
538  recursive,
539  patternMatch
540  );
541  }
542  else
543  {
544  return nullptr;
545  }
546  }
547 
548  return iter();
549 }
550 
551 
553 (
554  const word& keyword,
555  bool recursive,
556  bool patternMatch
557 ) const
558 {
559  const entry* entryPtr = lookupEntryPtr(keyword, recursive, patternMatch);
560 
561  if (entryPtr == nullptr)
562  {
564  (
565  *this
566  ) << "keyword " << keyword << " is undefined in dictionary "
567  << name()
568  << exit(FatalIOError);
569  }
570 
571  return *entryPtr;
572 }
573 
574 
576 (
577  const word& keyword,
578  bool recursive,
579  bool patternMatch
580 ) const
581 {
582  return lookupEntry(keyword, recursive, patternMatch).stream();
583 }
584 
585 
587 (
588  const word& keyword,
589  bool recursive,
590  bool patternMatch
591 ) const
592 {
593  if (keyword[0] == ':')
594  {
595  // Go up to top level
596  const dictionary* dictPtr = this;
597  while (&dictPtr->parent_ != &dictionary::null)
598  {
599  dictPtr = &dictPtr->parent_;
600  }
601 
602  // At top. Recurse to find entries
603  return dictPtr->lookupScopedSubEntryPtr
604  (
605  keyword.substr(1, keyword.size()-1),
606  false,
607  patternMatch
608  );
609  }
610  else
611  {
612  return lookupScopedSubEntryPtr
613  (
614  keyword,
615  recursive,
616  patternMatch
617  );
618  }
619 }
620 
621 
623 {
624  word varName = keyword(1, keyword.size()-1);
625 
626  // Lookup the variable name in the given dictionary
627  const entry* ePtr = lookupScopedEntryPtr(varName, true, true);
628 
629  // If defined insert its entries into this dictionary
630  if (ePtr != nullptr)
631  {
632  const dictionary& addDict = ePtr->dict();
633 
634  forAllConstIter(IDLList<entry>, addDict, iter)
635  {
636  add(iter());
637  }
638 
639  return true;
640  }
641 
642  return false;
643 }
644 
645 
646 bool Foam::dictionary::isDict(const word& keyword) const
647 {
648  // Find non-recursive with patterns
649  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
650 
651  if (entryPtr)
652  {
653  return entryPtr->isDict();
654  }
655  else
656  {
657  return false;
658  }
659 }
660 
661 
663 {
664  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
665 
666  if (entryPtr)
667  {
668  return &entryPtr->dict();
669  }
670  else
671  {
672  return nullptr;
673  }
674 }
675 
676 
678 {
679  entry* entryPtr = lookupEntryPtr(keyword, false, true);
680 
681  if (entryPtr)
682  {
683  return &entryPtr->dict();
684  }
685  else
686  {
687  return nullptr;
688  }
689 }
690 
691 
692 const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const
693 {
694  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
695 
696  if (entryPtr == nullptr)
697  {
699  (
700  *this
701  ) << "keyword " << keyword << " is undefined in dictionary "
702  << name()
703  << exit(FatalIOError);
704  }
705  return entryPtr->dict();
706 }
707 
708 
710 {
711  entry* entryPtr = lookupEntryPtr(keyword, false, true);
712 
713  if (entryPtr == nullptr)
714  {
716  (
717  *this
718  ) << "keyword " << keyword << " is undefined in dictionary "
719  << name()
720  << exit(FatalIOError);
721  }
722  return entryPtr->dict();
723 }
724 
725 
727 (
728  const word& keyword,
729  const bool mustRead
730 ) const
731 {
732  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
733 
734  if (entryPtr == nullptr)
735  {
736  if (mustRead)
737  {
739  (
740  *this
741  ) << "keyword " << keyword << " is undefined in dictionary "
742  << name()
743  << exit(FatalIOError);
744  return entryPtr->dict();
745  }
746  else
747  {
748  return dictionary(*this, dictionary(name() + '.' + keyword));
749  }
750  }
751  else
752  {
753  return entryPtr->dict();
754  }
755 }
756 
757 
759 (
760  const word& keyword
761 ) const
762 {
763  const entry* entryPtr = lookupEntryPtr(keyword, false, true);
764 
765  if (entryPtr)
766  {
767  return entryPtr->dict();
768  }
769  else
770  {
771  return *this;
772  }
773 }
774 
775 
777 {
778  wordList keys(size());
779 
780  label nKeys = 0;
781  forAllConstIter(IDLList<entry>, *this, iter)
782  {
783  keys[nKeys++] = iter().keyword();
784  }
785 
786  return keys;
787 }
788 
789 
791 {
792  return hashedEntries_.sortedToc();
793 }
794 
795 
797 {
798  List<keyType> keys(size());
799 
800  label nKeys = 0;
801  forAllConstIter(IDLList<entry>, *this, iter)
802  {
803  if (iter().keyword().isPattern() ? patterns : !patterns)
804  {
805  keys[nKeys++] = iter().keyword();
806  }
807  }
808  keys.setSize(nKeys);
809 
810  return keys;
811 }
812 
813 
814 bool Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
815 {
816  HashTable<entry*>::iterator iter = hashedEntries_.find
817  (
818  entryPtr->keyword()
819  );
820 
821  if (mergeEntry && iter != hashedEntries_.end())
822  {
823  // Merge dictionary with dictionary
824  if (iter()->isDict() && entryPtr->isDict())
825  {
826  iter()->dict().merge(entryPtr->dict());
827  delete entryPtr;
828 
829  return true;
830  }
831  else
832  {
833  // Replace existing dictionary with entry or vice versa
834  IDLList<entry>::replace(iter(), entryPtr);
835  delete iter();
836  hashedEntries_.erase(iter);
837 
838  if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
839  {
840  entryPtr->name() = name() + '.' + entryPtr->keyword();
841 
842  if (entryPtr->keyword().isPattern())
843  {
844  patternEntries_.insert(entryPtr);
845  patternRegexps_.insert
846  (
847  autoPtr<regExp>(new regExp(entryPtr->keyword()))
848  );
849  }
850 
851  return true;
852  }
853  else
854  {
855  IOWarningInFunction((*this))
856  << "problem replacing entry "<< entryPtr->keyword()
857  << " in dictionary " << name() << endl;
858 
859  IDLList<entry>::remove(entryPtr);
860  delete entryPtr;
861  return false;
862  }
863  }
864  }
865 
866  if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
867  {
868  entryPtr->name() = name() + '.' + entryPtr->keyword();
869  IDLList<entry>::append(entryPtr);
870 
871  if (entryPtr->keyword().isPattern())
872  {
873  patternEntries_.insert(entryPtr);
874  patternRegexps_.insert
875  (
876  autoPtr<regExp>(new regExp(entryPtr->keyword()))
877  );
878  }
879 
880  return true;
881  }
882  else
883  {
884  IOWarningInFunction((*this))
885  << "attempt to add entry "<< entryPtr->keyword()
886  << " which already exists in dictionary " << name()
887  << endl;
888 
889  delete entryPtr;
890  return false;
891  }
892 }
893 
894 
895 void Foam::dictionary::add(const entry& e, bool mergeEntry)
896 {
897  add(e.clone(*this).ptr(), mergeEntry);
898 }
899 
900 
901 void Foam::dictionary::add(const keyType& k, const word& w, bool overwrite)
902 {
903  add(new primitiveEntry(k, token(w)), overwrite);
904 }
905 
906 
908 (
909  const keyType& k,
910  const Foam::string& s,
911  bool overwrite
912 )
913 {
914  add(new primitiveEntry(k, token(s)), overwrite);
915 }
916 
917 
918 void Foam::dictionary::add(const keyType& k, const label l, bool overwrite)
919 {
920  add(new primitiveEntry(k, token(l)), overwrite);
921 }
922 
923 
924 void Foam::dictionary::add(const keyType& k, const scalar s, bool overwrite)
925 {
926  add(new primitiveEntry(k, token(s)), overwrite);
927 }
928 
929 
931 (
932  const keyType& k,
933  const dictionary& d,
934  bool mergeEntry
935 )
936 {
937  add(new dictionaryEntry(k, *this, d), mergeEntry);
938 }
939 
940 
942 {
943  entry* existingPtr = lookupEntryPtr(entryPtr->keyword(), false, true);
944 
945  // Clear dictionary so merge acts like overwrite
946  if (existingPtr && existingPtr->isDict())
947  {
948  existingPtr->dict().clear();
949  }
950  add(entryPtr, true);
951 }
952 
953 
955 {
956  set(e.clone(*this).ptr());
957 }
958 
959 
960 void Foam::dictionary::set(const keyType& k, const dictionary& d)
961 {
962  set(new dictionaryEntry(k, *this, d));
963 }
964 
965 
966 bool Foam::dictionary::remove(const word& Keyword)
967 {
968  HashTable<entry*>::iterator iter = hashedEntries_.find(Keyword);
969 
970  if (iter != hashedEntries_.end())
971  {
972  // Delete from patterns first
973  DLList<entry*>::iterator wcLink =
974  patternEntries_.begin();
976  patternRegexps_.begin();
977 
978  // Find in pattern using exact match only
979  if (findInPatterns(false, Keyword, wcLink, reLink))
980  {
981  patternEntries_.remove(wcLink);
982  patternRegexps_.remove(reLink);
983  }
984 
985  IDLList<entry>::remove(iter());
986  delete iter();
987  hashedEntries_.erase(iter);
988 
989  return true;
990  }
991  else
992  {
993  return false;
994  }
995 }
996 
997 
999 (
1000  const keyType& oldKeyword,
1001  const keyType& newKeyword,
1002  bool forceOverwrite
1003 )
1004 {
1005  // No change
1006  if (oldKeyword == newKeyword)
1007  {
1008  return false;
1009  }
1010 
1011  HashTable<entry*>::iterator iter = hashedEntries_.find(oldKeyword);
1012 
1013  // oldKeyword not found - do nothing
1014  if (iter == hashedEntries_.end())
1015  {
1016  return false;
1017  }
1018 
1019  if (iter()->keyword().isPattern())
1020  {
1022  (
1023  *this
1024  ) << "Old keyword "<< oldKeyword
1025  << " is a pattern."
1026  << "Pattern replacement not yet implemented."
1027  << exit(FatalIOError);
1028  }
1029 
1030 
1031  HashTable<entry*>::iterator iter2 = hashedEntries_.find(newKeyword);
1032 
1033  // newKeyword already exists
1034  if (iter2 != hashedEntries_.end())
1035  {
1036  if (forceOverwrite)
1037  {
1038  if (iter2()->keyword().isPattern())
1039  {
1040  // Delete from patterns first
1041  DLList<entry*>::iterator wcLink =
1042  patternEntries_.begin();
1044  patternRegexps_.begin();
1045 
1046  // Find in patterns using exact match only
1047  if (findInPatterns(false, iter2()->keyword(), wcLink, reLink))
1048  {
1049  patternEntries_.remove(wcLink);
1050  patternRegexps_.remove(reLink);
1051  }
1052  }
1053 
1054  IDLList<entry>::replace(iter2(), iter());
1055  delete iter2();
1056  hashedEntries_.erase(iter2);
1057 
1058  }
1059  else
1060  {
1062  (
1063  *this
1064  ) << "cannot rename keyword "<< oldKeyword
1065  << " to existing keyword " << newKeyword
1066  << " in dictionary " << name() << endl;
1067  return false;
1068  }
1069  }
1070 
1071  // Change name and HashTable, but leave DL-List untouched
1072  iter()->keyword() = newKeyword;
1073  iter()->name() = name() + '.' + newKeyword;
1074  hashedEntries_.erase(oldKeyword);
1075  hashedEntries_.insert(newKeyword, iter());
1076 
1077  if (newKeyword.isPattern())
1078  {
1079  patternEntries_.insert(iter());
1080  patternRegexps_.insert
1081  (
1082  autoPtr<regExp>(new regExp(newKeyword))
1083  );
1084  }
1085 
1086  return true;
1087 }
1088 
1089 
1091 {
1092  // Check for assignment to self
1093  if (this == &dict)
1094  {
1095  FatalIOErrorInFunction(*this)
1096  << "attempted merge to self for dictionary " << name()
1097  << abort(FatalIOError);
1098  }
1099 
1100  bool changed = false;
1101 
1102  forAllConstIter(IDLList<entry>, dict, iter)
1103  {
1104  HashTable<entry*>::iterator fnd = hashedEntries_.find(iter().keyword());
1105 
1106  if (fnd != hashedEntries_.end())
1107  {
1108  // Recursively merge sub-dictionaries
1109  // TODO: merge without copying
1110  if (fnd()->isDict() && iter().isDict())
1111  {
1112  if (fnd()->dict().merge(iter().dict()))
1113  {
1114  changed = true;
1115  }
1116  }
1117  else
1118  {
1119  add(iter().clone(*this).ptr(), true);
1120  changed = true;
1121  }
1122  }
1123  else
1124  {
1125  // Not found - just add
1126  add(iter().clone(*this).ptr());
1127  changed = true;
1128  }
1129  }
1130 
1131  return changed;
1132 }
1133 
1134 
1136 {
1138  hashedEntries_.clear();
1139  patternEntries_.clear();
1140  patternRegexps_.clear();
1141 }
1142 
1143 
1145 {
1146  // Changing parents probably doesn't make much sense,
1147  // but what about the names?
1148  name() = dict.name();
1149 
1151  hashedEntries_.transfer(dict.hashedEntries_);
1152  patternEntries_.transfer(dict.patternEntries_);
1153  patternRegexps_.transfer(dict.patternRegexps_);
1154 }
1155 
1156 
1158 {
1159  return xferMove(*this);
1160 }
1161 
1162 
1163 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1164 
1166 {
1167  return lookup(keyword);
1168 }
1169 
1170 
1172 {
1173  // Check for assignment to self
1174  if (this == &rhs)
1175  {
1176  FatalIOErrorInFunction(*this)
1177  << "attempted assignment to self for dictionary " << name()
1178  << abort(FatalIOError);
1179  }
1180 
1181  name() = rhs.name();
1182  clear();
1183 
1184  // Create clones of the entries in the given dictionary
1185  // resetting the parentDict to this dictionary
1186 
1187  forAllConstIter(IDLList<entry>, rhs, iter)
1188  {
1189  add(iter().clone(*this).ptr());
1190  }
1191 }
1192 
1193 
1195 {
1196  // Check for assignment to self
1197  if (this == &rhs)
1198  {
1199  FatalIOErrorInFunction(*this)
1200  << "attempted addition assignment to self for dictionary " << name()
1201  << abort(FatalIOError);
1202  }
1203 
1204  forAllConstIter(IDLList<entry>, rhs, iter)
1205  {
1206  add(iter().clone(*this).ptr());
1207  }
1208 }
1209 
1210 
1212 {
1213  // Check for assignment to self
1214  if (this == &rhs)
1215  {
1216  FatalIOErrorInFunction(*this)
1217  << "attempted assignment to self for dictionary " << name()
1218  << abort(FatalIOError);
1219  }
1220 
1221  forAllConstIter(IDLList<entry>, rhs, iter)
1222  {
1223  if (!found(iter().keyword()))
1224  {
1225  add(iter().clone(*this).ptr());
1226  }
1227  }
1228 }
1229 
1230 
1232 {
1233  // Check for assignment to self
1234  if (this == &rhs)
1235  {
1236  FatalIOErrorInFunction(*this)
1237  << "attempted assignment to self for dictionary " << name()
1238  << abort(FatalIOError);
1239  }
1240 
1241  forAllConstIter(IDLList<entry>, rhs, iter)
1242  {
1243  set(iter().clone(*this).ptr());
1244  }
1245 }
1246 
1247 
1248 /* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
1249 
1250 Foam::dictionary Foam::operator+
1252  const dictionary& dict1,
1253  const dictionary& dict2
1254 )
1255 {
1256  dictionary sum(dict1);
1257  sum += dict2;
1258  return sum;
1259 }
1260 
1261 
1262 Foam::dictionary Foam::operator|
1264  const dictionary& dict1,
1265  const dictionary& dict2
1266 )
1267 {
1268  dictionary sum(dict1);
1269  sum |= dict2;
1270  return sum;
1271 }
1272 
1273 
1274 // ************************************************************************* //
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:172
A class for handling keywords in dictionaries.
Definition: keyType.H:64
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
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:431
bool remove(const word &)
Remove an entry specified by keyword.
Definition: dictionary.C:966
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:69
label endLineNumber() const
Return line number of last token in dictionary.
Definition: dictionary.C:384
void operator=(const dictionary &)
Definition: dictionary.C:1171
tokenList tokens() const
Return the dictionary as a list of tokens.
Definition: dictionary.C:411
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:470
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:397
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:1194
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:137
void transfer(ILList< LListBase, T > &)
Transfer the contents of the argument into this List.
Definition: ILList.C:125
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:60
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:453
dictionaryName()
Construct dictionaryName null.
Definition: dictionary.H:90
static const dictionary null
Null dictionary.
Definition: dictionary.H:202
An STL-conforming const_iterator.
Definition: LList.H:291
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:240
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:553
The output stream for calculating SHA1 digests.
Definition: OSHA1stream.H:133
T * last()
Return the last entry.
Definition: UILList.H:118
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:1144
autoPtr< dictionary > clone() const
Construct and return clone.
Definition: dictionary.C:340
An STL-conforming const_iterator.
Definition: UILList.H:227
const entry * lookupScopedEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:587
wordList toc() const
Return the table of contents.
Definition: dictionary.C:776
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:646
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:814
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:692
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:999
void operator<<=(const dictionary &)
Unconditionally include entries from the given dictionary.
Definition: dictionary.C:1231
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:103
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:759
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
A class for handling words, derived from string.
Definition: word.H:59
const dictionary & parent() const
Return the parent dictionary.
Definition: dictionary.H:260
void clear()
Clear the contents of the list.
Definition: ILList.C:112
An STL-conforming iterator.
Definition: UILList.H:178
const dictionary & topDict() const
Return the top of the tree.
Definition: dictionary.C:356
T * remove(T *p)
Remove and return element.
Definition: UILList.H:139
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
Xfer< dictionary > xfer()
Transfer contents to the Xfer container.
Definition: dictionary.C:1157
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:662
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:796
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:1211
ITstream & operator[](const word &) const
Find and return entry.
Definition: dictionary.C:1165
#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:348
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:941
bool substituteScopedKeyword(const word &keyword)
Substitute the given scoped keyword prepended by &#39;$&#39; with the.
Definition: dictionary.C:622
bool merge(const dictionary &)
Merge entries from the given dictionary.
Definition: dictionary.C:1090
#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:106
void clear()
Clear the dictionary.
Definition: dictionary.C:1135
virtual ITstream & stream() const =0
Return token stream if this entry is a primitive entry.
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:371
wordList sortedToc() const
Return the sorted table of contents.
Definition: dictionary.C:790
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:727
Foam::SHA1Digest digest()
Return SHA1::Digest for the data processed until now.
Definition: OSHA1stream.H:185
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:576
IOerror FatalIOError