Version: 9.16.0
parserBase.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 CEA, EDF
2//
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.
7//
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.
12//
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
16//
17// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18//
19
20#include "parserBase.hxx"
21#include "Exception.hxx"
22#include "Proc.hxx"
23#include "Logger.hxx"
24#include <sstream>
25
26//#define _DEVDEBUG_
27#include "YacsTrace.hxx"
28#include <libxml/parserInternals.h>
29
31_xmlParserCtxt* saxContext;
32
33namespace YACS
34{
36 std::stack<parser*> parser::_stackParser;
37
39{
40 if(_level==0)
41 {
42 delete _counts;
43 }
44 else
45 {
46 DEBTRACE("Problem with parser: final stack level should be 0 and not " << _level);
47 }
48}
49
50std::stack<parser*>& parser::getStack()
51{
52 return _stackParser;
53}
54
56{
58 _stackParser.push(pp);
59 DEBTRACE("parser::SetUserDataAndPush, stack size: " << pp->_level);
60}
61
62void parser::onEnd(const XML_Char *el, parser* child)
63{
64 DEBTRACE("parser::onEnd: " << el)
65}
66
67void parser::charData(const XML_Char *s, int len)
68{
69 _content=_content+std::string(s,len);
70}
71
73{
74 DEBTRACE("parser::endParser, level: " <<_level);
75 _level=_level-1;
76 if(_level>0)
77 {
78 delete _counts;
79 _counts=_stackCount.top();
81 _stackCount.pop();
82 _stackOrder.pop();
83 }
84}
85
87{
88 DEBTRACE("parser::init, level: " <<_level);
89 if(_level>0)
90 {
91 _stackCount.push(_counts);
93 _counts=new std::map<std::string,int>;
94 }
95 _level=_level+1;
96 _counts->clear();
98}
99
101{
102 if((*_counts).find(el)==(*_counts).end())
103 (*_counts)[el]=1;
104 else
105 (*_counts)[el]=(*_counts)[el]+1;
106}
107
108void parser::checkOrder(std::string& el)
109{
110 if(_orders.count(el)==0)return;
111 if(_orders[el] < _orderState)
112 {
113 std::string msg="unexpected "+el+" element (wrong order)";
114 throw YACS::Exception(msg);
115 }
116 else if(_orders[el] > _orderState)
117 {
119 }
120}
121
122void parser::maxcount(std::string name, int max, std::string& el)
123{
124 if(el!=name)return;
125 if((*_counts)[name]>max)
126 {
127 std::stringstream msg;
128 msg <<"unexpected "+name+" element (count="<<(*_counts)[name];
129 msg <<" > maxOccurs=" << max << ")";
130 throw YACS::Exception(msg.str());
131 }
132}
133
134void parser::mincount(std::string name,int min )
135{
136 if((*_counts)[name]<min)
137 {
138 std::stringstream msg;
139 msg<<"expected "+name+" element (count="<<(*_counts)[name];
140 msg << " < minOccurs=" << min << ")";
141 throw YACS::Exception(msg.str());
142 }
143}
144
145void parser::maxchoice(std::string *names, int max, std::string& el)
146{
147 int i=0;
148 int ncount=0;
149 while (names[i]!= "")
150 {
151 ncount=ncount+(*_counts)[names[i]];
152 ++i;
153 }
154 if(ncount>max)
155 {
156 std::stringstream msg;
157 msg<<"unexpected "+el+" element (choice count="<<ncount<<" > maxOccurs=" << max << ")";
158 throw YACS::Exception(msg.str());
159 }
160}
161
162void parser::minchoice(std::string *names, int min)
163{
164 int i=0;
165 int ncount=0;
166 while (names[i]!= "")
167 {
168 ncount=ncount+(*_counts)[names[i]];
169 ++i;
170 }
171 if(ncount<min)
172 {
173 std::stringstream msg;
174 msg << "expected element ";
175 i=0;
176 while (names[i]!= "")
177 {
178 msg << names[i] << ",";
179 ++i;
180 }
181 msg << "(choice count="<<ncount<<" < minOccurs=" << min << ")";
182 throw YACS::Exception(msg.str());
183 }
184}
185
186void parser::required(const std::string& name, const XML_Char** attr)
187{
188 for (int i = 0; attr[i]; i += 2)
189 {
190 if(name == std::string(attr[i]))return;
191 }
192 throw YACS::Exception("Attribute: "+name+" is required");
193}
194
195void parser::buildAttr(const XML_Char** attr)
196{
197 if (!attr)
198 return;
199 for (int i = 0; attr[i]; i += 2)
200 {
201 DEBTRACE(attr[i] << "=" << attr[i + 1]);
202 }
203}
204
205void parser::onStart(const XML_Char* el, const XML_Char** attr)
206{
207 DEBTRACE( "parser::onStart: " << el );
212}
213
214void parser::logError(const std::string& reason)
215{
216 DEBTRACE( "parser::logError: " << _file );
217 currentProc->getLogger("parser")->error(reason,main_parser._file.c_str(),saxContext->input->line);
218}
219void parser::XML_SetUserData(_xmlParserCtxt* ctxt,
220 parser* par)
221{
222 ctxt->userData = par;
223}
224
226{
227 DEBTRACE("parser::start_document");
228 parser *currentParser = static_cast<parser *> (data);
229}
230
232{
233 DEBTRACE("parser::end_document");
234 parser *currentParser = static_cast<parser *> (data);
235}
236
238 const xmlChar* name,
239 const xmlChar** p)
240{
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);
245}
246
248 const xmlChar* name)
249{
250 DEBTRACE("parser::end_element");
251 parser *childParser = static_cast<parser *> (data);
252 _stackParser.pop();
253 parser* pp=_stackParser.top();
255 pp->onEnd((const XML_Char *)name, childParser);
256 childParser->endParser();
257 }
258
260 const xmlChar* ch,
261 int len)
262{
263 DEBTRACE("parser::characters " << len);
264 parser *currentParser = (parser *) (data);
265 currentParser->charData((const XML_Char*) ch, len);
266}
267
268void XMLCALL parser::comment(void* data,
269 const xmlChar* value)
270{
271 DEBTRACE("parser::comment");
272 parser *currentParser = static_cast<parser *> (data);
273}
274
276 const xmlChar* value,
277 int len)
278{
279 DEBTRACE("parser::cdata_block");
280 parser *currentParser = static_cast<parser *> (data);
281 currentParser->charData((const XML_Char*) value, len);
282}
283
284void XMLCALL parser::warning(void* data,
285 const char* fmt, ...)
286{
287 DEBTRACE("parser::warning");
288 parser *currentParser = static_cast<parser *> (data);
289 va_list args;
290 va_start(args, fmt);
291 std::string format = "%s";
292 if (format == fmt)
293 {
294 char* parv;
295 parv = va_arg(args, char*);
296 std::cerr << parv ;
297 }
298 else std::cerr << __FILE__ << " [" << __LINE__ << "] : "
299 << "error format not taken into account: " << fmt << std::endl;
300 va_end(args);
301}
302
303void XMLCALL parser::error(void* data,
304 const char* fmt, ...)
305{
306 DEBTRACE("parser::error");
307 parser *currentParser = static_cast<parser *> (data);
308 va_list args;
309 va_start(args, fmt);
310 std::string format = "%s";
311 if (format == fmt)
312 {
313 char* parv;
314 parv = va_arg(args, char*);
315 std::cerr << parv ;
316 }
317 else std::cerr << __FILE__ << " [" << __LINE__ << "] : "
318 << "error format not taken into account: " << fmt << std::endl;
319 va_end(args);
320}
321
323 const char* fmt, ...)
324{
325 DEBTRACE("parser::fatal_error");
326 parser *currentParser = static_cast<parser *> (data);
327 va_list args;
328 va_start(args, fmt);
329 std::string format = "%s";
330 if (format == fmt)
331 {
332 char* parv;
333 parv = va_arg(args, char*);
334 std::cerr << parv ;
335 }
336 else std::cerr << __FILE__ << " [" << __LINE__ << "] : "
337 << "error format not taken into account: " << fmt << std::endl;
338 va_end(args);
339}
340
341}
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
virtual void error(const std::string &message, const char *filename, int line)
Definition: Logger.cxx:50
Base class for all schema objects.
Definition: Proc.hxx:44
virtual Logger * getLogger(const std::string &name)
Definition: Proc.cxx:431
Proc * p
Definition: driver.cxx:216
char XML_Char
Definition: parserBase.hxx:37
YACS::ENGINE::Proc * currentProc
Definition: parserBase.cxx:30
_xmlParserCtxt * saxContext
Definition: parserBase.cxx:31
virtual void charData(const XML_Char *s, int len)
Definition: parserBase.cxx:67
std::string _content
Definition: parserBase.hxx:97
virtual void minchoice(std::string *names, int min)
Definition: parserBase.cxx:162
static void XMLCALL start_element(void *data, const xmlChar *name, const xmlChar **p)
Definition: parserBase.cxx:237
virtual void maxcount(std::string name, int max, std::string &el)
Definition: parserBase.cxx:122
static void XMLCALL warning(void *data, const char *fmt,...)
Definition: parserBase.cxx:284
virtual void init()
Definition: parserBase.cxx:86
virtual void pre()
Definition: parserBase.hxx:61
virtual void SetUserDataAndPush(parser *pp)
Definition: parserBase.cxx:55
virtual void mincount(std::string name, int min)
Definition: parserBase.cxx:134
std::stack< parser * > & getStack()
Definition: parserBase.cxx:50
virtual void checkOrder(std::string &el)
Definition: parserBase.cxx:108
virtual ~parser()
Definition: parserBase.cxx:38
static std::stack< parser * > _stackParser
Definition: parserBase.hxx:42
static void XMLCALL fatal_error(void *data, const char *fmt,...)
Definition: parserBase.cxx:322
virtual void onStart(const XML_Char *el, const XML_Char **attr)
Definition: parserBase.cxx:205
static void XMLCALL end_document(void *data)
Definition: parserBase.cxx:231
static void XMLCALL comment(void *data, const xmlChar *value)
Definition: parserBase.cxx:268
virtual void required(const std::string &name, const XML_Char **attr)
Definition: parserBase.cxx:186
virtual void buildAttr(const XML_Char **attr)
Definition: parserBase.cxx:195
static void XML_SetUserData(_xmlParserCtxt *ctxt, parser *par)
Definition: parserBase.cxx:219
static parser main_parser
Definition: parserBase.hxx:41
static void XMLCALL error(void *data, const char *fmt,...)
Definition: parserBase.cxx:303
std::map< std::string, int > * _counts
Definition: parserBase.hxx:98
static void XMLCALL cdata_block(void *data, const xmlChar *value, int len)
Definition: parserBase.cxx:275
static void XMLCALL end_element(void *data, const xmlChar *name)
Definition: parserBase.cxx:247
virtual void incrCount(const XML_Char *elem)
Definition: parserBase.cxx:100
virtual void maxchoice(std::string *names, int max, std::string &el)
Definition: parserBase.cxx:145
virtual void onEnd(const XML_Char *el, parser *child)
Definition: parserBase.cxx:62
std::string _file
Definition: parserBase.hxx:96
std::map< std::string, int > _orders
Definition: parserBase.hxx:99
std::stack< std::map< std::string, int > * > _stackCount
Definition: parserBase.hxx:102
static void XMLCALL start_document(void *data)
Definition: parserBase.cxx:225
virtual void endParser()
Definition: parserBase.cxx:72
void logError(const std::string &reason)
Definition: parserBase.cxx:214
static void XMLCALL characters(void *data, const xmlChar *ch, int len)
Definition: parserBase.cxx:259
std::stack< int > _stackOrder
Definition: parserBase.hxx:103
#define XMLCALL