initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / db / dictionary / entry / entryIO.C
blob509c892e1d99cac863e2a6c6cd29183a2ed98c29
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "primitiveEntry.H"
28 #include "dictionaryEntry.H"
29 #include "functionEntry.H"
30 #include "includeEntry.H"
31 #include "inputModeEntry.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
37     token keywordToken;
39     // Read the next valid token discarding spurious ';'s
40     do
41     {
42         if
43         (
44             is.read(keywordToken).bad()
45          || is.eof()
46          || !keywordToken.good()
47         )
48         {
49             return false;
50         }
51     }
52     while (keywordToken == token::END_STATEMENT);
54     // If the token is a valid keyword set 'keyword' return true...
55     if (keywordToken.isWord())
56     {
57         keyword = keywordToken.wordToken();
58         return true;
59     }
60     else if (keywordToken.isString())
61     {
62         // Enable wildcards
63         keyword = keywordToken.stringToken();
64         return true;
65     }
66     // If it is the end of the dictionary or file return false...
67     else if (keywordToken == token::END_BLOCK || is.eof())
68     {
69         return false;
70     }
71     // Otherwise the token is invalid
72     else
73     {
74         cerr<< "--> FOAM Warning : " << std::endl
75             << "    From function "
76             << "entry::getKeyword(keyType&, Istream&)" << std::endl
77             << "    in file " << __FILE__
78             << " at line " << __LINE__ << std::endl
79             << "    Reading " << is.name().c_str() << std::endl
80             << "    found " << keywordToken << std::endl
81             << "    expected either " << token::END_BLOCK << " or EOF"
82             << std::endl;
84         return false;
85     }
89 bool Foam::entry::New(dictionary& parentDict, Istream& is)
91     is.fatalCheck("entry::New(const dictionary& parentDict, Istream&)");
93     keyType keyword;
95     // Get the next keyword and if invalid return false
96     if (!getKeyword(keyword, is))
97     {
98         return false;
99     }
100     else  // Keyword starts entry ...
101     {
102         if (keyword[0] == '#')         // ... Function entry
103         {
104             word functionName = keyword(1, keyword.size()-1);
105             return functionEntry::execute(functionName, parentDict, is);
106         }
107         else if (keyword[0] == '$')    // ... Substitution entry
108         {
109             parentDict.substituteKeyword(keyword);
110             return true;
111         }
112         else if (keyword == "include") // ... For backward compatibility
113         {
114             return functionEntries::includeEntry::execute(parentDict, is);
115         }
116         else                           // ... Data entries
117         {
118             token nextToken(is);
119             is.putBack(nextToken);
121             // Deal with duplicate entries
122             bool mergeEntry = false;
124             // See (using exact match) if entry already present
125             entry* existingPtr = parentDict.lookupEntryPtr
126             (
127                 keyword,
128                 false,
129                 false
130             );
132             if (existingPtr)
133             {
134                 if (functionEntries::inputModeEntry::merge())
135                 {
136                     mergeEntry = true;
137                 }
138                 else if (functionEntries::inputModeEntry::overwrite())
139                 {
140                     // clear dictionary so merge acts like overwrite
141                     if (existingPtr->isDict())
142                     {
143                         existingPtr->dict().clear();
144                     }
145                     mergeEntry = true;
146                 }
147                 else if (functionEntries::inputModeEntry::protect())
148                 {
149                     // read and discard the entry
150                     if (nextToken == token::BEGIN_BLOCK)
151                     {
152                         dictionaryEntry dummy(keyword, parentDict, is);
153                     }
154                     else
155                     {
156                         primitiveEntry  dummy(keyword, parentDict, is);
157                     }
158                     return true;
159                 }
160                 else if (functionEntries::inputModeEntry::error())
161                 {
162                     FatalIOErrorIn
163                     (
164                         "entry::New(const dictionary& parentDict, Istream&)",
165                         is
166                     )
167                         << "ERROR! duplicate entry: " << keyword
168                         << exit(FatalIOError);
170                     return false;
171                 }
172             }
174             if (nextToken == token::BEGIN_BLOCK)
175             {
176                 return parentDict.add
177                 (
178                     new dictionaryEntry(keyword, parentDict, is),
179                     mergeEntry
180                 );
181             }
182             else
183             {
184                 return parentDict.add
185                 (
186                     new primitiveEntry(keyword, parentDict, is),
187                     mergeEntry
188                 );
189             }
190         }
191     }
195 Foam::autoPtr<Foam::entry> Foam::entry::New(Istream& is)
197     is.fatalCheck("entry::New(Istream&)");
199     keyType keyword;
201     // Get the next keyword and if invalid return false
202     if (!getKeyword(keyword, is))
203     {
204         return autoPtr<entry>(NULL);
205     }
206     else // Keyword starts entry ...
207     {
208         token nextToken(is);
209         is.putBack(nextToken);
211         if (nextToken == token::BEGIN_BLOCK)
212         {
213             return autoPtr<entry>
214             (
215                 new dictionaryEntry(keyword, dictionary::null, is)
216             );
217         }
218         else
219         {
220             return autoPtr<entry>
221             (
222                 new primitiveEntry(keyword, is)
223             );
224         }
225     }
229 // * * * * * * * * * * * * * Ostream operator  * * * * * * * * * * * * * * * //
231 Foam::Ostream& Foam::operator<<(Ostream& os, const entry& e)
233     e.write(os);
234     return os;
238 // ************************************************************************* //