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

# Content
1 /*
2 * 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 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * 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 *
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 */
41 #include <algorithm>
42 #include <stack>
43 #include <cstdio>
44 #include "io/SectionParserManager.hpp"
45 #include "utils/Trim.hpp"
46 #include "utils/simError.h"
47
48 namespace OpenMD {
49
50 SectionParserManager::~SectionParserManager() {
51 SectionParserManager::iterator i;
52 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
53 delete (i->sectionParser);
54 }
55 sectionParsers_.clear();
56 }
57
58 void SectionParserManager::parse(std::istream& input, ForceField& ff) {
59
60 //reset active flags
61 SectionParserManager::iterator i;
62 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
63 i->isActive = false;
64 }
65
66 const int bufferSize = 65535;
67 char buffer[bufferSize];
68 int lineNo = 0;
69 std::stack<std::string> sectionNameStack;
70 //scan through the input stream and find section names
71 while(input.getline(buffer, bufferSize)) {
72 ++lineNo;
73
74 std::string line = trimLeftCopy(buffer);
75 //a line begins with "//" is a comment line
76 if ( line.empty() || (line.size() >= 2 && line[0] == '/'
77 && line[1] == '/') ) {
78 continue;
79 } else {
80 StringTokenizer tokenizer(line);
81 if (tokenizer.countTokens() < 2) {
82 continue;
83 } else {
84 std::string keyword = tokenizer.nextToken();
85
86 if (keyword == "begin") {
87 std::string section = tokenizer.nextToken();
88 sectionNameStack.push(section);
89
90 i = std::find_if(sectionParsers_.begin(), sectionParsers_.end(),
91 SameSectionParserFunctor(section));
92 if (i == sectionParsers_.end()){
93 sprintf(painCave.errMsg,
94 "SectionParserManager Error: Can not find corresponding "
95 "section parser for %s\n",
96 section.c_str());
97 painCave.isFatal = 1;
98 simError();
99 } else {
100 if (i->isActive) {
101 sprintf(painCave.errMsg, "SectionParserManager Error:find multiple %s "
102 "section\n",
103 section.c_str());
104 painCave.isFatal = 1;
105 simError();
106 } else {
107 i->isActive = true;
108 i->lineNo = lineNo;
109 i->offset = input.tellg();
110 }
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 sectionNameStack.top().c_str(), section.c_str(), lineNo);
119 painCave.isFatal = 1;
120 simError();
121 }
122
123 } else {
124 continue;
125 }
126 }
127 }
128
129 }
130
131 if (!sectionNameStack.empty()) {
132 sprintf(painCave.errMsg, "SectionParserManager Error: stack is not empty\n");
133 painCave.isFatal = 1;
134 simError();
135 }
136
137 //invoke parser
138 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
139 if (i->isActive) {
140 //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 (i->sectionParser)->validateSection();
146 }
147 }
148
149 }
150
151 void SectionParserManager::push_front(SectionParser* sp) {
152 SectionParserManager::iterator i;
153 i = findSectionParser(sp->getSectionName());
154 if (i != sectionParsers_.end()) {
155 std::cerr << sp->getSectionName() << " section parser already exists"
156 << std::endl;
157 return;
158 }
159
160 SectionParserContext context;
161
162 if (sectionParsers_.empty()) {
163 context.priority = beginPriority_;
164 } else {
165 context.priority = sectionParsers_.front().priority - priorityDifference_;
166 }
167
168 context.sectionParser = sp;
169 context.lineNo = 0;
170 context.offset = 0;
171 context.isActive = false;
172
173 sectionParsers_.push_front(context);
174 }
175
176 void SectionParserManager::push_back(SectionParser* sp) {
177 SectionParserManager::iterator i;
178 i = findSectionParser(sp->getSectionName());
179 if (i != sectionParsers_.end()) {
180 std::cerr << sp->getSectionName() << " section parser already exists"
181 << std::endl;
182 return;
183 }
184
185 SectionParserContext context;
186 if (sectionParsers_.empty()) {
187 context.priority = beginPriority_;
188 } else {
189 context.priority = sectionParsers_.back().priority + priorityDifference_;
190 }
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 }
200
201 void SectionParserManager::insert(SectionParser* sp, int priority) {
202 SectionParserManager::iterator i;
203 i = findSectionParser(sp->getSectionName());
204 if (i != sectionParsers_.end()) {
205 std::cerr << sp->getSectionName() << " section parser already exists"
206 << std::endl;
207 }
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 sectionParsers_.push_back(context);
218 } else {
219
220 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
229 }
230 }
231
232 }
233
234
235 SectionParserManager::iterator SectionParserManager::findSectionParser(const std::string& sectionName) {
236 SectionParserManager::iterator i;
237 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
238 if (i->sectionParser->getSectionName() == sectionName) {
239 break;
240 }
241 }
242
243 return i;
244 }
245
246 }