1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "parserBase.hxx"
21 #include "Exception.hxx"
27 #include "YacsTrace.hxx"
28 #include <libxml/parserInternals.h>
30 YACS::ENGINE::Proc* currentProc;
31 _xmlParserCtxt* saxContext;
35 parser parser::main_parser;
36 std::stack<parser*> parser::_stackParser;
46 DEBTRACE("Problem with parser: final stack level should be 0 and not " << _level);
50 std::stack<parser*>& parser::getStack()
55 void parser::SetUserDataAndPush(parser* pp)
57 XML_SetUserData(saxContext,pp);
58 _stackParser.push(pp);
59 DEBTRACE("parser::SetUserDataAndPush, stack size: " << sp.size());
62 void parser::onEnd(const XML_Char *el, parser* child)
64 DEBTRACE("parser::onEnd: " << el)
67 void parser::charData(const XML_Char *s, int len)
69 _content=_content+std::string(s,len);
72 void parser::endParser()
74 DEBTRACE("parser::endParser, level: " <<_level);
79 _counts=_stackCount.top();
80 _orderState=_stackOrder.top();
88 DEBTRACE("parser::init, level: " <<_level);
91 _stackCount.push(_counts);
92 _stackOrder.push(_orderState);
93 _counts=new std::map<std::string,int>;
100 void parser::incrCount(const XML_Char *el)
102 if((*_counts).find(el)==(*_counts).end())
105 (*_counts)[el]=(*_counts)[el]+1;
108 void parser::checkOrder(std::string& el)
110 if(_orders.count(el)==0)return;
111 if(_orders[el] < _orderState)
113 std::string msg="unexpected "+el+" element (wrong order)";
114 throw YACS::Exception(msg);
116 else if(_orders[el] > _orderState)
118 _orderState=_orders[el];
122 void parser::maxcount(std::string name, int max, std::string& el)
125 if((*_counts)[name]>max)
127 std::stringstream msg;
128 msg <<"unexpected "+name+" element (count="<<(*_counts)[name];
129 msg <<" > maxOccurs=" << max << ")";
130 throw YACS::Exception(msg.str());
134 void parser::mincount(std::string name,int min )
136 if((*_counts)[name]<min)
138 std::stringstream msg;
139 msg<<"expected "+name+" element (count="<<(*_counts)[name];
140 msg << " < minOccurs=" << min << ")";
141 throw YACS::Exception(msg.str());
145 void parser::maxchoice(std::string *names, int max, std::string& el)
149 while (names[i]!= "")
151 ncount=ncount+(*_counts)[names[i]];
156 std::stringstream msg;
157 msg<<"unexpected "+el+" element (choice count="<<ncount<<" > maxOccurs=" << max << ")";
158 throw YACS::Exception(msg.str());
162 void parser::minchoice(std::string *names, int min)
166 while (names[i]!= "")
168 ncount=ncount+(*_counts)[names[i]];
173 std::stringstream msg;
174 msg << "expected element ";
176 while (names[i]!= "")
178 msg << names[i] << ",";
181 msg << "(choice count="<<ncount<<" < minOccurs=" << min << ")";
182 throw YACS::Exception(msg.str());
186 void parser::required(const std::string& name, const XML_Char** attr)
188 for (int i = 0; attr[i]; i += 2)
190 if(name == std::string(attr[i]))return;
192 throw YACS::Exception("Attribute: "+name+" is required");
195 void parser::buildAttr(const XML_Char** attr)
199 for (int i = 0; attr[i]; i += 2)
201 DEBTRACE(attr[i] << "=" << attr[i + 1]);
205 void parser::onStart(const XML_Char* el, const XML_Char** attr)
207 DEBTRACE( "parser::onStart: " << el );
208 SetUserDataAndPush(&main_parser);
211 main_parser.buildAttr(attr);
214 void parser::logError(const std::string& reason)
216 DEBTRACE( "parser::logError: " << _file );
217 currentProc->getLogger("parser")->error(reason,main_parser._file.c_str(),saxContext->input->line);
219 void parser::XML_SetUserData(_xmlParserCtxt* ctxt,
222 ctxt->userData = par;
225 void XMLCALL parser::start_document(void* data)
227 DEBTRACE("parser::start_document");
228 parser *currentParser = static_cast<parser *> (data);
231 void XMLCALL parser::end_document(void* data)
233 DEBTRACE("parser::end_document");
234 parser *currentParser = static_cast<parser *> (data);
237 void XMLCALL parser::start_element(void* data,
241 DEBTRACE("parser::start_element " << name);
242 parser *currentParser = static_cast<parser *> (data);
243 currentParser->incrCount((const XML_Char *)name);
244 currentParser->onStart((const XML_Char *)name, (const XML_Char **)p);
247 void XMLCALL parser::end_element(void* data,
250 DEBTRACE("parser::end_element");
251 parser *childParser = static_cast<parser *> (data);
253 parser* pp=_stackParser.top();
254 XML_SetUserData(saxContext, pp);
255 pp->onEnd((const XML_Char *)name, childParser);
256 childParser->endParser();
259 void XMLCALL parser::characters(void* data,
263 DEBTRACE("parser::characters " << len);
264 parser *currentParser = (parser *) (data);
265 currentParser->charData((const XML_Char*) ch, len);
268 void XMLCALL parser::comment(void* data,
269 const xmlChar* value)
271 DEBTRACE("parser::comment");
272 parser *currentParser = static_cast<parser *> (data);
275 void XMLCALL parser::cdata_block(void* data,
276 const xmlChar* value,
279 DEBTRACE("parser::cdata_block");
280 parser *currentParser = static_cast<parser *> (data);
281 currentParser->charData((const XML_Char*) value, len);
284 void XMLCALL parser::warning(void* data,
285 const char* fmt, ...)
287 DEBTRACE("parser::warning");
288 parser *currentParser = static_cast<parser *> (data);
291 std::string format = "%s";
295 parv = va_arg(args, char*);
298 else std::cerr << __FILE__ << " [" << __LINE__ << "] : "
299 << "error format not taken into account: " << fmt << std::endl;
303 void XMLCALL parser::error(void* data,
304 const char* fmt, ...)
306 DEBTRACE("parser::error");
307 parser *currentParser = static_cast<parser *> (data);
310 std::string format = "%s";
314 parv = va_arg(args, char*);
317 else std::cerr << __FILE__ << " [" << __LINE__ << "] : "
318 << "error format not taken into account: " << fmt << std::endl;
322 void XMLCALL parser::fatal_error(void* data,
323 const char* fmt, ...)
325 DEBTRACE("parser::fatal_error");
326 parser *currentParser = static_cast<parser *> (data);
329 std::string format = "%s";
333 parv = va_arg(args, char*);
336 else std::cerr << __FILE__ << " [" << __LINE__ << "] : "
337 << "error format not taken into account: " << fmt << std::endl;