dictionary.C 27 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
5
    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
6
7
8
9
10
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

11
12
13
14
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
15
16
17
18
19
20
21

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    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
27
28

\*---------------------------------------------------------------------------*/

#include "dictionary.H"
#include "primitiveEntry.H"
#include "dictionaryEntry.H"
29
#include "regExp.H"
Mark Olesen's avatar
Mark Olesen committed
30
#include "OSHA1stream.H"
31
#include "DynamicList.H"
32
33
34

/* * * * * * * * * * * * * * * Static Member Data  * * * * * * * * * * * * * */

35
36
37
38
39
namespace Foam
{
defineTypeNameAndDebug(dictionary, 0);
const dictionary dictionary::null;
}
40

mattijs's avatar
mattijs committed
41
42
43

// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //

44
bool Foam::dictionary::findInPatterns
mattijs's avatar
mattijs committed
45
(
46
    const bool patternMatch,
mattijs's avatar
mattijs committed
47
48
    const word& Keyword,
    DLList<entry*>::const_iterator& wcLink,
49
    DLList<autoPtr<regExp> >::const_iterator& reLink
mattijs's avatar
mattijs committed
50
51
) const
{
52
    if (patternEntries_.size())
mattijs's avatar
mattijs committed
53
    {
54
        while (wcLink != patternEntries_.end())
mattijs's avatar
mattijs committed
55
        {
56
57
            if
            (
58
59
                patternMatch
              ? reLink()->match(Keyword)
60
61
              : wcLink()->keyword() == Keyword
            )
mattijs's avatar
mattijs committed
62
63
64
65
66
67
68
69
70
71
72
73
74
            {
                return true;
            }

            ++reLink;
            ++wcLink;
        }
    }

    return false;
}


75
bool Foam::dictionary::findInPatterns
mattijs's avatar
mattijs committed
76
(
77
    const bool patternMatch,
mattijs's avatar
mattijs committed
78
79
    const word& Keyword,
    DLList<entry*>::iterator& wcLink,
80
    DLList<autoPtr<regExp> >::iterator& reLink
mattijs's avatar
mattijs committed
81
82
)
{
83
    if (patternEntries_.size())
mattijs's avatar
mattijs committed
84
    {
85
        while (wcLink != patternEntries_.end())
mattijs's avatar
mattijs committed
86
        {
87
88
            if
            (
89
90
                patternMatch
              ? reLink()->match(Keyword)
91
92
              : wcLink()->keyword() == Keyword
            )
mattijs's avatar
mattijs committed
93
94
95
96
97
98
99
100
101
102
103
104
105
            {
                return true;
            }

            ++reLink;
            ++wcLink;
        }
    }

    return false;
}


106
107
108
109
110
111
112
113
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

Foam::dictionary::dictionary()
:
    parent_(dictionary::null)
{}


114
115
116
117
118
119
120
Foam::dictionary::dictionary(const fileName& name)
:
    dictionaryName(name),
    parent_(dictionary::null)
{}


121
122
123
124
125
126
Foam::dictionary::dictionary
(
    const dictionary& parentDict,
    const dictionary& dict
)
:
127
    dictionaryName(dict.name()),
128
129
130
    IDLList<entry>(dict, *this),
    parent_(parentDict)
{
Mark Olesen's avatar
Mark Olesen committed
131
    forAllIter(IDLList<entry>, *this, iter)
132
133
    {
        hashedEntries_.insert(iter().keyword(), &iter());
mattijs's avatar
mattijs committed
134

135
        if (iter().keyword().isPattern())
mattijs's avatar
mattijs committed
136
        {
137
138
            patternEntries_.insert(&iter());
            patternRegexps_.insert
mattijs's avatar
mattijs committed
139
            (
140
                autoPtr<regExp>(new regExp(iter().keyword()))
mattijs's avatar
mattijs committed
141
142
            );
        }
143
144
145
146
147
148
149
150
151
    }
}


Foam::dictionary::dictionary
(
    const dictionary& dict
)
:
152
    dictionaryName(dict.name()),
