ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/io/SectionParserManager.cpp
Revision: 1401
Committed: Wed Jan 6 21:06:59 2010 UTC (15 years, 3 months ago) by jmarr
File size: 8091 byte(s)
Log Message:
Added missing cstdio include lines for gcc 4.4 compatibility

File Contents

# User Rev Content
1 gezelter 507 /*
2 gezelter 246 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9 gezelter 1390 * 1. Redistributions of source code must retain the above copyright
10 gezelter 246 * notice, this list of conditions and the following disclaimer.
11     *
12 gezelter 1390 * 2. Redistributions in binary form must reproduce the above copyright
13 gezelter 246 * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31 gezelter 1390 *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39     * [4] Vardeman & Gezelter, in progress (2009).
40 gezelter 246 */
41     #include <algorithm>
42 tim 413 #include <stack>
43 jmarr 1401 #include <cstdio>
44 gezelter 246 #include "io/SectionParserManager.hpp"
45     #include "utils/Trim.hpp"
46 tim 413 #include "utils/simError.h"
47 gezelter 246
48 gezelter 1390 namespace OpenMD {
49 gezelter 246
50 gezelter 507 SectionParserManager::~SectionParserManager() {
51 gezelter 246 SectionParserManager::iterator i;
52     for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
53 gezelter 507 delete (i->sectionParser);
54 gezelter 246 }
55     sectionParsers_.clear();
56 gezelter 507 }
57 gezelter 246
58 gezelter 507 void SectionParserManager::parse(std::istream& input, ForceField& ff) {
59 gezelter 246
60     //reset active flags
61     SectionParserManager::iterator i;
62     for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
63 gezelter 507 i->isActive = false;
64 gezelter 246 }
65    
66     const int bufferSize = 65535;
67     char buffer[bufferSize];
68     int lineNo = 0;
69 tim 413 std::stack<std::string> sectionNameStack;
70 gezelter 246 //scan through the input stream and find section names
71     while(input.getline(buffer, bufferSize)) {
72 gezelter 507 ++lineNo;
73 gezelter 246
74 gezelter 507 std::string line = trimLeftCopy(buffer);
75     //a line begins with "//" is a comment line
76 chrisfen 514 if ( line.empty() || (line.size() >= 2 && line[0] == '/'
77     && line[1] == '/') ) {
78 gezelter 507 continue;
79     } else {
80     StringTokenizer tokenizer(line);
81     if (tokenizer.countTokens() < 2) {
82     continue;
83     } else {
84     std::string keyword = tokenizer.nextToken();
85 gezelter 246
86 gezelter 507 if (keyword == "begin") {
87     std::string section = tokenizer.nextToken();
88     sectionNameStack.push(section);
89 chrisfen 514
90     i = std::find_if(sectionParsers_.begin(), sectionParsers_.end(),
91     SameSectionParserFunctor(section));
92 gezelter 507 if (i == sectionParsers_.end()){
93 chrisfen 514 sprintf(painCave.errMsg,
94     "SectionParserManager Error: Can not find corresponding "
95     "section parser for %s\n",
96     section.c_str());
97 gezelter 507 painCave.isFatal = 1;
98     simError();
99     } else {
100     if (i->isActive) {
101 chrisfen 514 sprintf(painCave.errMsg, "SectionParserManager Error:find multiple %s "
102     "section\n",
103     section.c_str());
104     painCave.isFatal = 1;
105     simError();
106 gezelter 507 } else {
107 chrisfen 514 i->isActive = true;
108     i->lineNo = lineNo;
109     i->offset = input.tellg();
110 gezelter 507 }
111     }
112     } else if (keyword == "end") {
113     std::string section = tokenizer.nextToken();
114     if (sectionNameStack.top() == section) {
115     sectionNameStack.pop();
116     } else {
117     sprintf(painCave.errMsg, "SectionParserManager Error: begin %s and end %s does not match at line %d\n",
118 chrisfen 514 sectionNameStack.top().c_str(), section.c_str(), lineNo);
119 gezelter 507 painCave.isFatal = 1;
120     simError();
121     }
122 chrisfen 514
123 gezelter 507 } else {
124     continue;
125     }
126     }
127     }
128 chrisfen 514
129 gezelter 246 }
130 chrisfen 514
131 tim 413 if (!sectionNameStack.empty()) {
132 gezelter 507 sprintf(painCave.errMsg, "SectionParserManager Error: stack is not empty\n");
133     painCave.isFatal = 1;
134     simError();
135 tim 413 }
136 chrisfen 514
137 gezelter 246 //invoke parser
138     for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
139 gezelter 507 if (i->isActive) {
140 chrisfen 514 //C++ standard does not guarantee seekg reset EOF, in that case, seekg will fail
141     //It is always a good idea to call clear() before seek
142     input.clear();
143     input.seekg(i->offset);
144     (i->sectionParser)->parse(input, ff, i->lineNo);
145 tim 749 (i->sectionParser)->validateSection();
146 gezelter 507 }
147 gezelter 246 }
148    
149 gezelter 507 }
150 chrisfen 514
151 gezelter 507 void SectionParserManager::push_front(SectionParser* sp) {
152 gezelter 246 SectionParserManager::iterator i;
153     i = findSectionParser(sp->getSectionName());
154     if (i != sectionParsers_.end()) {
155 gezelter 1277 std::cerr << sp->getSectionName() << " section parser already exists"
156 chrisfen 514 << std::endl;
157 gezelter 507 return;
158 gezelter 246 }
159    
160     SectionParserContext context;
161    
162     if (sectionParsers_.empty()) {
163 gezelter 507 context.priority = beginPriority_;
164 gezelter 246 } else {
165 gezelter 507 context.priority = sectionParsers_.front().priority - priorityDifference_;
166 gezelter 246 }
167 chrisfen 514
168 gezelter 246 context.sectionParser = sp;
169     context.lineNo = 0;
170     context.offset = 0;
171     context.isActive = false;
172    
173     sectionParsers_.push_front(context);
174 gezelter 507 }
175 gezelter 246
176 gezelter 507 void SectionParserManager::push_back(SectionParser* sp) {
177 gezelter 246 SectionParserManager::iterator i;
178     i = findSectionParser(sp->getSectionName());
179     if (i != sectionParsers_.end()) {
180 gezelter 1277 std::cerr << sp->getSectionName() << " section parser already exists"
181 chrisfen 514 << std::endl;
182 gezelter 507 return;
183 gezelter 246 }
184    
185     SectionParserContext context;
186     if (sectionParsers_.empty()) {
187 gezelter 507 context.priority = beginPriority_;
188 gezelter 246 } else {
189 gezelter 507 context.priority = sectionParsers_.back().priority + priorityDifference_;
190 gezelter 246 }
191    
192     context.sectionParser = sp;
193     context.lineNo = 0;
194     context.offset = 0;
195     context.isActive = false;
196    
197     sectionParsers_.push_back(context);
198    
199 gezelter 507 }
200 gezelter 246
201 gezelter 507 void SectionParserManager::insert(SectionParser* sp, int priority) {
202 gezelter 246 SectionParserManager::iterator i;
203     i = findSectionParser(sp->getSectionName());
204     if (i != sectionParsers_.end()) {
205 gezelter 1277 std::cerr << sp->getSectionName() << " section parser already exists"
206 chrisfen 514 << std::endl;
207 gezelter 246 }
208    
209     SectionParserContext context;
210     context.priority = priority;
211     context.sectionParser = sp;
212     context.lineNo = 0;
213     context.offset = 0;
214     context.isActive = false;
215    
216     if (sectionParsers_.empty()) {
217 gezelter 507 sectionParsers_.push_back(context);
218 gezelter 246 } else {
219    
220 gezelter 507 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
221     if (i->priority == priority) {
222     std::cerr << "Priority " << priority << " already used" << std::endl;
223     return;
224     } else if (i->priority > priority) {
225     sectionParsers_.insert(i, context);
226     break;
227     }
228 gezelter 246
229 gezelter 507 }
230 gezelter 246 }
231    
232 gezelter 507 }
233 gezelter 246
234    
235 gezelter 507 SectionParserManager::iterator SectionParserManager::findSectionParser(const std::string& sectionName) {
236 gezelter 246 SectionParserManager::iterator i;
237     for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
238 gezelter 507 if (i->sectionParser->getSectionName() == sectionName) {
239 chrisfen 514 break;
240 gezelter 507 }
241 gezelter 246 }
242    
243     return i;
244 gezelter 507 }
245 gezelter 246
246     }