ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/io/SectionParserManager.cpp
(Generate patch)

Comparing trunk/src/io/SectionParserManager.cpp (file contents):
Revision 246 by gezelter, Wed Jan 12 22:41:40 2005 UTC vs.
Revision 1401 by jmarr, Wed Jan 6 21:06:59 2010 UTC

# Line 1 | Line 1
1 < /*
1 > /*
2   * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3   *
4   * The University of Notre Dame grants you ("Licensee") a
# Line 6 | Line 6
6   * redistribute this software in source and binary code form, provided
7   * that the following conditions are met:
8   *
9 < * 1. Acknowledgement of the program authors must be made in any
10 < *    publication of scientific results based in part on use of the
11 < *    program.  An acceptable form of acknowledgement is citation of
12 < *    the article in which the program was described (Matthew
13 < *    A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 < *    J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 < *    Parallel Simulation Engine for Molecular Dynamics,"
16 < *    J. Comput. Chem. 26, pp. 252-271 (2005))
17 < *
18 < * 2. Redistributions of source code must retain the above copyright
9 > * 1. Redistributions of source code must retain the above copyright
10   *    notice, this list of conditions and the following disclaimer.
11   *
12 < * 3. Redistributions in binary form must reproduce the above copyright
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.
# Line 37 | Line 28
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 oopse {
48 > namespace OpenMD {
49  
50 < SectionParserManager::~SectionParserManager() {
50 >  SectionParserManager::~SectionParserManager() {
51      SectionParserManager::iterator i;
52      for (i = sectionParsers_.begin(); i != sectionParsers_.end(); ++i) {
53 <        delete (i->sectionParser);
53 >      delete (i->sectionParser);
54      }
55      sectionParsers_.clear();
56 < }
56 >  }
57  
58 < void SectionParserManager::parse(std::istream& input, ForceField& ff) {
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;
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;
72 >      ++lineNo;
73          
74 <        std::string line = trimLeftCopy(buffer);
75 <        //a line begins with "//" is comment
76 <        if ( line.empty() || (line.size() >= 2 && line[0] == '/' && line[1] == '/')) {
77 <            continue;
78 <        } else {        
79 <            StringTokenizer tokenizer(line);
80 <            if (tokenizer.countTokens() < 2) {
81 <                continue;
82 <            } else {
83 <                std::string keyword = tokenizer.nextToken();
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 <                    continue;
88 <                }
89 <
90 <                std::string section = tokenizer.nextToken();
91 <
92 <                i = std::find_if(sectionParsers_.begin(), sectionParsers_.end(), SameSectionParserFunctor(section));
93 <                if (i == sectionParsers_.end()){
94 <                    //can not find corresponding section parser
95 <                    std::cerr << "Can not find corresponding section parser for section: " << section << std::endl;
96 <                } else {
97 <                    i->isActive = true;
98 <                    i->lineNo = lineNo;
99 <                    i->offset = input.tellg();
100 <                }
101 <                
102 <            }
103 <        }
104 <
105 <        
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 <
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 <        }
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) {
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 is alway existed" << std::endl;
156 <        return;
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_;
163 >      context.priority = beginPriority_;
164      } else {
165 <        context.priority = sectionParsers_.front().priority - priorityDifference_;
165 >      context.priority = sectionParsers_.front().priority - priorityDifference_;
166      }
167 <
167 >    
168      context.sectionParser = sp;
169      context.lineNo = 0;
170      context.offset = 0;
171      context.isActive = false;
172  
173      sectionParsers_.push_front(context);
174 < }
174 >  }
175  
176 < void SectionParserManager::push_back(SectionParser* sp) {
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 is alway existed" << std::endl;
181 <        return;
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_;
187 >      context.priority = beginPriority_;
188      } else {
189 <        context.priority = sectionParsers_.back().priority + priorityDifference_;
189 >      context.priority = sectionParsers_.back().priority + priorityDifference_;
190      }
191  
192      context.sectionParser = sp;
# Line 159 | Line 196 | void SectionParserManager::push_back(SectionParser* sp
196  
197      sectionParsers_.push_back(context);
198  
199 < }
199 >  }
200  
201 < void SectionParserManager::insert(SectionParser* sp, int priority) {
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 is alway existed" << std::endl;
205 >      std::cerr << sp->getSectionName() << " section parser already exists"
206 >      << std::endl;
207      }
208  
209      SectionParserContext context;    
# Line 176 | Line 214 | void SectionParserManager::insert(SectionParser* sp, i
214      context.isActive = false;
215  
216      if (sectionParsers_.empty()) {
217 <        sectionParsers_.push_back(context);
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 <            }
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 <        }
229 >      }
230      }
231  
232 < }
232 >  }
233  
234  
235 < SectionParserManager::iterator SectionParserManager::findSectionParser(const std::string& sectionName) {
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 <        }
238 >      if (i->sectionParser->getSectionName() == sectionName) {
239 >        break;
240 >      }
241      }
242  
243      return i;
244 < }
244 >  }
245  
246   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines