44#include "io/SectionParserManager.hpp"
50#include "utils/Trim.hpp"
51#include "utils/simError.h"
55 SectionParserManager::~SectionParserManager() {
56 SectionParserManager::iterator i;
57 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
58 delete (i->sectionParser);
60 sectionParsers_.clear();
63 void SectionParserManager::parse(std::istream& input, ForceField& ff) {
65 SectionParserManager::iterator i;
66 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
70 const int bufferSize = 65535;
71 char buffer[bufferSize];
73 std::stack<std::string> sectionNameStack;
75 while (input.getline(buffer, bufferSize)) {
78 std::string line = Utils::trimLeftCopy(buffer);
81 (line.size() >= 2 && line[0] ==
'/' && line[1] ==
'/')) {
84 StringTokenizer tokenizer(line);
85 if (tokenizer.countTokens() < 2) {
88 std::string keyword = tokenizer.nextToken();
90 if (keyword ==
"begin") {
91 std::string section = tokenizer.nextToken();
92 sectionNameStack.push(section);
94 i = std::find_if(sectionParsers_.begin(), sectionParsers_.end(),
95 SameSectionParserFunctor(section));
96 if (i == sectionParsers_.end()) {
97 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
98 "SectionParserManager Error: Can not find corresponding "
99 "section parser for %s\n",
101 painCave.isFatal = 1;
105 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
106 "SectionParserManager Error: Found multiple %s "
109 painCave.isFatal = 1;
114 i->offset = input.tellg();
117 }
else if (keyword ==
"end") {
118 std::string section = tokenizer.nextToken();
119 if (sectionNameStack.top() == section) {
120 sectionNameStack.pop();
122 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
123 "SectionParserManager Error: begin %s "
124 "and end %s do not match at line %d\n",
125 sectionNameStack.top().c_str(), section.c_str(), lineNo);
126 painCave.isFatal = 1;
136 if (!sectionNameStack.empty()) {
137 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
138 "SectionParserManager Error: Stack is not empty\n");
139 painCave.isFatal = 1;
144 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
150 input.seekg(i->offset);
151 (i->sectionParser)->parse(input, ff, i->lineNo);
152 (i->sectionParser)->validateSection(ff);
157 void SectionParserManager::push_front(SectionParser* sp) {
158 SectionParserManager::iterator i;
159 i = findSectionParser(sp->getSectionName());
160 if (i != sectionParsers_.end()) {
161 std::cerr << sp->getSectionName() <<
" section parser already exists"
166 SectionParserContext context;
168 if (sectionParsers_.empty()) {
169 context.priority = beginPriority_;
171 context.priority = sectionParsers_.front().priority - priorityDifference_;
174 context.sectionParser = sp;
177 context.isActive =
false;
179 sectionParsers_.push_front(context);
182 void SectionParserManager::push_back(SectionParser* sp) {
183 SectionParserManager::iterator i;
184 i = findSectionParser(sp->getSectionName());
185 if (i != sectionParsers_.end()) {
186 std::cerr << sp->getSectionName() <<
" section parser already exists"
191 SectionParserContext context;
192 if (sectionParsers_.empty()) {
193 context.priority = beginPriority_;
195 context.priority = sectionParsers_.back().priority + priorityDifference_;
198 context.sectionParser = sp;
201 context.isActive =
false;
203 sectionParsers_.push_back(context);
206 void SectionParserManager::insert(SectionParser* sp,
int priority) {
207 SectionParserManager::iterator i;
208 i = findSectionParser(sp->getSectionName());
209 if (i != sectionParsers_.end()) {
210 std::cerr << sp->getSectionName() <<
" section parser already exists"
214 SectionParserContext context;
215 context.priority = priority;
216 context.sectionParser = sp;
219 context.isActive =
false;
221 if (sectionParsers_.empty()) {
222 sectionParsers_.push_back(context);
224 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
225 if (i->priority == priority) {
226 std::cerr <<
"Priority " << priority <<
" already used" << std::endl;
228 }
else if (i->priority > priority) {
229 sectionParsers_.insert(i, context);
236 SectionParserManager::iterator SectionParserManager::findSectionParser(
237 const std::string& sectionName) {
238 SectionParserManager::iterator i;
239 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
240 if (i->sectionParser->getSectionName() == sectionName) {
break; }
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.