Salome HOME
2fad33769b37a921dd888593392d5aa50b8300d8
[modules/yacs.git] / src / yacsloader / switchParsers.hxx
1 //  Copyright (C) 2006-2008  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.
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 #ifndef _SWITCHPARSERS_HXX_
20 #define _SWITCHPARSERS_HXX_
21
22 #include "parserBase.hxx"
23 #include "propertyParsers.hxx"
24 #include "nodeParsers.hxx"
25
26 #include "Loop.hxx"
27 #include "ForLoop.hxx"
28 #include "ForEachLoop.hxx"
29 #include "WhileLoop.hxx"
30 #include "Switch.hxx"
31 #include "Bloc.hxx"
32 #include "Proc.hxx"
33 #include "InlineNode.hxx"
34 #include "ServiceNode.hxx"
35 #include "ServiceInlineNode.hxx"
36 #include "Runtime.hxx"
37
38 #include "factory.hxx"
39
40 #include <sstream>
41 #include <string>
42 #include <vector>
43 #include <map>
44
45 extern YACS::ENGINE::Proc* currentProc;
46 extern YACS::ENGINE::Runtime* theRuntime;
47
48 namespace YACS
49 {
50
51 struct casetypeParser:parser
52 {
53   static casetypeParser caseParser;
54   void onStart(const XML_Char* el, const XML_Char** attr);
55   void onEnd(const char *el,parser* child);
56   virtual void buildAttr(const XML_Char** attr);
57   virtual void pre ();
58   virtual void id (const int& n);
59   virtual void property (const myprop& prop);
60   virtual void inline_ (ENGINE::InlineNode* const& n);
61   virtual void sinline (ENGINE::ServiceInlineNode* const& n);
62   virtual void service (ENGINE::ServiceNode* const& n);
63   virtual void node (ENGINE::InlineNode* const& n);
64   virtual void forloop (ENGINE::ForLoop* const& n);
65   virtual void foreach (ENGINE::ForEachLoop* const& n);
66   virtual void while_ (ENGINE::WhileLoop* const& n);
67   virtual void switch_ (ENGINE::Switch* const& n);
68   virtual void bloc (ENGINE::Bloc* const& n);
69   virtual std::pair<int,ENGINE::Node*> post();
70   ENGINE::Node* _cnode;
71   int _id;
72   std::vector<int> _idStack;
73 };
74
75 struct defaultcasetypeParser:casetypeParser
76 {
77   static defaultcasetypeParser defaultcaseParser;
78   virtual void buildAttr(const XML_Char** attr);
79   virtual void pre ();
80 };
81
82 struct switchtypeParser:parser
83 {
84   static switchtypeParser switchParser;
85   void onStart(const XML_Char* el, const XML_Char** attr);
86   void onEnd(const char *el,parser* child);
87   virtual void buildAttr(const XML_Char** attr);
88   virtual void pre ();
89   virtual void case_ (const std::pair<int,ENGINE::Node*>& p);
90   virtual void default_ (const std::pair<int,ENGINE::Node*>& p);
91   virtual void name (const std::string& name);
92   virtual void state (const std::string& state);
93   virtual void select (const int& s);
94   virtual ENGINE::Switch* post ();
95   // stack to store switches in case of switch in switch
96   std::vector<ENGINE::Switch *> _cnodes;
97   std::string _state;
98 };
99
100 }
101
102 #include "loopParsers.hxx"
103
104 namespace YACS
105 {
106
107   static std::string switch_t3[]={"inline","sinline","service","node","forloop","foreach","while","switch","bloc",""};
108
109   void casetypeParser::buildAttr(const XML_Char** attr)
110     {
111       this->required("id",attr);
112       for (int i = 0; attr[i]; i += 2) 
113         {
114           if(std::string(attr[i]) == "id")id(atoi(attr[i+1]));
115         }
116     }
117   void casetypeParser::pre ()
118     {
119       _cnode=0;
120       _id=0;
121     }
122   void casetypeParser::id (const int& n)
123     {
124       DEBTRACE( "case_id: " << n )             
125       _id=n;
126       //store this level id
127       _idStack.push_back(_id);
128       //store this level name
129       std::stringstream temp;
130       if (_id <0) temp << "m" << -_id << "_";
131       else temp << "p" << _id << "_";
132       std::string fullname=currentProc->names.back()+temp.str();
133       DEBTRACE( "case_fullname: " << fullname )             
134       currentProc->names.push_back(fullname);
135     }
136   void casetypeParser::property (const myprop& prop)
137     {
138       DEBTRACE( "property_set: " << prop._name << prop._value )             
139     }
140   void casetypeParser::inline_ (ENGINE::InlineNode* const& n)
141     {
142       _cnode=n;
143       std::string fullname=currentProc->names.back()+ n->getName();
144       currentProc->nodeMap[fullname]=n;
145       currentProc->inlineMap[fullname]=n;
146     }
147   void casetypeParser::sinline (ENGINE::ServiceInlineNode* const& n)
148     {
149       _cnode=n;
150       std::string fullname=currentProc->names.back()+ n->getName();
151       currentProc->nodeMap[fullname]=n;
152       currentProc->serviceMap[fullname]=n;
153     }
154   void casetypeParser::service (ENGINE::ServiceNode* const& n)
155     {
156       _cnode=n;
157       std::string fullname=currentProc->names.back()+ n->getName();
158       currentProc->nodeMap[fullname]=n;
159       currentProc->serviceMap[fullname]=n;
160     }
161   void casetypeParser::node (ENGINE::InlineNode* const& n)
162     {
163       _cnode=n;
164       std::string fullname=currentProc->names.back()+ n->getName();
165       currentProc->nodeMap[fullname]=n;
166       currentProc->inlineMap[fullname]=n;
167     }
168   void casetypeParser::forloop (ENGINE::ForLoop* const& n)
169     {
170       _cnode=n;
171       std::string fullname=currentProc->names.back()+ n->getName();
172       currentProc->nodeMap[fullname]=n;
173     }
174   void casetypeParser::foreach (ENGINE::ForEachLoop* const& n)
175     {
176       _cnode=n;
177       std::string fullname=currentProc->names.back()+ n->getName();
178       currentProc->nodeMap[fullname]=n;
179       fullname += ".splitter";
180       currentProc->nodeMap[fullname]=n->getChildByShortName("splitter");
181     }
182   void casetypeParser::while_ (ENGINE::WhileLoop* const& n)
183     {
184       _cnode=n;
185       std::string fullname=currentProc->names.back()+ n->getName();
186       currentProc->nodeMap[fullname]=n;
187     }
188   void casetypeParser::switch_ (ENGINE::Switch* const& n)
189     {
190       _cnode=n;
191       std::string fullname=currentProc->names.back()+ n->getName();
192       currentProc->nodeMap[fullname]=n;
193     }
194   void casetypeParser::bloc (ENGINE::Bloc* const& n)
195     {
196       _cnode=n;
197       std::string fullname=currentProc->names.back()+ n->getName();
198       currentProc->nodeMap[fullname]=n;
199     }
200   std::pair<int,ENGINE::Node*> casetypeParser::post()
201     {
202       DEBTRACE( "case_post" )             
203       minchoice(switch_t3,1);
204       //get back this level id
205       _id=_idStack.back();
206       _idStack.pop_back();
207       //pop back this level name
208       currentProc->names.pop_back();
209       return std::pair<int,ENGINE::Node*>(_id,_cnode);
210     }
211
212   void defaultcasetypeParser::buildAttr(const XML_Char** attr)
213     {
214       for (int i = 0; attr[i]; i += 2) 
215       {
216         DEBTRACE( attr[i] << "=" << attr[i + 1] )             
217       }
218     }
219   void defaultcasetypeParser::pre ()
220     {
221       _id=0;
222       _cnode=0;
223       //store this level id
224       _idStack.push_back(_id);
225       //store this level name
226       std::string fullname=currentProc->names.back()+"default_";
227       DEBTRACE( "case_fullname: " << fullname )             
228       currentProc->names.push_back(fullname);
229     }
230
231   void switchtypeParser::buildAttr(const XML_Char** attr)
232     {
233       this->required("name",attr);
234       for (int i = 0; attr[i]; i += 2) 
235         {
236           if(std::string(attr[i]) == "name")name(attr[i+1]);
237           if(std::string(attr[i]) == "state")state(attr[i+1]);
238           if(std::string(attr[i]) == "select")select(atoi(attr[i+1]));
239         }
240     }
241   void switchtypeParser::pre (){_state="";}
242   void switchtypeParser::case_ (const std::pair<int,ENGINE::Node*>& p)
243     {
244       ENGINE::Switch* s=_cnodes.back();
245       s->edSetNode(p.first,p.second);
246     }
247   void switchtypeParser::default_ (const std::pair<int,ENGINE::Node*>& p)
248     {
249       ENGINE::Switch* s=_cnodes.back();
250       s->edSetDefaultNode(p.second);
251     }
252   void switchtypeParser::name (const std::string& name)
253     {
254       ENGINE::Switch* s;
255       std::string fullname=currentProc->names.back()+name;
256       DEBTRACE( "switch_fullname: " << fullname )             
257       s=theRuntime->createSwitch(name);
258       _cnodes.push_back(s);
259       currentProc->names.push_back(fullname+'.');
260     }
261   void switchtypeParser::state (const std::string& state)
262     {
263       //state is an attribute (no order). It can be defined before name
264       //To be improved
265       ENGINE::Switch* s=_cnodes.back();
266       if(_state == "disabled")
267         {
268           DEBTRACE( "Switch disabled: " << s->getName())             
269           s->exDisabledState();
270         }
271     }
272   void switchtypeParser::select (const int& s)
273     {
274       //select is an attribute
275       ENGINE::Switch* sw=_cnodes.back();
276       ENGINE::InputPort *p=sw->edGetConditionPort();
277       p->edInit(s);
278     }
279   ENGINE::Switch* switchtypeParser::post ()
280     {
281       DEBTRACE( "switch_post: " )             
282       ENGINE::Switch* sw=_cnodes.back();
283       //pop back current level name and node
284       _cnodes.pop_back();
285       currentProc->names.pop_back();
286       return sw;
287     }
288
289 void switchtypeParser::onStart(const XML_Char* el, const XML_Char** attr)
290 {
291   DEBTRACE( "switchtypeParser::onStart: " << el )
292   std::string element(el);
293   this->maxcount("default",1,element);
294   parser* pp=&parser::main_parser;
295   if(element == "case")pp=&casetypeParser::caseParser;
296   else if(element == "default")pp=&defaultcasetypeParser::defaultcaseParser;
297   SetUserDataAndPush(pp);
298   pp->init();
299   pp->pre();
300   pp->buildAttr(attr);
301 }
302
303 void switchtypeParser::onEnd(const char *el,parser* child)
304 {
305   DEBTRACE( "switchtypeParser::onEnd: " << el )
306   std::string element(el);
307   if(element == "case")case_(((casetypeParser*)child)->post());
308   else if(element == "default")default_(((defaultcasetypeParser*)child)->post());
309 }
310
311 void casetypeParser::onStart(const XML_Char* el, const XML_Char** attr)
312 {
313   DEBTRACE( "casetypeParser::onStart: " << el )
314   std::string element(el);
315   this->maxcount("inline",1,element);
316   this->maxcount("sinline",1,element);
317   this->maxcount("service",1,element);
318   this->maxcount("node",1,element);
319   this->maxcount("forloop",1,element);
320   this->maxcount("foreach",1,element);
321   this->maxcount("while",1,element);
322   this->maxcount("switch",1,element);
323   this->maxcount("bloc",1,element);
324   this->maxchoice(switch_t3,1,element);
325   parser* pp=&parser::main_parser;
326   if(element == "property")pp=&propertytypeParser::propertyParser;
327   else if(element == "inline")pp=&inlinetypeParser<>::inlineParser;
328   else if(element == "sinline")pp=&sinlinetypeParser<>::sinlineParser;
329   else if(element == "service")pp=&servicetypeParser<>::serviceParser;
330   else if(element == "node")pp=&nodetypeParser<>::nodeParser;
331   else if(element == "forloop")pp=&forlooptypeParser<>::forloopParser;
332   else if(element == "foreach")pp=&foreachlooptypeParser<>::foreachloopParser;
333   else if(element == "while")pp=&whilelooptypeParser<>::whileloopParser;
334   else if(element == "switch")pp=&switchtypeParser::switchParser;
335   else if(element == "bloc")pp=&bloctypeParser<>::blocParser;
336   SetUserDataAndPush(pp);
337   pp->init();
338   pp->pre();
339   pp->buildAttr(attr);
340 }
341
342 void casetypeParser::onEnd(const char *el,parser* child)
343 {
344   DEBTRACE( "casetypeParser::onEnd: " << el )
345   std::string element(el);
346   if(element == "property")property(((propertytypeParser*)child)->post());
347   else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
348   else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
349   else if(element == "service")service(((servicetypeParser<>*)child)->post());
350   else if(element == "node")node(((nodetypeParser<>*)child)->post());
351   else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
352   else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
353   else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
354   else if(element == "switch")switch_(((switchtypeParser*)child)->post());
355   else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
356 }
357
358 }
359
360 #endif