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