47#include "io/SectionParserManager.hpp"
54#include "utils/Trim.hpp"
55#include "utils/simError.h"
59 SectionParserManager::~SectionParserManager() {
60 SectionParserManager::iterator i;
61 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
62 delete (i->sectionParser);
64 sectionParsers_.clear();
67 void SectionParserManager::parse(std::istream& input,
ForceField& ff) {
69 SectionParserManager::iterator i;
70 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
74 const int bufferSize = 65535;
75 char buffer[bufferSize];
77 std::stack<std::string> sectionNameStack;
79 while (input.getline(buffer, bufferSize)) {
82 std::string line =
stripComments(Utils::trimLeftCopy(buffer));
85 (line.size() >= 2 && line[0] ==
'/' && line[1] ==
'/')) {
88 StringTokenizer tokenizer(line);
89 if (tokenizer.countTokens() < 2) {
92 std::string keyword = tokenizer.nextToken();
94 if (keyword ==
"begin") {
95 std::string section = tokenizer.nextToken();
96 sectionNameStack.push(section);
98 i = std::find_if(sectionParsers_.begin(), sectionParsers_.end(),
99 SameSectionParserFunctor(section));
100 if (i == sectionParsers_.end()) {
101 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
102 "SectionParserManager Error: Can not find corresponding "
103 "section parser for %s\n",
105 painCave.isFatal = 1;
109 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
110 "SectionParserManager Error: Found multiple %s "
113 painCave.isFatal = 1;
118 i->offset = input.tellg();
121 }
else if (keyword ==
"end") {
122 std::string section = tokenizer.nextToken();
123 if (sectionNameStack.top() == section) {
124 sectionNameStack.pop();
126 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
127 "SectionParserManager Error: begin %s "
128 "and end %s do not match at line %d\n",
129 sectionNameStack.top().c_str(), section.c_str(), lineNo);
130 painCave.isFatal = 1;
140 if (!sectionNameStack.empty()) {
141 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
142 "SectionParserManager Error: Stack is not empty.\n"
143 "\tCheck for matching begin / end lines.\n");
144 painCave.isFatal = 1;
149 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
155 input.seekg(i->offset);
156 (i->sectionParser)->parse(input, ff, i->lineNo);
157 (i->sectionParser)->validateSection(ff);
163 SectionParserManager::iterator i;
164 i = findSectionParser(sp->getSectionName());
165 if (i != sectionParsers_.end()) {
166 std::cerr << sp->getSectionName() <<
" section parser already exists"
171 SectionParserContext context;
173 if (sectionParsers_.empty()) {
174 context.priority = beginPriority_;
176 context.priority = sectionParsers_.front().priority - priorityDifference_;
179 context.sectionParser = sp;
182 context.isActive =
false;
184 sectionParsers_.push_front(context);
188 SectionParserManager::iterator i;
189 i = findSectionParser(sp->getSectionName());
190 if (i != sectionParsers_.end()) {
191 std::cerr << sp->getSectionName() <<
" section parser already exists"
196 SectionParserContext context;
197 if (sectionParsers_.empty()) {
198 context.priority = beginPriority_;
200 context.priority = sectionParsers_.back().priority + priorityDifference_;
203 context.sectionParser = sp;
206 context.isActive =
false;
208 sectionParsers_.push_back(context);
211 void SectionParserManager::insert(
SectionParser* sp,
int priority) {
212 SectionParserManager::iterator i;
213 i = findSectionParser(sp->getSectionName());
214 if (i != sectionParsers_.end()) {
215 std::cerr << sp->getSectionName() <<
" section parser already exists"
219 SectionParserContext context;
220 context.priority = priority;
221 context.sectionParser = sp;
224 context.isActive =
false;
226 if (sectionParsers_.empty()) {
227 sectionParsers_.push_back(context);
229 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
230 if (i->priority == priority) {
231 std::cerr <<
"Priority " << priority <<
" already used" << std::endl;
233 }
else if (i->priority > priority) {
234 sectionParsers_.insert(i, context);
241 SectionParserManager::iterator SectionParserManager::findSectionParser(
242 const std::string& sectionName) {
243 SectionParserManager::iterator i;
244 for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
245 if (i->sectionParser->getSectionName() == sectionName) {
break; }
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string stripComments(const std::string &S)
Strip comments from a string.