153
154
155
    IDLList<entry>(dict, *this),
    parent_(dictionary::null)
{
Mark Olesen's avatar
Mark Olesen committed
156
    forAllIter(IDLList<entry>, *this, iter)
157
158
    {
        hashedEntries_.insert(iter().keyword(), &iter());
mattijs's avatar
mattijs committed
159

160
        if (iter().keyword().isPattern())
mattijs's avatar
mattijs committed
161
        {
162
163
            patternEntries_.insert(&iter());
            patternRegexps_.insert
mattijs's avatar
mattijs committed
164
            (
165
                autoPtr<regExp>(new regExp(iter().keyword()))
mattijs's avatar
mattijs committed
166
167
            );
        }
168
169
170
171
    }
}


172
173
174
175
176
177
178
179
180
181
182
183
184
185
Foam::dictionary::dictionary
(
    const dictionary* dictPtr
)
:
    parent_(dictionary::null)
{
    if (dictPtr)
    {
        operator=(*dictPtr);
    }
}


186
187
188
Foam::dictionary::dictionary
(
    const dictionary& parentDict,
Mark Olesen's avatar
Mark Olesen committed
189
    const Xfer<dictionary>& dict
190
191
192
193
194
)
:
    parent_(parentDict)
{
    transfer(dict());
195
    name() = parentDict.name() + '.' + name();
196
197
198
199
200
}


Foam::dictionary::dictionary
(
Mark Olesen's avatar
Mark Olesen committed
201
    const Xfer<dictionary>& dict
202
203
204
205
206
207
208
209
)
:
    parent_(dictionary::null)
{
    transfer(dict());
}


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
Foam::autoPtr<Foam::dictionary> Foam::dictionary::clone() const
{
    return autoPtr<dictionary>(new dictionary(*this));
}


// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

Foam::dictionary::~dictionary()
{
    // cerr<< "~dictionary() " << name() << " " << long(this) << std::endl;
}


// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
const Foam::dictionary& Foam::dictionary::topDict() const
{
    const dictionary& p = parent();

    if (&p != this && !p.name().empty())
    {
        return p.topDict();
    }
    else
    {
        return p;
    }
}


241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
Foam::label Foam::dictionary::startLineNumber() const
{
    if (size())
    {
        return first()->startLineNumber();
    }
    else
    {
        return -1;
    }
}


Foam::label Foam::dictionary::endLineNumber() const
{
    if (size())
    {
        return last()->endLineNumber();
    }
    else
    {
        return -1;
    }
}


267
Foam::SHA1Digest Foam::dictionary::digest() const
Mark Olesen's avatar
Mark Olesen committed
268
269
270
271
{
    OSHA1stream os;

    // process entries
Mark Olesen's avatar
Mark Olesen committed
272
    forAllConstIter(IDLList<entry>, *this, iter)
Mark Olesen's avatar
Mark Olesen committed
273
274
275
276
277
278
279
280
    {
        os << *iter;
    }

    return os.digest();
}


281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
Foam::tokenList Foam::dictionary::tokens() const
{
    // linearise dictionary into a string
    OStringStream os;
    write(os, false);
    IStringStream is(os.str());

    // parse string as tokens
    DynamicList<token> tokens;
    token t;
    while (is.read(t))
    {
        tokens.append(t);
    }

    return tokenList(tokens.xfer());
}


300
301
302
303
304
305
bool Foam::dictionary::found
(
    const word& keyword,
    bool recursive,
    bool patternMatch
) const
306
307
308
309
310
311
312
{
    if (hashedEntries_.found(keyword))
    {
        return true;
    }
    else
    {
313
        if (patternMatch && patternEntries_.size())
mattijs's avatar
mattijs committed
314
        {
Mark Olesen's avatar
Mark Olesen committed
315
316
            DLList<entry*>::const_iterator wcLink =
                patternEntries_.begin();
317
            DLList<autoPtr<regExp> >::const_iterator reLink =
318
                patternRegexps_.begin();
mattijs's avatar
mattijs committed
319

320
            // Find in patterns using regular expressions only
321
            if (findInPatterns(patternMatch, keyword, wcLink, reLink))
mattijs's avatar
mattijs committed
322
323
324
325
326
327
328
            {
                return true;
            }
        }

        if (recursive && &parent_ != &dictionary::null)
        {
329
            return parent_.found(keyword, recursive, patternMatch);
mattijs's avatar
mattijs committed
330
331
332
333
334
        }
        else
        {
            return false;
        }
335
336
337
338
339
340
341
    }
}


