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