Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / yacsloader / parserBase.cxx
1
2 #include "parserBase.hxx"
3 #include "Exception.hxx"
4 #include "Proc.hxx"
5 #include "Logger.hxx"
6 #include <sstream>
7
8 //#define _DEVDEBUG_
9 #include "YacsTrace.hxx"
10
11 YACS::ENGINE::Proc* currentProc;
12 XML_Parser p ;
13 std::stack<YACS::parser*> sp;
14
15 namespace YACS
16 {
17   parser parser::main_parser;
18
19 parser::~parser()
20 {
21   if(_level==0)
22     {
23       delete _counts;
24     }
25   else
26     {
27       DEBTRACE("Problem with parser: final stack level should be 0 and not " << _level);
28     }
29 }
30
31 std::stack<parser*>& parser::getStack()
32 {
33   return sp;
34 }
35
36 void parser::SetUserDataAndPush(parser* pp)
37 {
38   XML_SetUserData(p,pp);
39   sp.push(pp);
40   DEBTRACE("parser::SetUserDataAndPush, stack size: " << sp.size());
41 }
42
43 void XMLCALL parser::start(void *data, const XML_Char* el, const XML_Char** attr)
44 {
45   DEBTRACE("parser::start, stack size: " << sp.size());
46   parser* pp=static_cast <parser *> (data);
47   pp->incrCount(el);
48   pp->onStart(el,attr);
49 }
50
51 void parser::onEnd(const XML_Char *el,parser* child)
52 {
53   DEBTRACE("parser::onEnd: " << el)
54 }
55
56 void XMLCALL parser::end(void *data, const char *el)
57 {
58   DEBTRACE("parser::end: " << el);
59   parser* child=static_cast <parser *> (data);
60   sp.pop();
61   DEBTRACE("parser::end, stack size: " << sp.size());
62   parser* pp=sp.top();
63   XML_SetUserData(p,pp);
64   pp->onEnd(el,child);
65   child->endParser();
66 }
67
68 void parser::charData(const XML_Char *s, int len)
69 {
70   _content=_content+std::string(s,len);
71 }
72
73 void XMLCALL parser::charac(void *data, const XML_Char *s, int len)
74 {
75   parser* pp=static_cast <parser *> (data);
76   pp->charData(s,len);
77 }
78
79 void parser::endParser()
80 {
81   DEBTRACE("parser::endParser, level: " <<_level);
82   _level=_level-1;
83   if(_level>0)
84     {
85       delete _counts;
86       _counts=_stackCount.top();
87       _orderState=_stackOrder.top();
88       _stackCount.pop();
89       _stackOrder.pop();
90     }
91 }
92
93 void parser::init ()
94 {
95   DEBTRACE("parser::init, level: " <<_level);
96   if(_level>0)
97     {
98       _stackCount.push(_counts);
99       _stackOrder.push(_orderState);
100       _counts=new std::map<std::string,int>;
101     }
102   _level=_level+1;
103   _counts->clear();
104   _orderState=0;
105 }
106
107 void parser::incrCount(const XML_Char *el)
108 {
109   if(_counts->count(el)==0)
110     (*_counts)[el]=1;
111   else
112     (*_counts)[el]=(*_counts)[el]+1;
113 }
114
115 void parser::checkOrder(std::string& el)
116 {
117   if(_orders.count(el)==0)return;
118   if(_orders[el] < _orderState)
119     {
120       std::string msg="unexpected "+el+" element (wrong order)";
121       throw YACS::Exception::Exception(msg);
122     }
123   else if(_orders[el] > _orderState)
124     {
125       _orderState=_orders[el];
126     }
127 }
128
129 void parser::maxcount(std::string name, int max, std::string& el)
130 {
131   if(el!=name)return;
132   if((*_counts)[name]>max)
133     {
134       std::stringstream msg;
135       msg <<"unexpected "+name+" element (count="<<(*_counts)[name];
136       msg <<" > maxOccurs=" << max << ")";
137       throw YACS::Exception::Exception(msg.str());
138     }
139 }
140
141 void parser::mincount(std::string name,int min )
142 {
143   if((*_counts)[name]<min)
144     {
145       std::stringstream msg;
146       msg<<"expected "+name+" element (count="<<(*_counts)[name];
147       msg << " < minOccurs=" << min << ")";
148       throw YACS::Exception::Exception(msg.str());
149     }
150 }
151
152 void parser::maxchoice(std::string *names, int max, std::string& el)
153 {
154   int i=0;
155   int ncount=0;
156   while (names[i]!= "")
157     {
158       ncount=ncount+(*_counts)[names[i]];
159       ++i;
160     }
161   if(ncount>max)
162     {
163       std::stringstream msg;
164       msg<<"unexpected "+el+" element (choice count="<<ncount<<" > maxOccurs=" << max << ")";
165       throw YACS::Exception::Exception(msg.str());
166     }
167 }
168
169 void parser::minchoice(std::string *names, int min)
170 {
171   int i=0;
172   int ncount=0;
173   while (names[i]!= "")
174     {
175       ncount=ncount+(*_counts)[names[i]];
176       ++i;
177     }
178   if(ncount<min)
179     {
180       std::stringstream msg;
181       msg << "expected element ";
182       i=0;
183       while (names[i]!= "")
184         {
185           msg << names[i] << ",";
186           ++i;
187         }
188       msg << "(choice count="<<ncount<<" < minOccurs=" << min << ")";
189       throw YACS::Exception::Exception(msg.str());
190     }
191 }
192
193 void parser::required(const std::string& name, const XML_Char** attr)
194 {
195   for (int i = 0; attr[i]; i += 2) 
196     {
197       if(name == std::string(attr[i]))return;
198     }
199   throw YACS::Exception::Exception("Attribute: "+name+" is required");
200 }
201
202 void parser::buildAttr(const XML_Char** attr)
203 {
204   for (int i = 0; attr[i]; i += 2) 
205     {
206       DEBTRACE(attr[i] << "=" << attr[i + 1]);
207     }
208 }
209
210 void parser::onStart(const XML_Char* el, const XML_Char** attr)
211 {
212   DEBTRACE( "parser::onStart: " << el );
213   SetUserDataAndPush(&main_parser);
214   main_parser.init();
215   main_parser.pre();
216   main_parser.buildAttr(attr);
217 }
218
219 void parser::logError(const std::string& reason)
220 {
221   DEBTRACE( "parser::logError: " << _file );
222   currentProc->getLogger("parser")->error(reason,main_parser._file.c_str(),XML_GetCurrentLineNumber(p));
223 }
224
225 }