const Foam::entry* Foam::dictionary::lookupEntryPtr
(
    const word& keyword,
mattijs's avatar
mattijs committed
342
    bool recursive,
343
    bool patternMatch
344
345
346
347
348
349
) const
{
    HashTable<entry*>::const_iterator iter = hashedEntries_.find(keyword);

    if (iter == hashedEntries_.end())
    {
350
        if (patternMatch && patternEntries_.size())
mattijs's avatar
mattijs committed
351
352
        {
            DLList<entry*>::const_iterator wcLink =
353
                patternEntries_.begin();
354
            DLList<autoPtr<regExp> >::const_iterator reLink =
355
                patternRegexps_.begin();
mattijs's avatar
mattijs committed
356

357
358
            // Find in patterns using regular expressions only
            if (findInPatterns(patternMatch, keyword, wcLink, reLink))
mattijs's avatar
mattijs committed
359
360
361
362
363
            {
                return wcLink();
            }
        }

Mark Olesen's avatar
Mark Olesen committed
364
        if (recursive && &parent_ != &dictionary::null)
365
        {
366
            return parent_.lookupEntryPtr(keyword, recursive, patternMatch);
367
368
369
370
371
372
373
374
375
376
377
        }
        else
        {
            return NULL;
        }
    }

    return iter();
}


378
379
380
Foam::entry* Foam::dictionary::lookupEntryPtr
(
    const word& keyword,
mattijs's avatar
mattijs committed
381
    bool recursive,
382
    bool patternMatch
383
384
385
386
387
388
)
{
    HashTable<entry*>::iterator iter = hashedEntries_.find(keyword);

    if (iter == hashedEntries_.end())
    {
389
        if (patternMatch && patternEntries_.size())
mattijs's avatar
mattijs committed
390
391
        {
            DLList<entry*>::iterator wcLink =
392
                patternEntries_.begin();
393
            DLList<autoPtr<regExp> >::iterator reLink =
394
                patternRegexps_.begin();
395
396
397

            // Find in patterns using regular expressions only
            if (findInPatterns(patternMatch, keyword, wcLink, reLink))
mattijs's avatar
mattijs committed
398
399
400
401
402
            {
                return wcLink();
            }
        }

Mark Olesen's avatar
Mark Olesen committed
403
        if (recursive && &parent_ != &dictionary::null)
404
405
406
407
        {
            return const_cast<dictionary&>(parent_).lookupEntryPtr
            (
                keyword,
mattijs's avatar
mattijs committed
408
                recursive,
409
                patternMatch
410
411
412
413
414
415
416
417
418
419
420
421
            );
        }
        else
        {
            return NULL;
        }
    }

    return iter();
}


422
423
424
const Foam::entry& Foam::dictionary::lookupEntry
(
    const word& keyword,
mattijs's avatar
mattijs committed
425
    bool recursive,
426
    bool patternMatch
427
428
) const
{
429
    const entry* entryPtr = lookupEntryPtr(keyword, recursive, patternMatch);
430

Mark Olesen's avatar
Mark Olesen committed
431
    if (entryPtr == NULL)
432
433
434
    {
        FatalIOErrorIn
        (
mattijs's avatar
mattijs committed
435
            "dictionary::lookupEntry(const word&, bool, bool) const",
436
            *this
437
        )   << "keyword " << keyword << " is undefined in dictionary "
438
439
440
441
            << name()
            << exit(FatalIOError);
    }

Mark Olesen's avatar
Mark Olesen committed
442
    return *entryPtr;
443
444
445
446
447
448
}


Foam::ITstream& Foam::dictionary::lookup
(
    const word& keyword,
mattijs's avatar
mattijs committed
449
    bool recursive,
450
    bool patternMatch
451
452
) const
{
453
    return lookupEntry(keyword, recursive, patternMatch).stream();
454
455
456
}


