Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / yacsloader / parsers.cxx
1 #include <stdio.h>
2 #include <stdexcept>
3 #include <expat.h>
4 #include <iostream>
5 #include <sstream>
6 #include <map>
7 #include <list>
8 #include <stdlib.h>
9 #include "parsers.hxx"
10 #include "factory.hxx"
11 #include "Runtime.hxx"
12 #include "Exception.hxx"
13 #include "Cstr2d.hxx"
14 #include "TypeCode.hxx"
15 #include "Loop.hxx"
16 #include "ForLoop.hxx"
17 #include "ForEachLoop.hxx"
18 #include "WhileLoop.hxx"
19 #include "Switch.hxx"
20 #include "Bloc.hxx"
21 #include "Proc.hxx"
22 #include "InlineNode.hxx"
23 #include "ServiceNode.hxx"
24 #include "ServiceInlineNode.hxx"
25 #include "OutputPort.hxx"
26 #include "InputPort.hxx"
27 #include "OutputDataStreamPort.hxx"
28 #include "InputDataStreamPort.hxx"
29 #include "ComponentInstance.hxx"
30 #include "Container.hxx"
31
32 using namespace YACS;
33 using YACS::ENGINE::Runtime;
34 using YACS::ENGINE::getRuntime;
35
36 using YACS::ENGINE::TypeCode;
37 using YACS::Exception;
38 using YACS::ENGINE::TypeCodeObjref;
39 using YACS::ENGINE::TypeCodeStruct;
40 using YACS::ENGINE::Objref;
41 using YACS::ENGINE::InlineNode;
42 using YACS::ENGINE::InlineFuncNode;
43 using YACS::ENGINE::ServiceNode;
44 using YACS::ENGINE::ServiceInlineNode;
45 using YACS::ENGINE::Node;
46 using YACS::ENGINE::Loop;
47 using YACS::ENGINE::ForLoop;
48 using YACS::ENGINE::ForEachLoop;
49 using YACS::ENGINE::WhileLoop;
50 using YACS::ENGINE::Switch;
51 using YACS::ENGINE::Bloc;
52 using YACS::ENGINE::Proc;
53 using YACS::ENGINE::InputPort;
54 using YACS::ENGINE::OutputPort;
55 using YACS::ENGINE::InputDataStreamPort;
56 using YACS::ENGINE::OutputDataStreamPort;
57
58 //#define _DEVDEBUG_
59 #include "YacsTrace.hxx"
60
61 Runtime* theRuntime=0;
62 static Proc* currentProc;
63
64 #define BUFFSIZE        8192
65
66 char Buff[BUFFSIZE];
67
68 XML_Parser p ;
69
70 std::stack<parser*> sp;
71
72 parser::~parser()
73 {
74   if(_level==0)
75     {
76       delete _counts;
77     }
78   else
79     {
80       DEBTRACE("Problem with parser: final stack level should be 0 and not " << _level);
81     }
82 }
83
84 void parser::SetUserDataAndPush(parser* pp)
85 {
86   XML_SetUserData(p,pp);
87   sp.push(pp);
88 }
89
90 void XMLCALL parser::start(void *data, const XML_Char* el, const XML_Char** attr)
91 {
92   parser* pp=static_cast <parser *> (data);
93   pp->incrCount(el);
94   pp->onStart(el,attr);
95 }
96
97 void parser::onEnd(const XML_Char *el,parser* child)
98 {
99   DEBTRACE("parser::onEnd: " << el)
100 }
101
102 void XMLCALL parser::end(void *data, const char *el)
103 {
104   DEBTRACE("parser::end: " << el);
105   parser* child=static_cast <parser *> (data);
106   sp.pop();
107   parser* pp=sp.top();
108   XML_SetUserData(p,pp);
109   pp->onEnd(el,child);
110   child->end();
111 }
112
113 void parser::charData(const XML_Char *s, int len)
114 {
115   _content=_content+std::string(s,len);
116 }
117
118 void XMLCALL parser::charac(void *data, const XML_Char *s, int len)
119 {
120   parser* pp=static_cast <parser *> (data);
121   pp->charData(s,len);
122 }
123
124 void parser::end ()
125 {
126   _level=_level-1;
127   if(_level>0)
128     {
129       delete _counts;
130       _counts=_stackCount.top();
131       _orderState=_stackOrder.top();
132       _stackCount.pop();
133       _stackOrder.pop();
134     }
135 }
136
137 void parser::init ()
138 {
139   if(_level>0)
140     {
141       _stackCount.push(_counts);
142       _stackOrder.push(_orderState);
143       _counts=new std::map<std::string,int>;
144     }
145   _level=_level+1;
146   _counts->clear();
147   _orderState=0;
148 }
149
150 void parser::incrCount(const XML_Char *el)
151 {
152   if(_counts->count(el)==0)
153     (*_counts)[el]=1;
154   else
155     (*_counts)[el]=(*_counts)[el]+1;
156 }
157
158 void parser::checkOrder(std::string& el)
159 {
160   if(_orders.count(el)==0)return;
161   if(_orders[el] < _orderState)
162     {
163       std::string msg="unexpected "+el+" element (wrong order)";
164       throw YACS::Exception::Exception(msg);
165     }
166   else if(_orders[el] > _orderState)
167     {
168       _orderState=_orders[el];
169     }
170 }
171
172 void parser::maxcount(std::string name, int max, std::string& el)
173 {
174   if(el!=name)return;
175   if((*_counts)[name]>max)
176     {
177       std::stringstream msg;
178       msg <<"unexpected "+name+" element (count="<<(*_counts)[name];
179       msg <<" > maxOccurs=" << max << ")";
180       throw YACS::Exception::Exception(msg.str());
181     }
182 }
183
184 void parser::mincount(std::string name,int min )
185 {
186   if((*_counts)[name]<min)
187     {
188       std::stringstream msg;
189       msg<<"expected "+name+" element (count="<<(*_counts)[name];
190       msg << " < minOccurs=" << min << ")";
191       throw YACS::Exception::Exception(msg.str());
192     }
193 }
194
195 void parser::maxchoice(std::string *names, int max, std::string& el)
196 {
197   int i=0;
198   int ncount=0;
199   while (names[i]!= "")
200     {
201       ncount=ncount+(*_counts)[names[i]];
202       ++i;
203     }
204   if(ncount>max)
205     {
206       std::stringstream msg;
207       msg<<"unexpected "+el+" element (choice count="<<ncount<<" > maxOccurs=" << max << ")";
208       throw YACS::Exception::Exception(msg.str());
209     }
210 }
211
212 void parser::minchoice(std::string *names, int min)
213 {
214   int i=0;
215   int ncount=0;
216   while (names[i]!= "")
217     {
218       ncount=ncount+(*_counts)[names[i]];
219       ++i;
220     }
221   if(ncount<min)
222     {
223       std::stringstream msg;
224       msg << "expected element ";
225       i=0;
226       while (names[i]!= "")
227         {
228           msg << names[i] << ",";
229           ++i;
230         }
231       msg << "(choice count="<<ncount<<" < minOccurs=" << min << ")";
232       throw YACS::Exception::Exception(msg.str());
233     }
234 }
235
236 void parser::required(const std::string& name, const XML_Char** attr)
237 {
238   for (int i = 0; attr[i]; i += 2) 
239     {
240       if(name == std::string(attr[i]))return;
241     }
242   throw YACS::Exception::Exception("Attribute: "+name+" is required");
243 }
244
245 void parser::buildAttr(const XML_Char** attr)
246 {
247   for (int i = 0; attr[i]; i += 2) 
248     {
249       DEBTRACE(attr[i] << "=" << attr[i + 1])
250     }
251 }
252
253 void parser::onStart(const XML_Char* el, const XML_Char** attr)
254 {
255   DEBTRACE( "parser::onStart: " << el )             
256   XML_SetUserData(p,&main_parser);
257   sp.push(&main_parser);
258   main_parser.buildAttr(attr);
259 }
260
261 /*! \brief Class for string parser.
262  *
263  *  Class used to parse string
264  */
265 struct stringtypeParser:parser
266 {
267   std::string post()
268     {
269       return _content;
270     }
271 };
272 static stringtypeParser stringParser;
273
274 /*! \brief Class for double parser.
275  *
276  *  Class used to parse double 
277  */
278 struct doubletypeParser:parser
279 {
280   double post()
281     {
282       return Cstr2d(_content.c_str());
283 //       std::istringstream s(_content.c_str());
284 //       double a;
285 //       if (!(s >> a))
286 //         throw YACS::Exception::Exception("problem in conversion from string to double");
287 //       std::cerr << "--------------_content s a "<< _content.c_str() << " " << s.str() << " " << a << std::endl;
288 //       return a;
289     }
290 };
291 static doubletypeParser doubleParser;
292
293 /*! \brief Class for integer parser.
294  *
295  *  Class used to parse integer
296  */
297 struct inttypeParser:parser
298 {
299   int post()
300     {
301       return atoi(_content.c_str());
302     }
303 };
304 static inttypeParser intParser;
305
306 /*! \brief Class for boolean parser.
307  *
308  *  Class used to parse bool
309  */
310 struct booltypeParser:parser
311 {
312   bool post()
313     {
314       DEBTRACE( _content )             
315       if(_content == "true")return true;
316       if(_content == "false")return false;
317       std::stringstream temp(_content);
318       bool b ;
319       temp >> b;
320       //std::cerr << b << std::endl;
321       return b;
322     }
323 };
324 static booltypeParser boolParser;
325
326 /*! \brief Class for property parser.
327  *
328  *  Class used to parse a property
329  *  A property is a pair of name(string), value(string)
330  *  XML schema is 
331  *    <xsd:complexType name="PropertyType">
332  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
333  *      <xsd:attribute name="value" type="xsd:string" use="required"/>
334  *    </xsd:complexType>
335  *
336  */
337 struct propertytypeParser: parser
338 {
339   virtual void buildAttr(const XML_Char** attr)
340     {
341       required("name",attr);
342       required("value",attr);
343       for (int i = 0; attr[i]; i += 2) 
344       {
345         if(std::string(attr[i]) == "name")name(attr[i+1]);
346         if(std::string(attr[i]) == "value")value(attr[i+1]);
347       }
348     }
349   virtual void name(const std::string& name){ _prop._name=name; }
350   virtual void value(const std::string& name){ _prop._value=name; }
351   myprop post(){return _prop;}
352   myprop _prop;
353 };
354 static propertytypeParser propertyParser;
355
356 /*! \brief Class for type parser.
357  *
358  *  Class used to parse a type definition (class TypeCode in implementation)
359  *  with a name and a kind (reserved to atomic types)
360  *  XML schema is 
361  *    <xsd:complexType name="TypeType">
362  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
363  *      <xsd:attribute name="kind" type="xsd:string" use="required"/>
364  *    </xsd:complexType>
365  *
366  */
367 struct typetypeParser: parser
368 {
369   virtual void buildAttr(const XML_Char** attr)
370     {
371       required("name",attr);
372       required("kind",attr);
373       for (int i = 0; attr[i]; i += 2) 
374         {
375           if(std::string(attr[i]) == "name")name(attr[i+1]);
376           if(std::string(attr[i]) == "kind")kind(attr[i+1]);
377         }
378     }
379   virtual void pre (){}
380   virtual void name(const std::string& name)
381     {
382       DEBTRACE( "type_name: " << name )             
383       _name=name;
384     }
385   virtual void kind(const std::string& name)
386     {
387       DEBTRACE( "type_kind: " << name )             
388       _kind=name;
389     }
390   virtual mytype post()
391     {
392       DEBTRACE( "type_post" )             
393       mytype t;
394       t._kind=_kind;
395       t._name=_name;
396       return t;
397     }
398   std::string _name;
399   std::string _kind;
400 };
401 static typetypeParser typeParser;
402
403 /*! \brief Class for sequence parser.
404  *
405  *  Class used to parse a sequence (type) definition (class TypeCodeSeq in implementation)
406  *  XML schema is 
407  *    <xsd:complexType name="SequenceType">
408  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
409  *      <xsd:attribute name="content" type="xsd:string" use="required"/>
410  *    </xsd:complexType>
411  *
412  */
413 struct seqtypeParser:public parser
414 {
415   virtual void onStart(const XML_Char* el, const XML_Char** attr)
416     {
417       DEBTRACE( "seqtypeParser::onStart: " << el )             
418       parser* pp=&main_parser;
419       XML_SetUserData(p,pp);
420       sp.push(pp);
421       pp->init();
422       pp->pre();
423       pp->buildAttr(attr);
424     }
425   virtual void onEnd(const char *el,parser* child)
426     {
427       DEBTRACE( "seqtypeParser::onEnd: " << el )             
428     }
429   virtual void buildAttr(const XML_Char** attr)
430     {
431       required("name",attr);
432       required("content",attr);
433       for (int i = 0; attr[i]; i += 2) 
434         {
435           if(std::string(attr[i]) == "name")name(attr[i+1]);
436           if(std::string(attr[i]) == "content")content(attr[i+1]);
437         }
438     }
439   void name(const std::string& name)
440     {
441       DEBTRACE( "seqtype_name: " << name )             
442       _name=name;
443     }
444   void content(const std::string& name)
445     {
446       DEBTRACE( "seqtype_content: " << name )             
447       if(currentProc->typeMap.count(name)==0)
448         {
449           std::stringstream msg;
450           msg << "Type " << name << " does not exist" << " (" <<__FILE__ << ":" << __LINE__ << ")";
451           throw Exception(msg.str());
452         }
453       _contentType=currentProc->typeMap[name];
454
455     }
456   TypeCode* post()
457     {
458       DEBTRACE( "seqtype_post" )             
459       TypeCode *t = currentProc->createSequenceTc(_name,_name,_contentType);
460       return t;
461     }
462   TypeCode* _contentType;
463   std::string _name;
464 };
465 static seqtypeParser seqParser;
466
467 /*! \brief Class for objref parser.
468  *
469  *  Class used to parse a objref (type) definition (class TypeCodeObjref in implementation)
470  *  XML schema is 
471  *    <xsd:complexType name="ObjrefType">
472  *      <xsd:sequence>
473  *        <xsd:element name="base" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
474  *      </xsd:sequence>
475  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
476  *      <xsd:attribute name="id" type="xsd:string" />
477  *    </xsd:complexType>
478  *
479  */
480 struct objtypeParser: parser
481 {
482   virtual void onStart(const XML_Char* el, const XML_Char** attr)
483     {
484       DEBTRACE( "objtypeParser::onStart: " << el )             
485       std::string element(el);
486       parser* pp=&main_parser;
487       if(element == "base")pp=&stringParser;
488       XML_SetUserData(p,pp);
489       sp.push(pp);
490       pp->init();
491       pp->pre();
492       pp->buildAttr(attr);
493     }
494   virtual void onEnd(const char *el,parser* child)
495     {
496       DEBTRACE( "objtypeParser::onEnd: " << el )             
497       std::string element(el);
498       if(element == "base")base(((stringtypeParser*)child)->post());
499     }
500   virtual void buildAttr(const XML_Char** attr)
501     {
502       required("name",attr);
503       for (int i = 0; attr[i]; i += 2) 
504         {
505           if(std::string(attr[i]) == "name")name(attr[i+1]);
506           if(std::string(attr[i]) == "id")id(attr[i+1]);
507         }
508     }
509   virtual void pre ()
510     {
511       _id="";
512       _ltc.clear();
513     }
514   virtual void name(const std::string& name)
515     {
516       DEBTRACE( "objtype_name: " << name )             
517       _name=name;
518     }
519   virtual void id(const std::string& name)
520     {
521       DEBTRACE( "objtype_id: " << name )             
522       _id=name;
523     }
524   virtual void base(const std::string& name)
525     {
526       DEBTRACE( "base_name: " << name )             
527       if(currentProc->typeMap.count(name)==0)
528         {
529           std::stringstream msg;
530           msg << "Type " << name << " does not exist" ;
531           msg << " (" <<__FILE__ << ":" << __LINE__ << ")";
532           throw Exception(msg.str());
533         }
534       if(currentProc->typeMap[name]->kind() != Objref)
535         {
536           std::stringstream msg;
537           msg << "Type " << name << " is not an objref" ;
538           msg << " (" <<__FILE__ << ":" << __LINE__ << ")";
539           throw Exception(msg.str());
540         }
541       _ltc.push_back((TypeCodeObjref *)currentProc->typeMap[name]);
542     }
543   virtual TypeCode * post()
544     {
545       DEBTRACE( "objtype_post" )             
546       TypeCode *t = currentProc->createInterfaceTc(_id,_name,_ltc);
547       return t;
548     }
549   std::string _name;
550   std::string _id;
551   std::list<TypeCodeObjref *> _ltc;
552 };
553 static objtypeParser objParser;
554
555 /*! \brief Class for member parser.
556  *
557  *  Class used to parse a struct member
558  *  A struct member is a pair of name(string), type(string)
559  *  XML schema is
560  *    <xsd:complexType name="MemberType">
561  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
562  *      <xsd:attribute name="type" type="xsd:string" use="required"/>
563  *    </xsd:complexType>
564  *
565  */
566 struct membertypeParser: parser
567 {
568   virtual void buildAttr(const XML_Char** attr)
569     {
570       required("name",attr);
571       required("type",attr);
572       for (int i = 0; attr[i]; i += 2)
573       {
574         if(std::string(attr[i]) == "name")name(attr[i+1]);
575         if(std::string(attr[i]) == "type")type(attr[i+1]);
576       }
577     }
578   virtual void name(const std::string& name){ _prop._name=name; }
579   virtual void type(const std::string& name){ _prop._value=name; }
580   myprop post(){return _prop;}
581   myprop _prop;
582 };
583 static membertypeParser memberParser;
584
585 /*! \brief Class for struct parser.
586  *
587  *  Class used to parse a struct (type) definition (class TypeCodeStruct in implementation)
588  *  XML schema is 
589  *    <xsd:complexType name="StructType">
590  *      <xsd:sequence>
591  *        <xsd:element name="member" type="MemberType" minOccurs="0" maxOccurs="unbounded"/>
592  *      </xsd:sequence>
593  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
594  *      <xsd:attribute name="id" type="xsd:string" />
595  *    </xsd:complexType>
596  *
597  */
598 struct structtypeParser: parser
599 {
600   virtual void onStart(const XML_Char* el, const XML_Char** attr)
601     {
602       DEBTRACE( "structtypeParser::onStart: " << el )             
603       std::string element(el);
604       parser* pp=&main_parser;
605       if(element == "member")pp=&memberParser;
606       XML_SetUserData(p,pp);
607       sp.push(pp);
608       pp->init();
609       pp->pre();
610       pp->buildAttr(attr);
611     }
612   virtual void onEnd(const char *el,parser* child)
613     {
614       DEBTRACE( "structtypeParser::onEnd: " << el )             
615       std::string element(el);
616       if(element == "member")member(((membertypeParser*)child)->post());
617     }
618   virtual void buildAttr(const XML_Char** attr)
619     {
620       required("name",attr);
621       for (int i = 0; attr[i]; i += 2) 
622         {
623           if(std::string(attr[i]) == "name")name(attr[i+1]);
624           if(std::string(attr[i]) == "id")id(attr[i+1]);
625         }
626     }
627   virtual void pre ()
628     {
629       _id="";
630       _members.clear();
631     }
632   virtual void name(const std::string& name)
633     {
634       DEBTRACE( "structtype_name: " << name );
635       _name=name;
636     }
637   virtual void id(const std::string& name)
638     {
639       DEBTRACE( "structtype_id: " << name );
640       _id=name;
641     }
642   virtual void member (const myprop& prop)
643     {
644       DEBTRACE( "structtype_member: " << prop._name << prop._value );
645       if(currentProc->typeMap.count(prop._value)!=0)
646         _members.push_back(prop);
647       else
648         {
649           std::string msg="Unknown type " + prop._value + " for member " + prop._name + " in struct " + _name;
650           throw Exception(msg);
651         }
652     }
653   virtual TypeCode * post()
654     {
655       DEBTRACE( "structtype_post" );
656       TypeCodeStruct *t;
657       if(currentProc->typeMap.count(_name)!=0)
658         {
659           //reuse a forward declaration
660           TypeCode* tt=currentProc->typeMap[_name];
661           if(tt->kind()==YACS::ENGINE::Struct)
662             {
663               t=(TypeCodeStruct*)tt;
664             }
665           else
666             {
667               std::string msg="Forward declaration must be a struct type but " + std::string(tt->name()) + " is not one" ;
668               throw Exception(msg);
669             }
670         }
671       else
672         {
673           t = (TypeCodeStruct*)currentProc->createStructTc(_id,_name);
674         }
675       std::vector<myprop>::const_iterator iter;
676       for(iter=_members.begin();iter!=_members.end();iter++)
677         {
678           DEBTRACE("member: " << iter->_name << " " <<iter->_value);
679           t->addMember(iter->_name,currentProc->typeMap[iter->_value]);
680         }
681       return t;
682     }
683   std::string _name;
684   std::string _id;
685   std::vector<myprop> _members;
686 };
687 static structtypeParser structParser;
688
689 /*! \brief Class for machine parser.
690  *
691  *  Class used to parse computer adress on which container must be started
692  *  XML schema is 
693  *    <xsd:complexType name="MachineType">
694  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
695  *    </xsd:complexType>
696  */
697 struct machinetypeParser: parser
698 {
699   virtual void buildAttr(const XML_Char** attr)
700     {
701       required("name",attr);
702       for (int i = 0; attr[i]; i += 2)
703       {
704         if(std::string(attr[i]) == "name")name(attr[i+1]);
705       }
706     }
707   virtual void pre (){_mach._name="";}
708   virtual void name(const std::string& name){ _mach._name=name; }
709   machine post()
710     {
711       return _mach;
712     }
713   machine _mach;
714 };
715 static machinetypeParser machineParser;
716
717 /*! \brief Class for container parser
718  *
719  *  Class used to parse container description
720  *  XML schema is 
721  *    <xsd:complexType name="ContainerType">
722  *      <xsd:sequence>
723  *        <xsd:element name="machine" type="MachineType" minOccurs="0" maxOccurs="unbounded"/>
724  *        <xsd:element name="property" type="PropertyType" minOccurs="0" maxOccurs="unbounded"/>
725  *      </xsd:sequence>
726  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
727  *    </xsd:complexType>
728  */
729 struct containertypeParser: parser
730 {
731   virtual void buildAttr(const XML_Char** attr)
732     {
733       required("name",attr);
734       for (int i = 0; attr[i]; i += 2)
735       {
736         if(std::string(attr[i]) == "name")name(attr[i+1]);
737       }
738     }
739   virtual void onStart(const XML_Char* el, const XML_Char** attr)
740     {
741       std::string element(el);
742       parser* pp=&main_parser;
743       if(element == "machine")pp=&machineParser;
744       if(element == "property")pp=&propertyParser;
745       XML_SetUserData(p,pp);
746       sp.push(pp);
747       pp->init();
748       pp->pre();
749       pp->buildAttr(attr);
750     }
751   virtual void onEnd(const char *el,parser* child)
752     {
753       std::string element(el);
754       if(element == "machine")machine_(((machinetypeParser*)child)->post());
755       if(element == "property")property(((propertytypeParser*)child)->post());
756     }
757   virtual void pre (){_container._machs.clear();}
758   virtual void name(const std::string& name){ _container._name=name; }
759   virtual void machine_(const machine& m)
760     {
761       DEBTRACE( "machine: " << m._name )             
762       _container._machs.push_back(m);
763     }
764   virtual void property (const myprop& prop)
765     {
766       DEBTRACE( "property_set: " << prop._name << prop._value )             
767       _container._props[prop._name]=prop._value;
768     }
769   mycontainer post()
770     {
771       //mincount("machine",1);
772       return _container;
773     }
774   mycontainer _container;
775 };
776 static containertypeParser containerParser;
777
778 /*! \brief Class for loading parser
779  *
780  *  Class used to parse service node loading information
781  *  XML schema is 
782  *    <xsd:complexType name="LoadType">
783  *      <xsd:attribute name="container" type="xsd:string" use="required"/>
784  *    </xsd:complexType>
785  */
786 struct loadtypeParser: parser
787 {
788   virtual void buildAttr(const XML_Char** attr)
789     {
790       required("container",attr);
791       for (int i = 0; attr[i]; i += 2)
792       {
793         if(std::string(attr[i]) == "container")container(attr[i+1]);
794       }
795     }
796   virtual void pre (){_loadon._container="";}
797   virtual void container(const std::string& name){ _loadon._container=name; }
798   loadon post()
799     {
800       return _loadon;
801     }
802   loadon _loadon;
803 };
804 static loadtypeParser loadParser;
805
806 /*! \brief Class for Inport parser.
807  *
808  *  This class is a base class for other inport parsers
809  *    <xsd:complexType name="InPortType">
810  *      <xsd:sequence>
811  *        <xsd:element name="property" type="PropertyType" minOccurs="0"/>
812  *      </xsd:sequence>
813  *      <xsd:attribute name="name" type="xsd:string" use="required"/>
814  *      <xsd:attribute name="type" type="xsd:string" use="required"/>
815  *    </xsd:complexType>
816  *
817  */
818 template <class T=myinport>
819 struct inporttypeParser: parser
820 {
821   virtual void onStart(const XML_Char* el, const XML_Char** attr)
822     {
823       std::string element(el);
824       parser* pp=&main_parser;
825       if(element == "property")pp=&propertyParser;
826       XML_SetUserData(p,pp);
827       sp.push(pp);
828       pp->init();
829       pp->pre();
830       pp->buildAttr(attr);
831     }
832   virtual void onEnd(const char *el,parser* child)
833     {
834       std::string element(el);
835       if(element == "property")property(((propertytypeParser*)child)->post());
836     }
837   virtual void buildAttr(const XML_Char** attr)
838     {
839       required("name",attr);
840       required("type",attr);
841       for (int i = 0; attr[i]; i += 2) 
842         {
843           if(std::string(attr[i]) == "name")name(attr[i+1]);
844           if(std::string(attr[i]) == "type")type(attr[i+1]);
845         }
846     }
847   virtual void pre ()
848     {
849       _port._name="";
850       _port._type="";
851       _port.clear();
852     }
853   virtual void name(const std::string& name)
854     {
855       _port._name=name;
856     }
857   virtual void type(const std::string& type)
858     {
859       _port._type=type;
860     }
861   virtual void property (const myprop& prop)
862     {
863       DEBTRACE( "property_set: " << prop._name << prop._value )             
864       _port.setProperty(prop._name,prop._value);
865     }
866   virtual T& post()
867     {
868       return _port;
869     }
870 protected:
871     T _port;
872 };
873 static inporttypeParser<> inportParser;
874
875 /*! \brief Class for Outport parser.
876  *
877  *  This class is also used for OutputDataStream Port
878  *  same XML schema as inporttypeParser
879  */
880 template <class T=myoutport>
881 struct outporttypeParser:public inporttypeParser<T>
882 {
883 };
884 static outporttypeParser<> outportParser;
885
886 /*! \brief Class for node parser.
887  *
888  *  This class is a base class for other parsers
889  */
890 template <class T=InlineNode*>
891 struct nodetypeParser:public parser
892 {
893   virtual void onStart(const XML_Char* el, const XML_Char** attr)
894     {
895       DEBTRACE( "nodetypeParser::onStart: " << el )             
896       std::string element(el);
897       parser* pp=&main_parser;
898       XML_SetUserData(p,pp);
899       sp.push(pp);
900       pp->init();
901       pp->pre();
902       pp->buildAttr(attr);
903     }
904   virtual void onEnd(const char *el,parser* child)
905     {
906       DEBTRACE( "nodetypeParser::onEnd: " << el )             
907       std::string element(el);
908     }
909   virtual void buildAttr(const XML_Char** attr)
910     {
911       required("name",attr);
912       required("type",attr);
913       for (int i = 0; attr[i]; i += 2) 
914       {
915         if(std::string(attr[i]) == "name")name(attr[i+1]);
916         if(std::string(attr[i]) == "state")state(attr[i+1]);
917         if(std::string(attr[i]) == "type")type(attr[i+1]);
918       }
919     }
920   virtual void pre()
921     {
922       _node=0;
923     }
924   virtual void name (const std::string& name)
925     {
926       DEBTRACE( "inline_name: " << name )             
927       _name=name;
928     }
929   virtual void state (const std::string& name)
930     {
931       _state=name;
932     }
933   virtual void type (const std::string& name)
934     {
935       DEBTRACE( "node_type " << name )             
936       _type=name;
937     }
938   virtual T post()
939     {
940       return _node;
941     }
942   std::string _type;
943   std::string _name;
944   std::string _state;
945   T _node;
946 };
947 static nodetypeParser<> nodeParser;
948
949 template <>
950 InlineNode* nodetypeParser<InlineNode*>::post ()
951 {
952   std::string fullname = currentProc->names.back()+_type;
953   if(currentProc->inlineMap.count(_type) != 0)
954     {
955       //InlineNode type with absolute name found
956       InlineNode* n=currentProc->inlineMap[_type];
957       _node=n->cloneNode(_name);
958     }
959   else if(currentProc->inlineMap.count(fullname) != 0)
960     {
961       //InlineNode type with relative name found
962       InlineNode* n=currentProc->inlineMap[fullname];
963       _node=n->cloneNode(_name);
964     }
965   else
966     {
967       throw Exception("Unknown InlineNode type");
968     }
969   if(_state == "disabled")_node->exDisabledState();
970   DEBTRACE( "node_post " << _node->getName() )             
971   return _node;
972 }
973
974 struct codetypeParser: parser
975 {
976   virtual void onStart(const XML_Char* el, const XML_Char** attr)
977     {
978       std::string element(el);
979       parser* pp=&main_parser;
980       if(element == "code")pp=&stringParser;
981       XML_SetUserData(p,pp);
982       sp.push(pp);
983       pp->init();
984       pp->pre();
985       pp->buildAttr(attr);
986     }
987   virtual void onEnd(const char *el,parser* child)
988     {
989       std::string element(el);
990       if(element == "code")code(((stringtypeParser*)child)->post());
991     }
992   virtual void pre (){_code="";}
993   virtual void code (const std::string& s)
994     {
995       if(_code == "")
996         _code=s;
997       else 
998         _code=_code + '\n' + s;
999     }
1000   virtual myfunc post ()
1001     {
1002       _func._name="script";
1003       _func._code=_code;
1004       return _func;
1005     }
1006     std::string _code;
1007     myfunc _func;
1008 };
1009 static codetypeParser codeParser;
1010
1011 struct functypeParser: codetypeParser
1012 {
1013   virtual void buildAttr(const XML_Char** attr)
1014     {
1015       required("name",attr);
1016       for (int i = 0; attr[i]; i += 2) 
1017       {
1018         if(std::string(attr[i]) == "name")name(attr[i+1]);
1019       }
1020     }
1021   virtual void name (const std::string& name)
1022     {
1023       _func._name=name;
1024     }
1025   virtual myfunc post ()
1026     {
1027       _func._code=_code;
1028       return _func;
1029     }
1030 };
1031 static functypeParser funcParser;
1032
1033 static std::string t1[]={"script","function",""};
1034
1035 template <class T=InlineNode*>
1036 struct inlinetypeParser:public nodetypeParser<T>
1037 {
1038   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1039     {
1040       DEBTRACE( "inlinetypeParser::onStart: " << el )             
1041       std::string element(el);
1042       parser* pp=&main_parser;
1043       this->maxcount("kind",1,element);
1044       this->maxcount("script",1,element);
1045       this->maxcount("function",1,element);
1046       this->maxchoice(t1,1,element);
1047       if(element == "kind")pp=&stringParser;
1048       else if(element == "script")pp=&codeParser;
1049       else if(element == "function")pp=&funcParser;
1050       else if(element == "inport")pp=&inportParser;
1051       else if(element == "outport")pp=&outportParser;
1052       XML_SetUserData(p,pp);
1053       sp.push(pp);
1054       pp->init();
1055       pp->pre();
1056       pp->buildAttr(attr);
1057     }
1058   virtual void onEnd(const char *el,parser* child)
1059     {
1060       DEBTRACE( "inlinetypeParser::onEnd: " << el )             
1061       std::string element(el);
1062       if(element == "kind")kind(((stringtypeParser*)child)->post());
1063       else if(element == "script")script(((codetypeParser*)child)->post());
1064       else if(element == "function")function(((functypeParser*)child)->post());
1065       else if(element == "inport") inport(((inporttypeParser<myinport>*)child)->post());
1066       else if(element == "outport") outport(((outporttypeParser<myoutport>*)child)->post());
1067     }
1068   virtual void buildAttr(const XML_Char** attr)
1069     {
1070       this->required("name",attr);
1071       for (int i = 0; attr[i]; i += 2) 
1072       {
1073         if(std::string(attr[i]) == "name")this->name(attr[i+1]);
1074         if(std::string(attr[i]) == "state")this->state(attr[i+1]);
1075       }
1076     }
1077   virtual void pre ()
1078     {
1079       this->_node=0;
1080       _kind="";
1081       this->_state="";
1082     }
1083   virtual void kind (const std::string& name)
1084     {
1085       DEBTRACE( "inline_kind " << name )             
1086       _kind=name;
1087     }
1088   virtual void script (const myfunc& f){}
1089   virtual void function (const myfunc& f) {}
1090   virtual void inport (const myinport& p)
1091     {
1092       DEBTRACE( "inline_inport: " << p._name <<":"<<p._type)             
1093       if(this->_node==0)
1094         throw Exception("Node must be completely defined before defining its ports");
1095       if(currentProc->typeMap.count(p._type)==0)
1096         {
1097           std::string msg="Unknown InPort Type: ";
1098           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
1099           throw Exception(msg);
1100         }
1101       this->_node->edAddInputPort(p._name,currentProc->typeMap[p._type]);
1102     }
1103   virtual void outport (const myoutport& p)
1104     {
1105       DEBTRACE( "inline_outport: " << p._name <<":"<<p._type)             
1106       if(this->_node==0)
1107         throw Exception("Node must be completely defined before defining its ports");
1108       if(currentProc->typeMap.count(p._type)==0)
1109         {
1110           std::string msg="Unknown OutPort Type: ";
1111           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
1112           throw Exception(msg);
1113         }
1114       this->_node->edAddOutputPort(p._name,currentProc->typeMap[p._type]);
1115     }
1116   virtual T post()
1117     {
1118       DEBTRACE( "inline_post " << this->_node->getName() )             
1119       if(this->_state == "disabled")this->_node->exDisabledState();
1120       /*
1121       std::list<OutputPort *>::iterator iter;
1122       std::list<OutputPort *> s=_node->getSetOfOutputPort();
1123       for(iter=s.begin();iter!=s.end();iter++)
1124         {
1125           std::cerr << "port name: " << (*iter)->getName() << std::endl;
1126           std::cerr << "port kind: " << (*iter)->edGetType()->kind() << std::endl;
1127         }
1128         */
1129       return this->_node;
1130     }
1131   std::string _kind;
1132 };
1133 static inlinetypeParser<> inlineParser;
1134
1135 template <>
1136 void inlinetypeParser<InlineNode*>::script (const myfunc& f)
1137 {
1138   DEBTRACE( "inline_script: " << f._code )             
1139   _node=theRuntime->createScriptNode(_kind,_name);
1140   _node->setScript(f._code);
1141 }
1142 template <>
1143 void inlinetypeParser<InlineNode*>::function (const myfunc& f)
1144 {
1145   DEBTRACE( "inline_function: " << f._code )             
1146   InlineFuncNode *fnode;
1147   fnode=theRuntime->createFuncNode(_kind,_name);
1148   fnode->setScript(f._code);
1149   fnode->setFname(f._name);
1150   _node=fnode;
1151 }
1152
1153 /*! \brief Class for parsing ServiceInlineNode description
1154  *
1155  *  
1156  */
1157 template <class T=ServiceInlineNode*>
1158 struct sinlinetypeParser:public inlinetypeParser<T>
1159 {
1160   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1161     {
1162       DEBTRACE( "sinlinetypeParser::onStart: " << el )             
1163       std::string element(el);
1164       parser* pp=&main_parser;
1165       this->maxcount("kind",1,element);
1166       this->maxcount("function",1,element);
1167       this->maxcount("load",1,element);
1168       if(element == "kind")pp=&stringParser;
1169       else if(element == "function")pp=&funcParser;
1170       else if(element == "load")pp=&loadParser;
1171       else if(element == "inport")pp=&inportParser;
1172       else if(element == "outport")pp=&outportParser;
1173       XML_SetUserData(p,pp);
1174       sp.push(pp);
1175       pp->init();
1176       pp->pre();
1177       pp->buildAttr(attr);
1178     }
1179   virtual void onEnd(const char *el,parser* child)
1180     {
1181       DEBTRACE( "sinlinetypeParser::onEnd: " << el )             
1182       std::string element(el);
1183       if(element == "kind")this->kind(((stringtypeParser*)child)->post());
1184       else if(element == "function")this->function(((functypeParser*)child)->post());
1185       else if(element == "load") load(((loadtypeParser*)child)->post());
1186       else if(element == "inport") this->inport(((inporttypeParser<myinport>*)child)->post());
1187       else if(element == "outport") this->outport(((outporttypeParser<myoutport>*)child)->post());
1188     }
1189   //virtual void service (const myfunc& f) {}
1190   virtual void load (const loadon& l)
1191     {
1192       DEBTRACE( "sinline_load: " )             
1193       if(this->_node==0)
1194         throw Exception("ServiceInlineNode must be completely defined before defining how to load it");
1195
1196       if(currentProc->containerMap.count(l._container) != 0)
1197         {
1198           //If it has already a container replace it ?????
1199           this->_node->getComponent()->setContainer(currentProc->containerMap[l._container]);
1200         }
1201       else
1202         {
1203           std::cerr <<  "WARNING: Unknown container " << l._container << std::endl;
1204         }
1205     }
1206 };
1207
1208 template <>
1209 void inlinetypeParser<ServiceInlineNode*>::function (const myfunc& f)
1210 {
1211   DEBTRACE( "sinline_function: " << f._code )             
1212   ServiceInlineNode *fnode;
1213   fnode=theRuntime->createSInlineNode(_kind,_name);
1214   fnode->setScript(f._code);
1215   fnode->setMethod(f._name);
1216   fnode->setComponent(theRuntime->createComponentInstance("PyCompo","SalomePy"));
1217   //fnode->setRef("PyCompo");
1218   _node=fnode;
1219 }
1220
1221 static sinlinetypeParser<> sinlineParser;
1222
1223 static std::string t2[]={"ref","node","component",""};
1224
1225 template <class T=ServiceNode*>
1226 struct servicetypeParser:public inlinetypeParser<T>
1227 {
1228   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1229     {
1230       DEBTRACE( "servicetypeParser::onStart: " << el )             
1231       std::string element(el);
1232       parser* pp=&main_parser;
1233       this->maxcount("kind",1,element);
1234       this->maxcount("ref",1,element);
1235       this->maxcount("node",1,element);
1236       this->maxcount("component",1,element);
1237       this->maxcount("method",1,element);
1238       this->maxcount("load",1,element);
1239       this->maxchoice(t2,1,element);
1240       if(element == "kind")pp=&stringParser;
1241       else if(element == "ref")pp=&stringParser;
1242       else if(element == "component")pp=&stringParser;
1243       else if(element == "node")pp=&stringParser;
1244       else if(element == "method")pp=&stringParser;
1245       else if(element == "load")pp=&loadParser;
1246       else if(element == "inport")pp=&inportParser;
1247       else if(element == "outport")pp=&outportParser;
1248       else if(element == "instream")pp=&inportParser;
1249       else if(element == "outstream")pp=&outportParser;
1250       XML_SetUserData(p,pp);
1251       sp.push(pp);
1252       pp->init();
1253       pp->pre();
1254       pp->buildAttr(attr);
1255     }
1256   virtual void onEnd(const char *el,parser* child)
1257     {
1258       DEBTRACE( "servicetypeParser::onEnd: " << el )             
1259       std::string element(el);
1260       if(element == "kind")this->kind(((stringtypeParser*)child)->post());
1261       else if(element == "ref") ref(((stringtypeParser*)child)->post());
1262       else if(element == "component") component(((stringtypeParser*)child)->post());
1263       else if(element == "node") node(((stringtypeParser*)child)->post());
1264       else if(element == "method") method(((stringtypeParser*)child)->post());
1265       else if(element == "load") load(((loadtypeParser*)child)->post());
1266       else if(element == "inport") this->inport(((inporttypeParser<myinport>*)child)->post());
1267       else if(element == "outport") this->outport(((outporttypeParser<myoutport>*)child)->post());
1268       else if(element == "instream") instream(((inporttypeParser<myinport>*)child)->post());
1269       else if(element == "outstream") outstream(((outporttypeParser<myoutport>*)child)->post());
1270     }
1271   virtual void ref (const std::string& name)
1272     {
1273       DEBTRACE( "service_ref: " << name )             
1274       this->_node=theRuntime->createRefNode(this->_kind,this->_name);
1275       this->_node->setRef(name);
1276     }
1277   virtual void component (const std::string& name)
1278     {
1279       DEBTRACE( "service_component: " << name )             
1280       this->_node=theRuntime->createCompoNode(this->_kind,this->_name);
1281       this->_node->setRef(name);
1282     }
1283   virtual void node (const std::string& name)
1284     {
1285       DEBTRACE( "service_node: " << name )             
1286       std::string fullname = currentProc->names.back()+name;
1287       if(currentProc->serviceMap.count(name) != 0)
1288         {
1289           //ServiceNode with absolute name found
1290           ServiceNode* n=currentProc->serviceMap[name];
1291           this->_node =n->createNode(this->_name);
1292         }
1293       else if(currentProc->serviceMap.count(fullname) != 0)
1294         {
1295           //ServiceNode with relative name found
1296           //TODO: must be a short name (possible only in the same context)
1297           ServiceNode* n=currentProc->serviceMap[fullname];
1298           this->_node =n->createNode(this->_name);
1299         }
1300       else
1301         {
1302           throw Exception("Unknown ServiceNode");
1303         }
1304     }
1305   virtual void method (const std::string& name)
1306     {
1307       DEBTRACE( "service_method: " << name )             
1308       if(this->_node==0)
1309         throw Exception("ServiceNode must be completely defined before defining its method");
1310       this->_node->setMethod(name);
1311     }
1312
1313   virtual void load (const loadon& l)
1314     {
1315       DEBTRACE( "service_load: " )             
1316       if(this->_node==0)
1317         throw Exception("ServiceNode must be completely defined before defining how to load it");
1318
1319       if(currentProc->containerMap.count(l._container) != 0)
1320         {
1321           //If it has already a container replace it ?????
1322           this->_node->getComponent()->setContainer(currentProc->containerMap[l._container]);
1323         }
1324       else
1325         {
1326           std::cerr << "WARNING: Unknown container " << l._container << std::endl;
1327         }
1328     }
1329
1330   virtual void instream (const myinport& p)
1331     {
1332       DEBTRACE( "service_instream" )             
1333       DEBTRACE( p._type )             
1334       DEBTRACE( p._name )             
1335       if(this->_node==0)
1336         throw Exception("ServiceNode must be completely defined before defining its ports");
1337       if(currentProc->typeMap.count(p._type)==0)
1338         {
1339           std::string msg="Unknown InPort Type: ";
1340           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
1341           throw Exception(msg);
1342         }
1343       InputDataStreamPort* port;
1344       port=this->_node->edAddInputDataStreamPort(p._name,currentProc->typeMap[p._type]);
1345       // Set all properties for this port
1346       std::map<std::string, std::string>::const_iterator pt;
1347       for(pt=p._props.begin();pt!=p._props.end();pt++)
1348         port->setProperty((*pt).first,(*pt).second);
1349     }
1350   virtual void outstream (const myoutport& p)
1351     {
1352       DEBTRACE( "service_outstream" )             
1353       DEBTRACE( p._type )             
1354       DEBTRACE( p._name )             
1355       if(this->_node==0)
1356         throw Exception("ServiceNode must be completely defined before defining its ports");
1357       if(currentProc->typeMap.count(p._type)==0)
1358         {
1359           std::string msg="Unknown OutPort Type: ";
1360           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
1361           throw Exception(msg);
1362         }
1363       OutputDataStreamPort* port;
1364       port=this->_node->edAddOutputDataStreamPort(p._name,currentProc->typeMap[p._type]);
1365       // Set all properties for this port
1366       std::map<std::string, std::string>::const_iterator pt;
1367       for(pt=p._props.begin();pt!=p._props.end();pt++)
1368         port->setProperty((*pt).first,(*pt).second);
1369     }
1370   virtual T post()
1371     {
1372       DEBTRACE( "service_post " << this->_node->getName() )             
1373       this->mincount("method",1);
1374       if(this->_state == "disabled")this->_node->exDisabledState();
1375       return this->_node;
1376     }
1377 };
1378 static servicetypeParser<> serviceParser;
1379
1380 template <class T=mycontrol>
1381 struct controltypeParser: parser
1382 {
1383   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1384     {
1385       std::string element(el);
1386       parser* pp=&main_parser;
1387       this->maxcount("fromnode",1,element);
1388       this->maxcount("tonode",1,element);
1389       if(element == "fromnode")pp=&stringParser;
1390       else if(element == "tonode")pp=&stringParser;
1391       XML_SetUserData(p,pp);
1392       sp.push(pp);
1393       pp->init();
1394       pp->pre();
1395       pp->buildAttr(attr);
1396     }
1397   virtual void onEnd(const char *el,parser* child)
1398     {
1399       std::string element(el);
1400       if(element == "fromnode")fromnode(((stringtypeParser*)child)->post());
1401       else if(element == "tonode")tonode(((stringtypeParser*)child)->post());
1402     }
1403   virtual void pre ()
1404     {
1405       _link.clear();
1406     }
1407   virtual void fromnode (const std::string& name)
1408     {
1409       _link.fromnode(name);
1410     }
1411   virtual void tonode (const std::string& name)
1412     {
1413       _link.tonode(name);
1414     }
1415   virtual void property (const myprop& prop)
1416     {
1417       DEBTRACE( "property_set: " << prop._name << prop._value )             
1418       _link.setProperty(prop._name,prop._value);
1419     }
1420   virtual T& post()
1421     {
1422       mincount("fromnode",1);
1423       mincount("tonode",1);
1424       return _link;
1425     }
1426     T _link;
1427 };
1428 static controltypeParser<> controlParser;
1429
1430 template <class T=mylink>
1431 struct linktypeParser: controltypeParser<T>
1432 {
1433   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1434     {
1435       std::string element(el);
1436       this->maxcount("fromnode",1,element);
1437       this->maxcount("tonode",1,element);
1438       this->maxcount("fromport",1,element);
1439       this->maxcount("toport",1,element);
1440       parser* pp=&main_parser;
1441       if(element == "fromnode")pp=&stringParser;
1442       else if(element == "tonode")pp=&stringParser;
1443       else if(element == "toport")pp=&stringParser;
1444       else if(element == "fromport")pp=&stringParser;
1445       else if(element == "property")pp=&propertyParser;
1446       XML_SetUserData(p,pp);
1447       sp.push(pp);
1448       pp->init();
1449       pp->pre();
1450       pp->buildAttr(attr);
1451     }
1452   virtual void onEnd(const char *el,parser* child)
1453     {
1454       std::string element(el);
1455       if(element == "fromnode")this->fromnode(((stringtypeParser*)child)->post());
1456       else if(element == "tonode")this->tonode(((stringtypeParser*)child)->post());
1457       else if(element == "toport")toport(((stringtypeParser*)child)->post());
1458       else if(element == "fromport")fromport(((stringtypeParser*)child)->post());
1459       else if(element == "property")this->property(((propertytypeParser*)child)->post());
1460     }
1461   virtual void buildAttr(const XML_Char** attr)
1462     {
1463       for (int i = 0; attr[i]; i += 2) 
1464         {
1465           if((std::string(attr[i]) == "control")
1466              && (std::string(attr[i+1]) == "false"))
1467             this->_link._withControl=false;
1468         }
1469     }
1470   virtual void fromport (const std::string& name)
1471     {
1472       this->_link.fromport(name);
1473     }
1474   virtual void toport (const std::string& name)
1475     {
1476       this->_link.toport(name);
1477     }
1478   virtual T& post()
1479     {
1480       this->mincount("fromnode",1);
1481       this->mincount("tonode",1);
1482       this->mincount("fromport",1);
1483       this->mincount("toport",1);
1484       return this->_link;
1485     }
1486 };
1487 static linktypeParser<> linkParser;
1488
1489 template <class T=mystream>
1490 struct streamtypeParser: linktypeParser<T>
1491 {
1492 };
1493 static streamtypeParser<> streamParser;
1494
1495 static std::string t4[]={"string","objref","double","int","boolean","array","struct",""};
1496
1497 /*! \brief Class for XML-RPC value parser.
1498  *
1499  *  This class is used to parse XML data that describes a sequence in XML-RPC format
1500  *  Its XML schema is:
1501  *    <xsd:complexType name="ValueType">
1502  *      <xsd:choice >
1503  *        <xsd:element name="int" type="IntType"/>
1504  *        <xsd:element name="boolean" type="BooleanType"/>
1505  *        <xsd:element name="double" type="DoubleType"/>
1506  *        <xsd:element name="string" type="StringType"/>
1507  *        <xsd:element name="objref" type="ObjrefType"/>
1508  *        <xsd:element name="array" type="ArrayType"/>
1509  *        <xsd:element name="struct" type="StructType"/>
1510  *      </xsd:choice>
1511  *    </xsd:complexType>
1512  */
1513 struct valuetypeParser: parser
1514 {
1515   virtual void onStart(const XML_Char* el, const XML_Char** attr);
1516   virtual void onEnd(const char *el,parser* child);
1517   virtual void pre (){ }
1518   virtual void int_ (const int& d)
1519     {
1520       std::ostringstream os;
1521       os << "<int>"   << d<< "</int>";
1522       _data=os.str();
1523       _v.push_back(_data);
1524     }
1525   virtual void boolean (const bool& d)
1526     {
1527       std::ostringstream os;
1528       os << "<boolean>"   << d<< "</boolean>";
1529       _data=os.str();
1530       _v.push_back(_data);
1531     }
1532   virtual void double_ (const double& d)
1533     {
1534       std::ostringstream os;
1535       os << "<double>"<< d<< "</double>";
1536       _data=os.str();
1537       _v.push_back(_data);
1538     }
1539   virtual void string(const std::string& d)
1540     {
1541       _data="<string>"+ d+ "</string>";
1542       _v.push_back(_data);
1543     }
1544   virtual void objref(const std::string& d)
1545     {
1546       _data="<objref>"+ d+ "</objref>";
1547       _v.push_back(_data);
1548     }
1549   virtual void array (const std::string& d)
1550     {
1551       _v.push_back(d);
1552     }
1553   virtual void struct_ (const std::string& d)
1554     {
1555       _v.push_back(d);
1556     }
1557   virtual std::string post()
1558     {
1559       minchoice(t4,1);
1560       std::string value="<value>"+_v.back()+"</value>\n";
1561       _v.pop_back();
1562       return value;
1563     }
1564   std::string _data;
1565   std::vector<std::string> _v;
1566 };
1567 static valuetypeParser valueParser;
1568
1569 /*! \brief Class for XML-RPC data parser.
1570  *
1571  *  This class is used to parse XML data that describes a sequence in XML-RPC format
1572  *  Its XML schema is:
1573  *    <xsd:complexType name="DataType">
1574  *      <xsd:element name="value" type="ValueType"/>
1575  *    </xsd:complexType>
1576  */
1577 struct datatypeParser: parser
1578 {
1579   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1580     {
1581       std::string element(el);
1582       parser* pp=&main_parser;
1583       if(element == "value")pp=&valueParser;
1584       XML_SetUserData(p,pp);
1585       sp.push(pp);
1586       pp->init();
1587       pp->pre();
1588       pp->buildAttr(attr);
1589     }
1590   virtual void onEnd(const char *el,parser* child)
1591     {
1592       std::string element(el);
1593       if(element == "value")value(((valuetypeParser*)child)->post());
1594     }
1595   virtual void pre ()
1596     {
1597       _datas.push_back(_data);
1598       _data="";
1599     }
1600   virtual void value (const std::string& v){
1601       _data=_data+v;
1602     }
1603   virtual std::string post()
1604     {
1605       mincount("value",1);
1606       std::string d="<data>\n"+_data+"</data>";
1607       _data=_datas.back();
1608       _datas.pop_back();
1609       return d;
1610     }
1611   std::string _data;
1612   std::vector<std::string> _datas;
1613 };
1614 static datatypeParser dataParser;
1615
1616 /*! \brief Class for XML-RPC member parser.
1617  *
1618  *  This class is used to parse XML data that describes a sequence in XML-RPC format
1619  *  Its XML schema is:
1620  *    <xsd:complexType name="MemberDataType">
1621  *      <xsd:element name="name" type="StringType"/>
1622  *      <xsd:element name="value" type="ValueType"/>
1623  *    </xsd:complexType>
1624  */
1625 struct memberdatatypeParser: parser
1626 {
1627   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1628     {
1629       std::string element(el);
1630       parser* pp=&main_parser;
1631       if(element == "name")pp=&stringParser;
1632       else if(element == "value")pp=&valueParser;
1633       XML_SetUserData(p,pp);
1634       sp.push(pp);
1635       pp->init();
1636       pp->pre();
1637       pp->buildAttr(attr);
1638     }
1639   virtual void onEnd(const char *el,parser* child)
1640     {
1641       std::string element(el);
1642       this->maxcount("name",1,element);
1643       this->maxcount("value",1,element);
1644       if(element == "name")name(((stringtypeParser*)child)->post());
1645       else if(element == "value")value(((valuetypeParser*)child)->post());
1646     }
1647   virtual void pre ()
1648     {
1649       _datas.push_back(_data);
1650       _data="";
1651     }
1652   virtual void name (const std::string& v)
1653     {
1654       _data=_data+"<name>"+v+"</name>";
1655     }
1656   virtual void value (const std::string& v)
1657     {
1658       _data=_data+v;
1659     }
1660   virtual std::string post()
1661     {
1662       mincount("value",1);
1663       mincount("name",1);
1664       std::string d="<member>\n"+_data+"</member>";
1665       _data=_datas.back();
1666       _datas.pop_back();
1667       return d;
1668     }
1669   std::string _data;
1670   std::vector<std::string> _datas;
1671 };
1672 static memberdatatypeParser memberdataParser;
1673
1674 /*! \brief Class for XML-RPC struct parser.
1675  *
1676  *  This class is used to parse XML data that describes a sequence in XML-RPC format
1677  *  Its XML schema is:
1678  *    <xsd:complexType name="StructDataType">
1679  *      <xsd:element name="member" type="MemberDataType" minOccurs="1"/>
1680  *    </xsd:complexType>
1681  */
1682 struct structdatatypeParser: parser
1683 {
1684   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1685     {
1686       std::string element(el);
1687       parser* pp=&main_parser;
1688       if(element == "member")pp=&memberdataParser;
1689       XML_SetUserData(p,pp);
1690       sp.push(pp);
1691       pp->init();
1692       pp->pre();
1693       pp->buildAttr(attr);
1694     }
1695   virtual void onEnd(const char *el,parser* child)
1696     {
1697       std::string element(el);
1698       if(element == "member")member(((memberdatatypeParser*)child)->post());
1699     }
1700   virtual void pre ()
1701     {
1702       _membersStack.push_back(_members);
1703       _members="";
1704     }
1705   virtual void member (const std::string& d)
1706     {
1707       _members=_members+d;
1708     }
1709   virtual std::string post()
1710     {
1711       mincount("member",1);
1712       std::string value="<struct>"+_members+"</struct>";
1713       _members=_membersStack.back();
1714       _membersStack.pop_back();
1715       return value;
1716     }
1717   std::string _members;
1718   std::vector<std::string> _membersStack;
1719 };
1720 static structdatatypeParser structdataParser;
1721
1722 /*! \brief Class for XML-RPC array parser.
1723  *
1724  *  This class is used to parse XML data that describes a sequence in XML-RPC format
1725  *  Its XML schema is:
1726  *    <xsd:complexType name="ArrayType">
1727  *      <xsd:element name="data" type="DataType" minOccurs="1" maxOccurs="1"/>
1728  *    </xsd:complexType>
1729  */
1730 struct arraytypeParser: parser
1731 {
1732   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1733     {
1734       std::string element(el);
1735       this->maxcount("data",1,element);
1736       parser* pp=&main_parser;
1737       if(element == "data")pp=&dataParser;
1738       XML_SetUserData(p,pp);
1739       sp.push(pp);
1740       pp->init();
1741       pp->pre();
1742       pp->buildAttr(attr);
1743     }
1744   virtual void onEnd(const char *el,parser* child)
1745     {
1746       std::string element(el);
1747       if(element == "data")data(((datatypeParser*)child)->post());
1748     }
1749   virtual void pre (){ }
1750   virtual void data (const std::string& d)
1751     {
1752       _arrays.push_back(d);
1753     }
1754   virtual std::string post()
1755     {
1756       mincount("data",1);
1757       std::string value="<array>"+_arrays.back()+"</array>";
1758       _arrays.pop_back();
1759       return value;
1760     }
1761   std::vector<std::string> _arrays;
1762 };
1763 static arraytypeParser arrayParser;
1764
1765
1766 void valuetypeParser::onStart(const XML_Char* el, const XML_Char** attr)
1767 {
1768   std::string element(el);
1769   parser* pp=&main_parser;
1770   this->maxcount("string",1,element);
1771   this->maxcount("objref",1,element);
1772   this->maxcount("double",1,element);
1773   this->maxcount("int",1,element);
1774   this->maxcount("boolean",1,element);
1775   this->maxcount("array",1,element);
1776   this->maxcount("struct",1,element);
1777   this->maxchoice(t4,1,element);
1778   if(element == "string")pp=&stringParser;
1779   else if(element == "objref")pp=&stringParser;
1780   else if(element == "double")pp=&doubleParser;
1781   else if(element == "int")pp=&intParser;
1782   else if(element == "boolean")pp=&boolParser;
1783   else if(element == "array")pp=&arrayParser;
1784   else if(element == "struct")pp=&structdataParser;
1785   XML_SetUserData(p,pp);
1786   sp.push(pp);
1787   pp->init();
1788   pp->pre();
1789   pp->buildAttr(attr);
1790 }
1791
1792 void valuetypeParser::onEnd(const char *el,parser* child)
1793 {
1794   std::string element(el);
1795   if(element == "string")string(((stringtypeParser*)child)->post());
1796   else if(element == "objref")objref(((stringtypeParser*)child)->post());
1797   else if(element == "double")double_(((doubletypeParser*)child)->post());
1798   else if(element == "int")int_(((inttypeParser*)child)->post());
1799   else if(element == "boolean")boolean(((booltypeParser*)child)->post());
1800   else if(element == "array")array(((arraytypeParser*)child)->post());
1801   else if(element == "struct")struct_(((structdatatypeParser*)child)->post());
1802 }
1803
1804 struct parametertypeParser: parser
1805 {
1806   virtual void onStart(const XML_Char* el, const XML_Char** attr)
1807     {
1808       std::string element(el);
1809       this->maxcount("tonode",1,element);
1810       this->maxcount("toport",1,element);
1811       this->maxcount("value",1,element);
1812       parser* pp=&main_parser;
1813       if(element == "tonode")pp=&stringParser;
1814       else if(element == "toport")pp=&stringParser;
1815       else if(element == "value")pp=&valueParser;
1816       XML_SetUserData(p,pp);
1817       sp.push(pp);
1818       pp->init();
1819       pp->pre();
1820       pp->buildAttr(attr);
1821     }
1822   virtual void onEnd(const char *el,parser* child)
1823     {
1824       std::string element(el);
1825       if(element == "tonode")tonode(((stringtypeParser*)child)->post());
1826       else if(element == "toport")toport(((stringtypeParser*)child)->post());
1827       else if(element == "value")value(((valuetypeParser*)child)->post());
1828     }
1829     virtual void pre (){}
1830     virtual void tonode (const std::string& name){
1831       _param._tonode=name;
1832     }
1833     virtual void toport (const std::string& name){
1834       _param._toport=name;
1835     }
1836     virtual void value (const std::string& name){
1837       _param._value=name;
1838     }
1839     virtual myparam& post(){
1840       mincount("tonode",1);
1841       mincount("toport",1);
1842       mincount("value",1);
1843       return _param;
1844     }
1845     myparam _param;
1846 };
1847 static parametertypeParser paramParser;
1848
1849 static std::string t3[]={"inline","sinline","service","node","forloop","foreach","while","switch","bloc",""};
1850
1851 struct casetypeParser:parser
1852 {
1853   void onStart(const XML_Char* el, const XML_Char** attr);
1854   void onEnd(const char *el,parser* child);
1855   virtual void buildAttr(const XML_Char** attr)
1856     {
1857       this->required("id",attr);
1858       for (int i = 0; attr[i]; i += 2) 
1859         {
1860           if(std::string(attr[i]) == "id")id(atoi(attr[i+1]));
1861         }
1862     }
1863   virtual void pre ()
1864     {
1865       _cnode=0;
1866       _id=0;
1867     }
1868   virtual void id (const int& n)
1869     {
1870       DEBTRACE( "case_id: " << n )             
1871       _id=n;
1872       //store this level id
1873       _idStack.push_back(_id);
1874       //store this level name
1875       std::stringstream temp;
1876       if (_id <0) temp << "m" << -_id << "_";
1877       else temp << "p" << _id << "_";
1878       std::string fullname=currentProc->names.back()+temp.str();
1879       DEBTRACE( "case_fullname: " << fullname )             
1880       currentProc->names.push_back(fullname);
1881     }
1882   virtual void property (const myprop& prop)
1883     {
1884       DEBTRACE( "property_set: " << prop._name << prop._value )             
1885     }
1886   virtual void inline_ (InlineNode* const& n)
1887     {
1888       _cnode=n;
1889       std::string fullname=currentProc->names.back()+ n->getName();
1890       currentProc->nodeMap[fullname]=n;
1891       currentProc->inlineMap[fullname]=n;
1892     }
1893   virtual void sinline (ServiceInlineNode* const& n)
1894     {
1895       _cnode=n;
1896       std::string fullname=currentProc->names.back()+ n->getName();
1897       currentProc->nodeMap[fullname]=n;
1898       currentProc->serviceMap[fullname]=n;
1899     }
1900   virtual void service (ServiceNode* const& n)
1901     {
1902       _cnode=n;
1903       std::string fullname=currentProc->names.back()+ n->getName();
1904       currentProc->nodeMap[fullname]=n;
1905       currentProc->serviceMap[fullname]=n;
1906     }
1907   virtual void node (InlineNode* const& n)
1908     {
1909       _cnode=n;
1910       std::string fullname=currentProc->names.back()+ n->getName();
1911       currentProc->nodeMap[fullname]=n;
1912       currentProc->inlineMap[fullname]=n;
1913     }
1914   virtual void forloop (ForLoop* const& n)
1915     {
1916       _cnode=n;
1917       std::string fullname=currentProc->names.back()+ n->getName();
1918       currentProc->nodeMap[fullname]=n;
1919     }
1920   virtual void foreach (ForEachLoop* const& n)
1921     {
1922       _cnode=n;
1923       std::string fullname=currentProc->names.back()+ n->getName();
1924       currentProc->nodeMap[fullname]=n;
1925       fullname += ".splitter";
1926       currentProc->nodeMap[fullname]=n->getChildByShortName("splitter");
1927     }
1928   virtual void while_ (WhileLoop* const& n)
1929     {
1930       _cnode=n;
1931       std::string fullname=currentProc->names.back()+ n->getName();
1932       currentProc->nodeMap[fullname]=n;
1933     }
1934   virtual void switch_ (Switch* const& n)
1935     {
1936       _cnode=n;
1937       std::string fullname=currentProc->names.back()+ n->getName();
1938       currentProc->nodeMap[fullname]=n;
1939     }
1940   virtual void bloc (Bloc* const& n)
1941     {
1942       _cnode=n;
1943       std::string fullname=currentProc->names.back()+ n->getName();
1944       currentProc->nodeMap[fullname]=n;
1945     }
1946   virtual std::pair<int,Node*> post()
1947     {
1948       DEBTRACE( "case_post" )             
1949       minchoice(t3,1);
1950       //get back this level id
1951       _id=_idStack.back();
1952       _idStack.pop_back();
1953       //pop back this level name
1954       currentProc->names.pop_back();
1955       return std::pair<int,Node*>(_id,_cnode);
1956     }
1957   Node* _cnode;
1958   int _id;
1959   std::vector<int> _idStack;
1960 };
1961 static casetypeParser caseParser;
1962
1963 struct defaultcasetypeParser:casetypeParser
1964 {
1965   virtual void buildAttr(const XML_Char** attr)
1966     {
1967       for (int i = 0; attr[i]; i += 2) 
1968       {
1969         DEBTRACE( attr[i] << "=" << attr[i + 1] )             
1970       }
1971     }
1972   virtual void pre ()
1973     {
1974       _id=0;
1975       _cnode=0;
1976       //store this level id
1977       _idStack.push_back(_id);
1978       //store this level name
1979       std::string fullname=currentProc->names.back()+"default_";
1980       DEBTRACE( "case_fullname: " << fullname )             
1981       currentProc->names.push_back(fullname);
1982     }
1983 };
1984 static defaultcasetypeParser defaultcaseParser;
1985
1986 struct switchtypeParser:parser
1987 {
1988   void onStart(const XML_Char* el, const XML_Char** attr);
1989   void onEnd(const char *el,parser* child);
1990   virtual void buildAttr(const XML_Char** attr)
1991     {
1992       this->required("name",attr);
1993       for (int i = 0; attr[i]; i += 2) 
1994         {
1995           if(std::string(attr[i]) == "name")name(attr[i+1]);
1996           if(std::string(attr[i]) == "state")state(attr[i+1]);
1997           if(std::string(attr[i]) == "select")select(atoi(attr[i+1]));
1998         }
1999     }
2000   virtual void pre (){_state="";}
2001   virtual void case_ (const std::pair<int,Node*>& p)
2002     {
2003       Switch* s=_cnodes.back();
2004       s->edSetNode(p.first,p.second);
2005     }
2006   virtual void default_ (const std::pair<int,Node*>& p)
2007     {
2008       Switch* s=_cnodes.back();
2009       s->edSetDefaultNode(p.second);
2010     }
2011   virtual void name (const std::string& name)
2012     {
2013       Switch* s;
2014       std::string fullname=currentProc->names.back()+name;
2015       DEBTRACE( "switch_fullname: " << fullname )             
2016       s=theRuntime->createSwitch(name);
2017       _cnodes.push_back(s);
2018       currentProc->names.push_back(fullname+'.');
2019     }
2020   virtual void state (const std::string& state)
2021     {
2022       //state is an attribute (no order). It can be defined before name
2023       //To be improved
2024       Switch* s=_cnodes.back();
2025       if(_state == "disabled")
2026         {
2027           DEBTRACE( "Switch disabled: " << s->getName())             
2028           s->exDisabledState();
2029         }
2030     }
2031   virtual void select (const int& s)
2032     {
2033       //select is an attribute
2034       Switch* sw=_cnodes.back();
2035       InputPort *p=sw->edGetConditionPort();
2036       p->edInit(s);
2037     }
2038   virtual Switch* post ()
2039     {
2040       DEBTRACE( "switch_post: " )             
2041       Switch* sw=_cnodes.back();
2042       //pop back current level name and node
2043       _cnodes.pop_back();
2044       currentProc->names.pop_back();
2045       return sw;
2046     }
2047   // stack to store switches in case of switch in switch
2048   std::vector<Switch *> _cnodes;
2049   std::string _state;
2050 };
2051 static switchtypeParser switchParser;
2052
2053 template <class T=Loop*>
2054 struct looptypeParser:parser
2055 {
2056   void onStart(const XML_Char* el, const XML_Char** attr);
2057   void onEnd(const char *el,parser* child);
2058   virtual void buildAttr(const XML_Char** attr)
2059     {
2060       this->required("name",attr);
2061       for (int i = 0; attr[i]; i += 2) 
2062         {
2063           if(std::string(attr[i]) == "name")name(attr[i+1]);
2064           if(std::string(attr[i]) == "state")state(attr[i+1]);
2065         }
2066     }
2067   virtual void pre ()
2068     {
2069       _state="";
2070       _cnode=0;
2071     }
2072   virtual void name (const std::string& name)
2073     {
2074       DEBTRACE( "bloc_name: " << name );
2075     }
2076   virtual void state (const std::string& name)
2077     {
2078       DEBTRACE( "bloc_state: " << name );
2079       _state=name;
2080     }
2081   virtual void property (const myprop& prop)
2082     {
2083       DEBTRACE( "property_set" << prop._name << prop._value );
2084     }
2085   virtual void inline_ (InlineNode* const& n)
2086     {
2087       DEBTRACE( "loop_inline" << n->getName() );
2088       _cnode->edSetNode(n);
2089       std::string fullname=currentProc->names.back()+ n->getName();
2090       currentProc->nodeMap[fullname]=n;
2091       currentProc->inlineMap[fullname]=n;
2092     }
2093   virtual void sinline (ServiceInlineNode* const& n)
2094     {
2095       DEBTRACE( "loop_sinline" << n->getName() )             
2096       _cnode->edSetNode(n);
2097       std::string fullname=currentProc->names.back()+ n->getName();
2098       currentProc->nodeMap[fullname]=n;
2099       currentProc->serviceMap[fullname]=n;
2100     }
2101   virtual void service (ServiceNode* const& n)
2102     {
2103       DEBTRACE( "loop_service" << n->getName() )             
2104       _cnode->edSetNode(n);
2105       std::string fullname=currentProc->names.back()+ n->getName();
2106       currentProc->nodeMap[fullname]=n;
2107       currentProc->serviceMap[fullname]=n;
2108     }
2109   virtual void node (InlineNode* const& n)
2110     {
2111       DEBTRACE( "loop_node" << n->getName() )             
2112       _cnode->edSetNode(n);
2113       std::string fullname=currentProc->names.back()+ n->getName();
2114       currentProc->nodeMap[fullname]=n;
2115       currentProc->inlineMap[fullname]=n;
2116     }
2117   virtual void forloop (ForLoop* const& b)
2118     {
2119       DEBTRACE( "loop_forloop" << b->getName() )             
2120       _cnode->edSetNode(b);
2121       std::string fullname=currentProc->names.back()+ b->getName();
2122       currentProc->nodeMap[fullname]=b;
2123     }
2124   virtual void foreach (ForEachLoop* const& b)
2125     {
2126       DEBTRACE("loop_foreach" << b->getName())
2127       _cnode->edSetNode(b);
2128       std::string fullname=currentProc->names.back()+ b->getName();
2129       currentProc->nodeMap[fullname]=b;
2130       fullname += ".splitter";
2131       currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
2132     }
2133   virtual void while_ (WhileLoop* const& b)
2134     {
2135       DEBTRACE( "loop_while: " << b->getName() )             
2136       _cnode->edSetNode(b);
2137       std::string fullname=currentProc->names.back()+ b->getName();
2138       currentProc->nodeMap[fullname]=b;
2139     }
2140   virtual void switch_ (Switch* const& b)
2141     {
2142       DEBTRACE( "loop_switch: " << b->getName() )             
2143       _cnode->edSetNode(b);
2144       std::string fullname=currentProc->names.back()+ b->getName();
2145       currentProc->nodeMap[fullname]=b;
2146     }
2147   virtual void bloc (Bloc* const& b)
2148     {
2149       DEBTRACE( "loop_bloc " << b->getName() )             
2150       _cnode->edSetNode(b);
2151       std::string fullname=currentProc->names.back()+ b->getName();
2152       currentProc->nodeMap[fullname]=b;
2153     }
2154
2155   virtual void datalink (const mylink& l)
2156     {
2157       DEBTRACE( "loop_datalink: " << l.fromnode() << l.fromport() << l.tonode() << l.toport())
2158       std::string msg;
2159
2160       //Try only relative name for from node
2161       std::string fromname = currentProc->names.back()+l.fromnode();
2162       if(currentProc->nodeMap.count(fromname) == 0)
2163         {
2164           msg="from node " + l.fromnode() + " does not exist in data link: ";
2165           msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
2166           throw Exception(msg);
2167         }
2168       //Try relative name for to node and then absolute one
2169       std::string toname = currentProc->names.back()+l.tonode();
2170       if(currentProc->nodeMap.count(toname) == 0)
2171         {
2172           //It's not a relative name. Try an absolute one (I think it's not possible)
2173           toname=l.tonode();
2174           if(currentProc->nodeMap.count(toname) == 0)
2175             {
2176               // The TO node does not exist -> error
2177               msg="to node " + l.tonode() + " does not exist in data link: ";
2178               msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
2179               throw Exception(msg);
2180             }
2181         }
2182       // We only link local node and other nodes (relative or absolute name in this order)
2183       DEBTRACE(fromname <<":"<<l.fromport()<<toname<<":"<<l.toport());
2184       if (l.withControl())
2185         _cnode->edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
2186                             currentProc->nodeMap[toname]->getInputPort(l.toport()));
2187       else
2188         _cnode->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
2189                             currentProc->nodeMap[toname]->getInputPort(l.toport()));
2190     }
2191
2192   std::string _state;
2193   T _cnode;
2194   std::vector<T> _cnodes;
2195 };
2196
2197 template <class T=ForLoop*>
2198 struct forlooptypeParser:looptypeParser<T>
2199 {
2200   virtual void buildAttr(const XML_Char** attr)
2201     {
2202       this->required("name",attr);
2203       for (int i = 0; attr[i]; i += 2) 
2204         {
2205           if(std::string(attr[i]) == "name")name(attr[i+1]);
2206           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
2207           if(std::string(attr[i]) == "nsteps")nsteps(atoi(attr[i+1]));
2208         }
2209     }
2210   virtual void name (const std::string& name)
2211     {
2212       DEBTRACE( "forloop_name: " << name );
2213       std::string fullname=currentProc->names.back()+name;
2214       this->_cnode=theRuntime->createForLoop(name);
2215       currentProc->nodeMap[fullname]=this->_cnode;
2216       this->_cnodes.push_back(this->_cnode);
2217       currentProc->names.push_back(fullname+'.');
2218       _nsteps=0;
2219     }
2220   virtual void nsteps (const int& n)
2221     {
2222       DEBTRACE( "forloop_nsteps: " << n )             
2223       if(!this->_cnode)
2224           throw Exception("Node name must be defined before nsteps");
2225       InputPort *iNbTimes=this->_cnode->edGetNbOfTimesInputPort();
2226       iNbTimes->edInit(n);
2227     }
2228   virtual T post()
2229     {
2230       DEBTRACE( "forloop_post" )             
2231       this->minchoice(t3,1);
2232       T b=this->_cnode;
2233       this->_cnodes.pop_back();
2234       currentProc->names.pop_back();
2235       this->_cnode=this->_cnodes.back();
2236       return b;
2237     }
2238   int _nsteps;
2239 };
2240 static forlooptypeParser<> forloopParser;
2241
2242 template <class T=WhileLoop*>
2243 struct whilelooptypeParser:looptypeParser<T>
2244 {
2245   virtual void name (const std::string& name)
2246     {
2247       DEBTRACE( "while_name: " << name )             
2248       std::string fullname=currentProc->names.back()+name;
2249       this->_cnode=theRuntime->createWhileLoop(name);
2250       currentProc->nodeMap[fullname]=this->_cnode;
2251       this->_cnodes.push_back(this->_cnode);
2252       currentProc->names.push_back(fullname+'.');
2253     }
2254   virtual T post()
2255     {
2256       DEBTRACE( "while_post" << this->_cnode->getName() )             
2257       this->minchoice(t3,1);
2258       InputPort *cond=this->_cnode->edGetConditionPort();
2259       cond->edInit(true);
2260       T b=this->_cnode;
2261       this->_cnodes.pop_back();
2262       currentProc->names.pop_back();
2263       this->_cnode=this->_cnodes.back();
2264       return b;
2265     }
2266 };
2267 static whilelooptypeParser<> whileloopParser;
2268
2269 template <class T=ForEachLoop*>
2270 struct foreachlooptypeParser:looptypeParser<T>
2271 {
2272   virtual void buildAttr(const XML_Char** attr)
2273     {
2274       this->required("name",attr);
2275       this->required("type",attr);
2276       for (int i = 0; attr[i]; i += 2) 
2277         {
2278           if(std::string(attr[i]) == "name")name(attr[i+1]);
2279           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
2280           if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
2281           if(std::string(attr[i]) == "type")datatype(attr[i+1]);
2282         }
2283       postAttr();
2284     }
2285   virtual void pre ()
2286     {
2287       _nbranch=0;
2288       this->looptypeParser<T>::pre();
2289     }
2290   virtual void name (const std::string& name)
2291     {
2292       DEBTRACE("foreach_name: " << name)
2293       _name=name;
2294       _fullname=currentProc->names.back()+name;
2295     }
2296   virtual void nbranch (const int& n)
2297     {
2298       DEBTRACE("foreach_nbranch: " << n )
2299       _nbranch=n;
2300     }
2301   virtual void datatype (const std::string& type)
2302     {
2303       DEBTRACE("foreach_datatype: "<< type)
2304       _datatype=type;
2305     }
2306   virtual void postAttr()
2307     {
2308       if(currentProc->typeMap.count(_datatype)==0)
2309         {
2310           std::stringstream msg;
2311           msg << "Type "<< _datatype <<" does not exist"<<" ("<<__FILE__<<":"<<__LINE__<< ")";
2312           throw Exception(msg.str());
2313         }
2314       this->_cnode=theRuntime->createForEachLoop(_name,currentProc->typeMap[_datatype]);
2315       //set number of branches
2316       if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
2317       this->_cnodes.push_back(this->_cnode);
2318       currentProc->names.push_back(_fullname + '.');
2319     }
2320   virtual T post()
2321     {
2322       DEBTRACE("foreach_post" << this->_cnode->getName())
2323       this->minchoice(t3,1);
2324       T b=this->_cnode;
2325       this->_cnodes.pop_back();
2326       currentProc->names.pop_back();
2327       if(this->_cnodes.size() == 0)
2328         this->_cnode=0;
2329       else
2330         this->_cnode=this->_cnodes.back();
2331       return b;
2332     }
2333   int _nbranch;
2334   std::string _fullname;
2335   std::string _name;
2336   std::string _datatype;
2337 };
2338 static foreachlooptypeParser<> foreachloopParser;
2339
2340 template <class T=Bloc*>
2341 struct bloctypeParser:parser
2342 {
2343   bloctypeParser():parser()
2344   {
2345     _orders["property"]=0;
2346     _orders["inline"]=2;
2347     _orders["service"]=2;
2348     _orders["sinline"]=2;
2349     _orders["node"]=2;
2350     _orders["forloop"]=2;
2351     _orders["foreach"]=2;
2352     _orders["while"]=2;
2353     _orders["switch"]=2;
2354     _orders["bloc"]=2;
2355     _orders["control"]=3;
2356     _orders["datalink"]=3;
2357     _orders["stream"]=3;
2358     _orders["parameter"]=3;
2359   }
2360   virtual void onStart(const XML_Char* el, const XML_Char** attr);
2361   virtual void onEnd(const char *el,parser* child);
2362   virtual void buildAttr(const XML_Char** attr)
2363     {
2364       this->required("name",attr);
2365       for (int i = 0; attr[i]; i += 2) 
2366         {
2367           if(std::string(attr[i]) == "name")name(attr[i+1]);
2368           if(std::string(attr[i]) == "state")state(attr[i+1]);
2369         }
2370     }
2371   void name (const std::string& name)
2372     {
2373     }
2374   virtual void state (const std::string& name){
2375       DEBTRACE( "bloc_state: " << name )             
2376       _state=name;
2377       if(_state == "disabled")
2378         {
2379           DEBTRACE( "Bloc disabled: " << _bloc->getName())             
2380           _bloc->exDisabledState();
2381         }
2382     }
2383   virtual void property (const myprop& prop)
2384     {
2385       DEBTRACE( "property_set: " << prop._name << prop._value )             
2386       _bloc->setProperty(prop._name,prop._value);
2387     }
2388   virtual void inline_ (InlineNode* const& n)
2389     {
2390       DEBTRACE( "bloc_pynode_set: " << n->getName() )             
2391       _bloc->edAddChild(n);
2392       std::string fullname = currentProc->names.back()+n->getName();
2393       currentProc->nodeMap[fullname]=n;
2394       currentProc->inlineMap[fullname]=n;
2395     }
2396   virtual void sinline (ServiceInlineNode* const& n)
2397     {
2398       DEBTRACE( "bloc_sinline: " << n->getName() )             
2399       _bloc->edAddChild(n);
2400       std::string fullname = currentProc->names.back()+n->getName();
2401       currentProc->nodeMap[fullname]=n;
2402       currentProc->serviceMap[fullname]=n;
2403     }
2404   virtual void service (ServiceNode* const& n)
2405     {
2406       DEBTRACE( "bloc_service_set: " << n->getName() )             
2407       _bloc->edAddChild(n);
2408       std::string fullname = currentProc->names.back()+n->getName();
2409       currentProc->nodeMap[fullname]=n;
2410       currentProc->serviceMap[fullname]=n;
2411     }
2412   virtual void node (InlineNode* const& n)
2413     {
2414       DEBTRACE( "bloc_node_set: " << n->getName() )             
2415       _bloc->edAddChild(n);
2416       std::string fullname = currentProc->names.back()+n->getName();
2417       DEBTRACE( "bloc_node_set fullname = "  << fullname )             
2418       currentProc->nodeMap[fullname]=n;
2419       currentProc->inlineMap[fullname]=n;
2420     }
2421   virtual void forloop (ForLoop* const& b)
2422     {
2423       DEBTRACE( "bloc_forloop_set: " << b->getName() )             
2424       _bloc->edAddChild(b);
2425       std::string fullname = currentProc->names.back()+b->getName();
2426       currentProc->nodeMap[fullname]=b;
2427     }
2428   virtual void foreach (ForEachLoop* const& b)
2429     {
2430       DEBTRACE( "bloc_foreach_set: " << b->getName() )             
2431       _bloc->edAddChild(b);
2432       std::string fullname = currentProc->names.back()+b->getName();
2433       currentProc->nodeMap[fullname]=b;
2434       fullname += ".splitter";
2435       currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
2436     }
2437   virtual void while_ (WhileLoop* const& b)
2438     {
2439       DEBTRACE( "bloc_while_set: " << b->getName() )             
2440       _bloc->edAddChild(b);
2441       std::string fullname = currentProc->names.back()+b->getName();
2442       currentProc->nodeMap[fullname]=b;
2443     }
2444   virtual void switch_ (Switch* const& b)
2445     {
2446       DEBTRACE( "bloc_switch_set: " << b->getName() )             
2447       _bloc->edAddChild(b);
2448       std::string fullname = currentProc->names.back()+b->getName();
2449       currentProc->nodeMap[fullname]=b;
2450     }
2451   virtual void bloc (Bloc* const& b)
2452     {
2453       DEBTRACE( "bloc_bloc_set: " << b->getName() )             
2454       _bloc->edAddChild(b);
2455       std::string fullname=currentProc->names.back()+ b->getName();
2456       currentProc->nodeMap[fullname]=b;
2457     }
2458   virtual void control (const mycontrol& l)
2459     {
2460       DEBTRACE( "bloc_control_set: " << l.fromnode() << " "<< l.tonode() )             
2461       std::string msg;
2462
2463       if(currentProc->nodeMap.count(currentProc->names.back()+l.fromnode()) == 0)
2464         {
2465           msg="from node " + l.fromnode() + " does not exist in control link: ";
2466           msg=msg+l.fromnode()+"->"+l.tonode();
2467           msg=msg+ " context: "+currentProc->names.back();
2468           throw Exception(msg);
2469         }
2470       if(currentProc->nodeMap.count(currentProc->names.back()+l.tonode()) == 0)
2471         {
2472           msg="to node " + l.tonode() + " does not exist in control link: ";
2473           msg=msg+l.fromnode()+"->"+l.tonode();
2474           msg=msg+ " context: "+currentProc->names.back();
2475           throw Exception(msg);
2476         }
2477       // We only link local nodes
2478       _bloc->edAddCFLink(currentProc->nodeMap[currentProc->names.back()+l.fromnode()],
2479                          currentProc->nodeMap[currentProc->names.back()+l.tonode()]);
2480     }
2481   virtual void datalink (const mylink& l)
2482     {
2483       DEBTRACE( "bloc_datalink_set: "<<l.fromnode()<<"("<<l.fromport()<<")->"<<l.tonode()<<"("<<l.toport()<<")")
2484       std::string msg;
2485
2486       //Try only relative name for from node
2487       std::string fromname = currentProc->names.back()+l.fromnode();
2488       if(currentProc->nodeMap.count(fromname) == 0)
2489         {
2490           msg="from node " + l.fromnode() + " does not exist in data link: ";
2491           msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
2492           throw Exception(msg);
2493         }
2494       //Try relative name for to node and then absolute one
2495       std::string toname = currentProc->names.back()+l.tonode();
2496       if(currentProc->nodeMap.count(toname) == 0)
2497         {
2498           //It's not a relative name. Try an absolute one (I think it's not possible)
2499           toname=l.tonode();
2500           if(currentProc->nodeMap.count(toname) == 0)
2501             {
2502               // The TO node does not exist -> error
2503               msg="to node " + l.tonode() + " does not exist in data link: ";
2504               msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
2505               throw Exception(msg);
2506             }
2507         }
2508       // We only link local node and other nodes (relative or absolute name in this order)
2509       DEBTRACE(fromname <<":"<<l.fromport()<<toname<<":"<<l.toport())
2510       if (l.withControl())
2511         _bloc->edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
2512                             currentProc->nodeMap[toname]->getInputPort(l.toport()));
2513       else
2514         _bloc->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
2515                             currentProc->nodeMap[toname]->getInputPort(l.toport()));
2516     }
2517   virtual void stream (const mystream& l)
2518     {
2519       DEBTRACE( "bloc_stream_set: " << l.fromnode() << l.fromport() << l.tonode() << l.toport() )
2520       std::string msg;
2521       std::string fromname = currentProc->names.back()+l.fromnode();
2522       std::string toname = currentProc->names.back()+l.tonode();
2523       //only relative names
2524       if(currentProc->nodeMap.count(fromname) == 0)
2525         {
2526             msg="from node " + l.fromnode() + " does not exist in stream link: ";
2527             msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
2528             throw Exception(msg);
2529         }
2530       if(currentProc->nodeMap.count(toname) == 0)
2531         {
2532             msg="to node " + l.tonode() + " does not exist in stream link: ";
2533             msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
2534             throw Exception(msg);
2535         }
2536       OutputDataStreamPort* pout=currentProc->nodeMap[fromname]->getOutputDataStreamPort(l.fromport());
2537       InputDataStreamPort* pin=currentProc->nodeMap[toname]->getInputDataStreamPort(l.toport());
2538       _bloc->edAddLink(pout,pin);
2539       // Set all properties for this link
2540       std::map<std::string, std::string>::const_iterator pt;
2541       for(pt=l._props.begin();pt!=l._props.end();pt++)
2542         {
2543           pin->setProperty((*pt).first,(*pt).second);
2544           pout->setProperty((*pt).first,(*pt).second);
2545         }
2546     }
2547   virtual void parameter (const myparam& p)
2548     {
2549       DEBTRACE( "++++++++++++++++++++Parameter+++++++++++++++++++++" )             
2550       std::string msg;
2551       std::string toname = currentProc->names.back()+p._tonode;
2552       if(currentProc->nodeMap.count(toname) == 0)
2553         {
2554           msg="to node " + p._tonode + " does not exist in parameter: ";
2555           msg=msg+"->"+p._tonode+"("+p._toport+")";
2556           throw Exception(msg);
2557         }
2558       InputPort* inport=currentProc->nodeMap[toname]->getInputPort(p._toport);
2559       //We don't know the parameter type. So we try to initialize the port
2560       //with the value. If it's not the right type, edInit throws an exception
2561       //std::cerr << "----------------------------- " << p.value.c_str() << std::endl;
2562       inport->edInit("XML",p._value.c_str());
2563       DEBTRACE( "++++++++++++++++++++End parameter+++++++++++++++++++++" )             
2564     }
2565   T post()
2566     {
2567       DEBTRACE( "bloc_post" )             
2568       currentProc->names.pop_back();
2569       T b=_bloc;
2570       _blocs.pop_back();
2571       if(_blocs.empty())
2572         _bloc=NULL;
2573       else
2574         _bloc=_blocs.back();
2575       return b;
2576     }
2577   T _bloc;
2578   std::string _state;
2579   std::vector<Bloc *> _blocs;
2580 };
2581 static bloctypeParser<> blocParser;
2582
2583 template <>
2584 void bloctypeParser<Bloc*>::name (const std::string& name)
2585 {
2586   DEBTRACE( "bloc_name: " << name )             
2587   std::string fullname=currentProc->names.back()+name;
2588   _bloc=theRuntime->createBloc(name);
2589   _blocs.push_back(_bloc);
2590   currentProc->names.push_back(fullname+'.');
2591 }
2592
2593 void switchtypeParser::onStart(const XML_Char* el, const XML_Char** attr)
2594 {
2595   DEBTRACE( "switchtypeParser::onStart: " << el )             
2596   std::string element(el);
2597   this->maxcount("default",1,element);
2598   parser* pp=&main_parser;
2599   if(element == "case")pp=&caseParser;
2600   else if(element == "default")pp=&defaultcaseParser;
2601   XML_SetUserData(p,pp);
2602   sp.push(pp);
2603   pp->init();
2604   pp->pre();
2605   pp->buildAttr(attr);
2606 }
2607 void switchtypeParser::onEnd(const char *el,parser* child)
2608 {
2609   DEBTRACE( "switchtypeParser::onEnd: " << el )             
2610   std::string element(el);
2611   if(element == "case")case_(((casetypeParser*)child)->post());
2612   else if(element == "default")default_(((defaultcasetypeParser*)child)->post());
2613 }
2614
2615
2616 void casetypeParser::onStart(const XML_Char* el, const XML_Char** attr)
2617 {
2618   DEBTRACE( "casetypeParser::onStart: " << el )             
2619   std::string element(el);
2620   this->maxcount("inline",1,element);
2621   this->maxcount("sinline",1,element);
2622   this->maxcount("service",1,element);
2623   this->maxcount("node",1,element);
2624   this->maxcount("forloop",1,element);
2625   this->maxcount("foreach",1,element);
2626   this->maxcount("while",1,element);
2627   this->maxcount("switch",1,element);
2628   this->maxcount("bloc",1,element);
2629   this->maxchoice(t3,1,element);
2630   parser* pp=&main_parser;
2631   if(element == "property")pp=&propertyParser;
2632   else if(element == "inline")pp=&inlineParser;
2633   else if(element == "sinline")pp=&sinlineParser;
2634   else if(element == "service")pp=&serviceParser;
2635   else if(element == "node")pp=&nodeParser;
2636   else if(element == "forloop")pp=&forloopParser;
2637   else if(element == "foreach")pp=&foreachloopParser;
2638   else if(element == "while")pp=&whileloopParser;
2639   else if(element == "switch")pp=&switchParser;
2640   else if(element == "bloc")pp=&blocParser;
2641   XML_SetUserData(p,pp);
2642   sp.push(pp);
2643   pp->init();
2644   pp->pre();
2645   pp->buildAttr(attr);
2646 }
2647
2648 void casetypeParser::onEnd(const char *el,parser* child)
2649 {
2650   DEBTRACE( "casetypeParser::onEnd: " << el )             
2651   std::string element(el);
2652   if(element == "property")property(((propertytypeParser*)child)->post());
2653   else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
2654   else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
2655   else if(element == "service")service(((servicetypeParser<>*)child)->post());
2656   else if(element == "node")node(((nodetypeParser<>*)child)->post());
2657   else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
2658   else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
2659   else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
2660   else if(element == "switch")switch_(((switchtypeParser*)child)->post());
2661   else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
2662 }
2663
2664 template <class T>
2665 void looptypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
2666 {
2667   DEBTRACE( "looptypeParser::onStart: " << el )             
2668   std::string element(el);
2669   this->maxcount("inline",1,element);
2670   this->maxcount("sinline",1,element);
2671   this->maxcount("service",1,element);
2672   this->maxcount("node",1,element);
2673   this->maxcount("forloop",1,element);
2674   this->maxcount("foreach",1,element);
2675   this->maxcount("while",1,element);
2676   this->maxcount("switch",1,element);
2677   this->maxcount("bloc",1,element);
2678   this->maxchoice(t3,1,element);
2679   parser* pp=&main_parser;
2680   if(element == "property")pp=&propertyParser;
2681   else if(element == "inline")pp=&inlineParser;
2682   else if(element == "sinline")pp=&sinlineParser;
2683   else if(element == "service")pp=&serviceParser;
2684   else if(element == "node")pp=&nodeParser;
2685   else if(element == "forloop")pp=&forloopParser;
2686   else if(element == "foreach")pp=&foreachloopParser;
2687   else if(element == "while")pp=&whileloopParser;
2688   else if(element == "switch")pp=&switchParser;
2689   else if(element == "bloc")pp=&blocParser;
2690   else if(element == "datalink")pp=&linkParser;
2691   XML_SetUserData(p,pp);
2692   sp.push(pp);
2693   pp->init();
2694   pp->pre();
2695   pp->buildAttr(attr);
2696 }
2697 template <class T>
2698 void looptypeParser<T>::onEnd(const char *el,parser* child)
2699 {
2700   DEBTRACE( "looptypeParser::onEnd: " << el )             
2701   std::string element(el);
2702   if(element == "property")property(((propertytypeParser*)child)->post());
2703   else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
2704   else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
2705   else if(element == "service")service(((servicetypeParser<>*)child)->post());
2706   else if(element == "node")node(((nodetypeParser<>*)child)->post());
2707   else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
2708   else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
2709   else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
2710   else if(element == "switch")switch_(((switchtypeParser*)child)->post());
2711   else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
2712   else if(element == "datalink") datalink(((linktypeParser<>*)child)->post());
2713 }
2714
2715 template <class T>
2716 void bloctypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
2717 {
2718   DEBTRACE( "bloctypeParser::onStart: " << el )             
2719   std::string element(el);
2720   checkOrder(element);
2721   parser* pp=&main_parser;
2722   if(element == "property")pp=&propertyParser;
2723   else if(element == "inline")pp=&inlineParser;
2724   else if(element == "sinline")pp=&sinlineParser;
2725   else if(element == "service")pp=&serviceParser;
2726   else if(element == "node")pp=&nodeParser;
2727   else if(element == "forloop")pp=&forloopParser;
2728   else if(element == "foreach")pp=&foreachloopParser;
2729   else if(element == "while")pp=&whileloopParser;
2730   else if(element == "switch")pp=&switchParser;
2731   else if(element == "bloc")pp=&blocParser;
2732   else if(element == "control")pp=&controlParser;
2733   else if(element == "datalink")pp=&linkParser;
2734   else if(element == "stream")pp=&streamParser;
2735   else if(element == "parameter")pp=&paramParser;
2736   XML_SetUserData(p,pp);
2737   sp.push(pp);
2738   pp->init();
2739   pp->pre();
2740   pp->buildAttr(attr);
2741 }
2742 template <class T>
2743 void bloctypeParser<T>::onEnd(const char *el,parser* child)
2744 {
2745   DEBTRACE( "bloctypeParser::onEnd: " << el )             
2746   std::string element(el);
2747   if(element == "property")property(((propertytypeParser*)child)->post());
2748   else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
2749   else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
2750   else if(element == "service")service(((servicetypeParser<>*)child)->post());
2751   else if(element == "node")node(((nodetypeParser<>*)child)->post());
2752   else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
2753   else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
2754   else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
2755   else if(element == "switch")switch_(((switchtypeParser*)child)->post());
2756   else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
2757   else if(element == "control") control(((controltypeParser<>*)child)->post());
2758   else if(element == "datalink") datalink(((linktypeParser<>*)child)->post());
2759   else if(element == "stream") stream(((streamtypeParser<>*)child)->post());
2760   else if(element == "parameter") parameter(((parametertypeParser*)child)->post());
2761 }
2762
2763 template <class T=Proc*>
2764 struct proctypeParser:bloctypeParser<T>
2765 {
2766   proctypeParser():bloctypeParser<T>()
2767   {
2768     this->_orders["type"]=1;
2769     this->_orders["sequence"]=1;
2770     this->_orders["objref"]=1;
2771   }
2772   void onStart(const XML_Char* el, const XML_Char** attr)
2773   {
2774     DEBTRACE( "proctypeParser::onStart: " << el )             
2775     std::string element(el);
2776     this->checkOrder(element);
2777     parser* pp=&main_parser;
2778     if(element == "property")pp=&propertyParser;
2779     else if(element == "type")pp=&typeParser;
2780     else if(element == "sequence")pp=&seqParser;
2781     else if(element == "objref")pp=&objParser;
2782     else if(element == "struct")pp=&structParser;
2783     else if(element == "container")pp=&containerParser;
2784     else if(element == "inline")pp=&inlineParser;
2785     else if(element == "sinline")pp=&sinlineParser;
2786     else if(element == "service")pp=&serviceParser;
2787     else if(element == "node")pp=&nodeParser;
2788     else if(element == "forloop")pp=&forloopParser;
2789     else if(element == "foreach")pp=&foreachloopParser;
2790     else if(element == "while")pp=&whileloopParser;
2791     else if(element == "switch")pp=&switchParser;
2792     else if(element == "bloc")pp=&blocParser;
2793     else if(element == "control")pp=&controlParser;
2794     else if(element == "datalink")pp=&linkParser;
2795     else if(element == "stream")pp=&streamParser;
2796     else if(element == "parameter")pp=&paramParser;
2797     else 
2798       {
2799         // OCC: san -- Allow external parsers for handling of unknown elements
2800         // and attributes. This capability is used by YACS GUI to read
2801         // graph presentation data
2802         if ( this->_defaultParsersMap ) 
2803           {
2804             if((this->_defaultParsersMap)->count(element) != 0)
2805               {
2806                 pp=(*(this->_defaultParsersMap))[element];
2807               }
2808             else
2809               {
2810                 std::cerr << "There is no parser for this element type. It will be ignored!" << std::endl; 
2811               }
2812           }
2813       }
2814     XML_SetUserData(p,pp);
2815     sp.push(pp);
2816     pp->init();
2817     pp->pre();
2818     pp->buildAttr(attr);
2819   }
2820   virtual void onEnd(const char *el,parser* child)
2821     {
2822       DEBTRACE( "proctypeParser::onEnd: " << el )             
2823       std::string element(el);
2824       if(element == "property")this->property(((propertytypeParser*)child)->post());
2825       else if(element == "type")type(((typetypeParser*)child)->post());
2826       else if(element == "sequence")sequence(((seqtypeParser*)child)->post());
2827       else if(element == "objref")objref(((objtypeParser*)child)->post());
2828       else if(element == "struct")struct_(((structtypeParser*)child)->post());
2829       else if(element == "container")container(((containertypeParser*)child)->post());
2830       else if(element == "inline")this->inline_(((inlinetypeParser<>*)child)->post());
2831       else if(element == "sinline")this->sinline(((sinlinetypeParser<>*)child)->post());
2832       else if(element == "service")this->service(((servicetypeParser<>*)child)->post());
2833       else if(element == "node")this->node(((nodetypeParser<>*)child)->post());
2834       else if(element == "forloop")this->forloop(((forlooptypeParser<>*)child)->post());
2835       else if(element == "foreach")this->foreach(((foreachlooptypeParser<>*)child)->post());
2836       else if(element == "while")this->while_(((whilelooptypeParser<>*)child)->post());
2837       else if(element == "switch")this->switch_(((switchtypeParser*)child)->post());
2838       else if(element == "bloc")this->bloc(((bloctypeParser<>*)child)->post());
2839       else if(element == "control") this->control(((controltypeParser<>*)child)->post());
2840       else if(element == "datalink") this->datalink(((linktypeParser<>*)child)->post());
2841       else if(element == "stream") this->stream(((streamtypeParser<>*)child)->post());
2842       else if(element == "parameter") this->parameter(((parametertypeParser*)child)->post());
2843     }
2844   virtual void buildAttr(const XML_Char** attr)
2845     {
2846       for (int i = 0; attr[i]; i += 2) 
2847         {
2848           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
2849         }
2850     }
2851   virtual void pre ()
2852     {
2853         std::string name("proc");
2854         currentProc=theRuntime->createProc(name);
2855         this->_bloc=currentProc;
2856         currentProc->names.push_back("");
2857     }
2858   virtual void type (const mytype& t)
2859     {
2860         DEBTRACE( "type_set" )             
2861         currentProc->typeMap[t._name]=currentProc->createType(t._name,t._kind);
2862     }
2863   virtual void sequence (TypeCode* const& t)
2864     {
2865         DEBTRACE( "sequence_set" )             
2866         currentProc->typeMap[t->name()]=t;
2867     }
2868   virtual void objref (TypeCode* const& t)
2869     {
2870         DEBTRACE( "objref_set" )             
2871         currentProc->typeMap[t->name()]=t;
2872     }
2873   virtual void struct_ (TypeCode* const& t)
2874     {
2875         DEBTRACE( "struct_set" )             
2876         currentProc->typeMap[t->name()]=t;
2877     }
2878   virtual void container (const mycontainer& t)
2879     {
2880       DEBTRACE( "container_set: " << t._name )             
2881       std::vector<machine>::const_iterator iter;
2882       for(iter=t._machs.begin();iter!=t._machs.end();iter++)
2883         {
2884           DEBTRACE( "machine name: " << (*iter)._name )             
2885         }
2886
2887       if(currentProc->containerMap.count(t._name) == 0)
2888         {
2889           YACS::ENGINE::Container* cont=theRuntime->createContainer();
2890           // Set all properties for this container
2891           std::map<std::string, std::string>::const_iterator pt;
2892           for(pt=t._props.begin();pt!=t._props.end();pt++)
2893             cont->setProperty((*pt).first,(*pt).second);
2894           currentProc->containerMap[t._name]=cont;
2895         }
2896       else
2897         {
2898           std::cerr << "Warning: container " << t._name << " already defined. It will be ignored" << std::endl;
2899         }
2900     }
2901
2902   T post(){return this->_bloc;}
2903 };
2904 static proctypeParser<> procParser;
2905
2906 struct roottypeParser:parser
2907 {
2908   void onStart(const XML_Char* el, const XML_Char** attr)
2909     {
2910       DEBTRACE( "roottypeParser::onStart: " << el )             
2911       std::string element(el);
2912       parser* pp=&main_parser;
2913       if(element == "proc")pp=&procParser;
2914       XML_SetUserData(p,pp);
2915       sp.push(pp);
2916       pp->init();
2917       pp->pre();
2918       pp->buildAttr(attr);
2919     }
2920   virtual void onEnd(const char *el,parser* child)
2921     {
2922       DEBTRACE( "roottypeParser::onEnd: " << el )             
2923       std::string element(el);
2924       if(element == "proc")proc(((proctypeParser<>*)child)->post());
2925     }
2926   virtual void proc (Proc* const& b)
2927     {
2928       DEBTRACE( "root_proc_set" << b->getName() )             
2929       _proc=b;
2930     }
2931   Proc* _proc;
2932 };
2933 static roottypeParser rootParser;
2934
2935 YACSLoader::YACSLoader()
2936 {
2937   theRuntime = getRuntime();
2938 }
2939
2940 Proc* YACSLoader::load(const char * file)
2941 {
2942   FILE* fin=fopen(file,"r");
2943   if (! fin) 
2944     {
2945       std::cerr << "Couldn't open schema file" << std::endl;
2946       throw std::invalid_argument("Couldn't open schema file");
2947       //throw Exception("Couldn't open schema file");
2948     }
2949
2950   p = XML_ParserCreate(NULL);
2951   if (! p) 
2952     {
2953       std::cerr << "Couldn't allocate memory for parser" << std::endl;
2954       throw Exception("Couldn't allocate memory for parser");
2955     }
2956   XML_SetElementHandler(p, parser::start,parser::end);
2957   XML_SetCharacterDataHandler(p,parser::charac );
2958   XML_SetUserData(p,&rootParser);
2959   sp.push(&rootParser);
2960   // OCC: san -- Allow external parsers for handling of unknown elements
2961   // and attributes. This capability is used by YACS GUI to read
2962   // graph presentation data
2963   if ( !_defaultParsersMap.empty() )
2964     procParser._defaultParsersMap = &_defaultParsersMap;
2965   
2966   try
2967     {
2968       for (;;) 
2969         {
2970           int done;
2971           int len;
2972
2973           len = fread(Buff, 1, BUFFSIZE, fin);
2974           if (ferror(fin)) 
2975             {
2976               std::cerr << "Read error" << std::endl;
2977               throw Exception("Read error");
2978             }
2979           done = feof(fin);
2980
2981           if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) 
2982             {
2983               throw Exception(XML_ErrorString(XML_GetErrorCode(p)));
2984             }
2985
2986           if (done)
2987             break;
2988         }
2989       XML_ParserFree (p);
2990       p=0;
2991       return rootParser._proc;
2992     }
2993   catch(Exception& e)
2994     {
2995       //get line number from XML parser
2996       std::cerr << "Error at line: " << XML_GetCurrentLineNumber(p) << std::endl;
2997       delete currentProc;
2998       currentProc=0;
2999       throw e;
3000     }
3001 }
3002
3003 YACSLoader::~YACSLoader()
3004 {
3005 }