| 39 |  | * such damages. | 
| 40 |  | */ | 
| 41 |  | #include <algorithm> | 
| 42 | + | #include <stack> | 
| 43 |  | #include "io/SectionParserManager.hpp" | 
| 44 |  | #include "utils/Trim.hpp" | 
| 45 | + | #include "utils/simError.h" | 
| 46 |  |  | 
| 47 |  | namespace oopse { | 
| 48 |  |  | 
| 65 |  | const int bufferSize = 65535; | 
| 66 |  | char buffer[bufferSize]; | 
| 67 |  | int lineNo = 0; | 
| 68 | + | std::stack<std::string> sectionNameStack; | 
| 69 |  | //scan through the input stream and find section names | 
| 70 |  | while(input.getline(buffer, bufferSize)) { | 
| 71 |  | ++lineNo; | 
| 72 |  |  | 
| 73 |  | std::string line = trimLeftCopy(buffer); | 
| 74 | < | //a line begins with "//" is comment | 
| 74 | > | //a line begins with "//" is a comment line | 
| 75 |  | if ( line.empty() || (line.size() >= 2 && line[0] == '/' && line[1] == '/')) { | 
| 76 |  | continue; | 
| 77 |  | } else { | 
| 81 |  | } else { | 
| 82 |  | std::string keyword = tokenizer.nextToken(); | 
| 83 |  |  | 
| 84 | < | if (keyword != "begin") { | 
| 85 | < | continue; | 
| 86 | < | } | 
| 84 | > | if (keyword == "begin") { | 
| 85 | > | std::string section = tokenizer.nextToken(); | 
| 86 | > | sectionNameStack.push(section); | 
| 87 |  |  | 
| 88 | < | std::string section = tokenizer.nextToken(); | 
| 89 | < |  | 
| 90 | < | i = std::find_if(sectionParsers_.begin(), sectionParsers_.end(), SameSectionParserFunctor(section)); | 
| 91 | < | if (i == sectionParsers_.end()){ | 
| 92 | < | //can not find corresponding section parser | 
| 93 | < | std::cerr << "Can not find corresponding section parser for section: " << section << std::endl; | 
| 88 | > | i = std::find_if(sectionParsers_.begin(), sectionParsers_.end(), SameSectionParserFunctor(section)); | 
| 89 | > | if (i == sectionParsers_.end()){ | 
| 90 | > | sprintf(painCave.errMsg, "SectionParserManager Error: Can not find corresponding section parser for %s\n", | 
| 91 | > | section.c_str()); | 
| 92 | > | painCave.isFatal = 1; | 
| 93 | > | simError(); | 
| 94 | > | } else { | 
| 95 | > | if (i->isActive) { | 
| 96 | > | sprintf(painCave.errMsg, "SectionParserManager Error:find multiple %s section\n", | 
| 97 | > | section.c_str()); | 
| 98 | > | painCave.isFatal = 1; | 
| 99 | > | simError(); | 
| 100 | > | } else { | 
| 101 | > | i->isActive = true; | 
| 102 | > | i->lineNo = lineNo; | 
| 103 | > | i->offset = input.tellg(); | 
| 104 | > | } | 
| 105 | > | } | 
| 106 | > | } else if (keyword == "end") { | 
| 107 | > | std::string section = tokenizer.nextToken(); | 
| 108 | > | if (sectionNameStack.top() == section) { | 
| 109 | > | sectionNameStack.pop(); | 
| 110 | > | } else { | 
| 111 | > | sprintf(painCave.errMsg, "SectionParserManager Error: begin %s and end %s does not match at line %d\n", | 
| 112 | > | sectionNameStack.top().c_str(), section.c_str(), lineNo); | 
| 113 | > | painCave.isFatal = 1; | 
| 114 | > | simError(); | 
| 115 | > | } | 
| 116 | > |  | 
| 117 |  | } else { | 
| 118 | < | i->isActive = true; | 
| 93 | < | i->lineNo = lineNo; | 
| 94 | < | i->offset = input.tellg(); | 
| 118 | > | continue; | 
| 119 |  | } | 
| 96 | – |  | 
| 120 |  | } | 
| 121 |  | } | 
| 99 | – |  | 
| 122 |  |  | 
| 123 |  | } | 
| 124 |  |  | 
| 125 | + | if (!sectionNameStack.empty()) { | 
| 126 | + | sprintf(painCave.errMsg, "SectionParserManager Error: stack is not empty\n"); | 
| 127 | + | painCave.isFatal = 1; | 
| 128 | + | simError(); | 
| 129 | + | } | 
| 130 | + |  | 
| 131 |  | //invoke parser | 
| 132 |  | for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) { | 
| 133 |  | if (i->isActive) { |