457
458
459
460
461
462
463
const Foam::entry* Foam::dictionary::lookupScopedEntryPtr
(
    const word& keyword,
    bool recursive,
    bool patternMatch
) const
{
464
    if (keyword[0] == ':')
465
    {
466
467
468
469
470
471
472
473
474
475
476
477
478
479
        // Go up to top level
        const dictionary* dictPtr = this;
        while (&dictPtr->parent_ != &dictionary::null)
        {
            dictPtr = &dictPtr->parent_;
        }

        // At top. Recurse to find entries
        return dictPtr->lookupScopedEntryPtr
        (
            keyword.substr(1, keyword.size()-1),
            false,
            patternMatch
        );
480
481
482
    }
    else
    {
483
        string::size_type dotPos = keyword.find('.');
484

485
486
487
488
        if (dotPos == string::npos)
        {
            // Non-scoped lookup
            return lookupEntryPtr(keyword, recursive, patternMatch);
489
490
491
        }
        else
        {
492
493
494
495
496
            if (dotPos == 0)
            {
                // Starting with a '.'. Go up for every 2nd '.' found

                const dictionary* dictPtr = this;
497

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
                string::size_type begVar = dotPos + 1;
                string::const_iterator iter = keyword.begin() + begVar;
                string::size_type endVar = begVar;
                while
                (
                    iter != keyword.end()
                 && *iter == '.'
                )
                {
                    ++iter;
                    ++endVar;

                    // Go to parent
                    if (&dictPtr->parent_ == &dictionary::null)
                    {
                        FatalIOErrorIn
                        (
                            "dictionary::lookupScopedEntryPtr"
                            "(const word&, bool, bool)",
                            *this
                        )   << "No parent of current dictionary"
                            << " when searching for "
                            << keyword.substr(begVar, keyword.size()-begVar)
                            << exit(FatalIOError);
                    }
                    dictPtr = &dictPtr->parent_;
                }
525

526
527
528
529
530
531
532
533
                return dictPtr->lookupScopedEntryPtr
                (
                    keyword.substr(endVar),
                    false,
                    patternMatch
                );
            }
            else
534
            {
535
536
537
538
539
540
541
542
543
544
                // Extract the first word
                word firstWord = keyword.substr(0, dotPos);

                const entry* entPtr = lookupScopedEntryPtr
                (
                    firstWord,
                    false,          //recursive
                    patternMatch
                );

545
546
547
548
549
550
551
                if (!entPtr)
                {
                    FatalIOErrorIn
                    (
                        "dictionary::lookupScopedEntryPtr"
                        "(const word&, bool, bool)",
                        *this
552
                    )   << "keyword " << firstWord
553
                        << " is undefined in dictionary "
554
555
                        << name() << endl
                        << "Valid keywords are " << keys()
556
557
                        << exit(FatalIOError);
                }
558
559

                if (entPtr->isDict())
560
                {
561
                    return entPtr->dict().lookupScopedEntryPtr
562
                    (
563
564
565
566
567
568
569
570
                        keyword.substr(dotPos, keyword.size()-dotPos),
                        false,
                        patternMatch
                    );
                }
                else
                {
                    return NULL;
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
                }
            }
        }
    }
}


bool Foam::dictionary::substituteScopedKeyword(const word& keyword)
{
    word varName = keyword(1, keyword.size()-1);

    // lookup the variable name in the given dictionary
    const entry* ePtr = lookupScopedEntryPtr(varName, true, true);

    // if defined insert its entries into this dictionary
    if (ePtr != NULL)
    {
        const dictionary& addDict = ePtr->dict();

        forAllConstIter(IDLList<entry>, addDict, iter)
        {
            add(iter());
        }

        return true;
    }

    return false;
}


602
603
bool Foam::dictionary::isDict(const word& keyword) const
{
604
    // Find non-recursive with patterns
mattijs's avatar
mattijs committed
605
    const entry* entryPtr = lookupEntryPtr(keyword, false, true);
Mark Olesen's avatar
Mark Olesen committed
606
607

    if (entryPtr)
608
609
610
611
612
613
614
615
616
617
618
619
    {
        return entryPtr->isDict();
    }
    else
    {
        return false;
    }
}


const Foam::dictionary* Foam::dictionary::subDictPtr(const word& keyword) const
{
mattijs's avatar
mattijs committed
620
    const entry* entryPtr = lookupEntryPtr(keyword, false, true);
Mark Olesen's avatar
Mark Olesen committed
621
622

    if (entryPtr)
623
624
625
626
627
628
629
630
631
632
633
634
    {
        return &entryPtr->dict();
    }
    else
    {
        return NULL;
    }
}


const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const
{
mattijs's avatar
mattijs committed
635
636
    const entry* entryPtr = lookupEntryPtr(keyword, false, true);

Mark Olesen's avatar
Mark Olesen committed
637
    if (entryPtr == NULL)
638
639
640
641
642
    {
        FatalIOErrorIn
        (
            "dictionary::subDict(const word& keyword) const",
            *this
643
        )   << "keyword " << keyword << " is undefined in dictionary "
644
645
646
            << name()
            << exit(FatalIOError);
    }
Mark Olesen's avatar
Mark Olesen committed
647
    return entryPtr->dict();
648
649
650
}


651
652
Foam::dictionary& Foam::dictionary::subDict(const word& keyword)
{
mattijs's avatar
mattijs committed
653
654
    entry* entryPtr = lookupEntryPtr(keyword, false, true);

Mark Olesen's avatar
Mark Olesen committed
655
    if (entryPtr == NULL)
656
657
658
    {
        FatalIOErrorIn
        (
Mark Olesen's avatar
Mark Olesen committed
659
            "dictionary::subDict(const word& keyword)",
660
            *this
661
        )   << "keyword " << keyword << " is undefined in dictionary "
662
663
664
            << name()
            << exit(FatalIOError);
    }
Mark Olesen's avatar
Mark Olesen committed
665
    return entryPtr->dict();
666
667
668
}


669
670
Foam::dictionary Foam::dictionary::subOrEmptyDict
(
671
672
    const word& keyword,
    const bool mustRead
673
674
675
676
677
678
) const
{
    const entry* entryPtr = lookupEntryPtr(keyword, false, true);

    if (entryPtr == NULL)
    {
679
680
681
682
683
684
685
686
687
688
689
690
691
        if (mustRead)
        {
            FatalIOErrorIn
            (
                "dictionary::subOrEmptyDict(const word& keyword, const bool)",
                *this
            )   << "keyword " << keyword << " is undefined in dictionary "
                << name()
                << exit(FatalIOError);
            return entryPtr->dict();
        }
        else
        {
692
            return dictionary(*this, dictionary(name() + '.' + keyword));
693
        }
694
695
696
697
698
699
700
701
    }
    else
    {
        return entryPtr->dict();
    }
}


702
703
Foam::wordList Foam::dictionary::toc() const
{
Mark Olesen's avatar
Mark Olesen committed
704
    wordList keys(size());
705

706
    label nKeys = 0;
707
    forAllConstIter(IDLList<entry>, *this, iter)
708
709
710
711
712
713
714
715
716
717
718
719
720
    {
        keys[nKeys++] = iter().keyword();
    }

    return keys;
}


Foam::List<Foam::keyType> Foam::dictionary::keys(bool patterns) const
{
    List<keyType> keys(size());

    label nKeys = 0;
Mark Olesen's avatar
Mark Olesen committed
721
    forAllConstIter(IDLList<entry>, *this, iter)
722
    {
723
724
725
726
        if (iter().keyword().isPattern() ? patterns : !patterns)
        {
            keys[nKeys++] = iter().keyword();
        }
Mark Olesen's avatar
Mark Olesen committed
727
    }
728
    keys.setSize(nKeys);
Mark Olesen's avatar
Mark Olesen committed
729
730
731
732
733
734
735

    return keys;
}


bool Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
{
mattijs's avatar
mattijs committed
736
737
738
739
    HashTable<entry*>::iterator iter = hashedEntries_.find
    (
        entryPtr->keyword()
    );
Mark Olesen's avatar
Mark Olesen committed
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759

    if (mergeEntry && iter != hashedEntries_.end())
    {
        // merge dictionary with dictionary
        if (iter()->isDict() && entryPtr->isDict())
        {
            iter()->dict().merge(entryPtr->dict());
            delete entryPtr;

            return true;
        }
        else
        {
            // replace existing dictionary with entry or vice versa
            IDLList<entry>::replace(iter(), entryPtr);
            delete iter();
            hashedEntries_.erase(iter);

            if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
            {
760
                entryPtr->name() = name() + '.' + entryPtr->keyword();
mattijs's avatar
mattijs committed
761

762
                if (entryPtr->keyword().isPattern())
mattijs's avatar
mattijs committed
763
                {
764
765
                    patternEntries_.insert(entryPtr);
                    patternRegexps_.insert
mattijs's avatar
mattijs committed
766
                    (
767
                        autoPtr<regExp>(new regExp(entryPtr->keyword()))
mattijs's avatar
mattijs committed
768
769
770
                    );
                }

Mark Olesen's avatar
Mark Olesen committed
771
772
773
774
                return true;
            }
            else
            {
775
                IOWarningIn("dictionary::add(entry*, bool)", (*this))
Mark Olesen's avatar
Mark Olesen committed
776
777
778
779
780
781
782
783
784
785
786
787
                    << "problem replacing entry "<< entryPtr->keyword()
                    << " in dictionary " << name() << endl;

                IDLList<entry>::remove(entryPtr);
                delete entryPtr;
                return false;
            }
        }
    }

    if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
    {
788
        entryPtr->name() = name() + '.' + entryPtr->keyword();
Mark Olesen's avatar
Mark Olesen committed
789
790
        IDLList<entry>::append(entryPtr);

791
        if (entryPtr->keyword().isPattern())
mattijs's avatar
mattijs committed
792
        {
793
794
            patternEntries_.insert(entryPtr);
            patternRegexps_.insert
mattijs's avatar
mattijs committed
795
            (
796
                autoPtr<regExp>(new regExp(entryPtr->keyword()))
mattijs's avatar
mattijs committed
797
798
799
            );
        }

Mark Olesen's avatar
Mark Olesen committed
800
        return true;
801
    }
Mark Olesen's avatar
Mark Olesen committed
802
803
    else
    {
804
        IOWarningIn("dictionary::add(entry*, bool)", (*this))
Mark Olesen's avatar
Mark Olesen committed
805
806
807
            << "attempt to add entry "<< entryPtr->keyword()
            << " which already exists in dictionary " << name()
            << endl;
808

Mark Olesen's avatar
Mark Olesen committed
809
810
811
        delete entryPtr;
        return false;
    }
812
813
814
}


Mark Olesen's avatar
Mark Olesen committed
815
void Foam::dictionary::add(const entry& e, bool mergeEntry)
816
{
Mark Olesen's avatar
Mark Olesen committed
817
    add(e.clone(*this).ptr(), mergeEntry);
818
819
}

820

mattijs's avatar
mattijs committed
821
void Foam::dictionary::add(const keyType& k, const word& w, bool overwrite)
822
{
Mark Olesen's avatar
Mark Olesen committed
823
    add(new primitiveEntry(k, token(w)), overwrite);
824
825
}

826

mattijs's avatar
mattijs committed
827
828
829
830
831
832
void Foam::dictionary::add
(
    const keyType& k,
    const Foam::string& s,
    bool overwrite
)
833
{
Mark Olesen's avatar
Mark Olesen committed
834
    add(new primitiveEntry(k, token(s)), overwrite);
835
836
}

837

mattijs's avatar
mattijs committed
838
void Foam::dictionary::add(const keyType& k, const label l, bool overwrite)
839
{
Mark Olesen's avatar
Mark Olesen committed
840
    add(new primitiveEntry(k, token(l)), overwrite);
841
842
}

843

mattijs's avatar
mattijs committed
844
void Foam::dictionary::add(const keyType& k, const scalar s, bool overwrite)
845
{
Mark Olesen's avatar
Mark Olesen committed
846
    add(new primitiveEntry(k, token(s)), overwrite);
847
848
}

849

mattijs's avatar
mattijs committed
850
851
852
853
854
855
void Foam::dictionary::add
(
    const keyType& k,
    const dictionary& d,
    bool mergeEntry
)
856
{
Mark Olesen's avatar
Mark Olesen committed
857
    add(new dictionaryEntry(k, *this, d), mergeEntry);
858
859
}

Mark Olesen's avatar
Mark Olesen committed
860
861

void Foam::dictionary::set(entry* entryPtr)
862
{
mattijs's avatar
mattijs committed
863
    entry* existingPtr = lookupEntryPtr(entryPtr->keyword(), false, true);
Mark Olesen's avatar
Mark Olesen committed
864
865
866
867
868
869
870

    // clear dictionary so merge acts like overwrite
    if (existingPtr && existingPtr->isDict())
    {
        existingPtr->dict().clear();
    }
    add(entryPtr, true);
871
872
}

Mark Olesen's avatar
Mark Olesen committed
873
874

void Foam::dictionary::set(const entry& e)
875
{
Mark Olesen's avatar
Mark Olesen committed
876
    set(e.clone(*this).ptr());
877
878
}

879

mattijs's avatar
mattijs committed
880
void Foam::dictionary::set(const keyType& k, const dictionary& d)
881
{
Mark Olesen's avatar
Mark Olesen committed
882
    set(new dictionaryEntry(k, *this, d));
883
884
885
886
887
888
889
890
891
}


bool Foam::dictionary::remove(const word& Keyword)
{
    HashTable<entry*>::iterator iter = hashedEntries_.find(Keyword);

    if (iter != hashedEntries_.end())
    {
892
        // Delete from patterns first
Mark Olesen's avatar
Mark Olesen committed
893
894
895
896
        DLList<entry*>::iterator wcLink =
            patternEntries_.begin();
        DLList<autoPtr<regExp> >::iterator reLink =
            patternRegexps_.begin();
mattijs's avatar
mattijs committed
897

898
899
        // Find in pattern using exact match only
        if (findInPatterns(false, Keyword, wcLink, reLink))
mattijs's avatar
mattijs committed
900
        {
901
902
            patternEntries_.remove(wcLink);
            patternRegexps_.remove(reLink);
mattijs's avatar
mattijs committed
903
904
        }

905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
        IDLList<entry>::remove(iter());
        delete iter();
        hashedEntries_.erase(iter);

        return true;
    }
    else
    {
        return false;
    }
}


bool Foam::dictionary::changeKeyword
(
mattijs's avatar
mattijs committed
920
921
    const keyType& oldKeyword,
    const keyType& newKeyword,
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
    bool forceOverwrite
)
{
    // no change
    if (oldKeyword == newKeyword)
    {
        return false;
    }

    HashTable<entry*>::iterator iter = hashedEntries_.find(oldKeyword);

    // oldKeyword not found - do nothing
    if (iter == hashedEntries_.end())
    {
        return false;
    }

939
    if (iter()->keyword().isPattern())
mattijs's avatar
mattijs committed
940
    {
941
        FatalIOErrorIn
mattijs's avatar
mattijs committed
942
        (
943
944
            "dictionary::changeKeyword(const word&, const word&, bool)",
            *this
mattijs's avatar
mattijs committed
945
        )   << "Old keyword "<< oldKeyword
946
947
            << " is a pattern."
            << "Pattern replacement not yet implemented."
948
            << exit(FatalIOError);
mattijs's avatar
mattijs committed
949
950
951
    }


952
953
954
955
956
957
958
    HashTable<entry*>::iterator iter2 = hashedEntries_.find(newKeyword);

    // newKeyword already exists
    if (iter2 != hashedEntries_.end())
    {
        if (forceOverwrite)
        {
959
            if (iter2()->keyword().isPattern())
mattijs's avatar
mattijs committed
960
            {
961
                // Delete from patterns first
mattijs's avatar
mattijs committed
962
                DLList<entry*>::iterator wcLink =
963
                    patternEntries_.begin();
964
                DLList<autoPtr<regExp> >::iterator reLink =
965
                    patternRegexps_.begin();
mattijs's avatar
mattijs committed
966

967
968
                // Find in patterns using exact match only
                if (findInPatterns(false, iter2()->keyword(), wcLink, reLink))
mattijs's avatar
mattijs committed
969
                {
970
971
                    patternEntries_.remove(wcLink);
                    patternRegexps_.remove(reLink);
mattijs's avatar
mattijs committed
972
973
974
                }
            }

Mark Olesen's avatar
Mark Olesen committed
975
            IDLList<entry>::replace(iter2(), iter());
976
977
            delete iter2();
            hashedEntries_.erase(iter2);
978

979
980
981
        }
        else
        {
982
            IOWarningIn
mattijs's avatar
mattijs committed
983
            (
984
985
                "dictionary::changeKeyword(const word&, const word&, bool)",
                *this
mattijs's avatar
mattijs committed
986
            )   << "cannot rename keyword "<< oldKeyword
Mark Olesen's avatar
Mark Olesen committed
987
988
                << " to existing keyword " << newKeyword
                << " in dictionary " << name() << endl;
989
990
991
992
993
994
            return false;
        }
    }

    // change name and HashTable, but leave DL-List untouched
    iter()->keyword() = newKeyword;
995
    iter()->name() = name() + '.' + newKeyword;
996
997
998
    hashedEntries_.erase(oldKeyword);
    hashedEntries_.insert(newKeyword, iter());

999
    if (newKeyword.isPattern())
mattijs's avatar
mattijs committed
1000
    {
For faster browsing, not all history is shown. View entire blame