Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / yacsloader / typeParsers.cxx
1
2 #include "typeParsers.hxx"
3 #include "dataParsers.hxx"
4 #include "Exception.hxx"
5 #include "Proc.hxx"
6 #include "Runtime.hxx"
7
8 #include <sstream>
9
10 //#define _DEVDEBUG_
11 #include "YacsTrace.hxx"
12
13 extern YACS::ENGINE::Proc* currentProc;
14 extern YACS::ENGINE::Runtime* theRuntime;
15
16 namespace YACS
17 {
18   typetypeParser typetypeParser::typeParser;
19   seqtypeParser seqtypeParser::seqParser;
20   objtypeParser objtypeParser::objParser;
21   structtypeParser structtypeParser::structParser;
22   membertypeParser membertypeParser::memberParser;
23
24   void typetypeParser::buildAttr(const XML_Char** attr)
25     {
26       required("name",attr);
27       required("kind",attr);
28       for (int i = 0; attr[i]; i += 2) 
29         {
30           if(std::string(attr[i]) == "name")name(attr[i+1]);
31           if(std::string(attr[i]) == "kind")kind(attr[i+1]);
32         }
33     }
34   void typetypeParser::pre (){}
35   void typetypeParser::name(const std::string& name)
36     {
37       DEBTRACE( "type_name: " << name )             
38       _name=name;
39     }
40   void typetypeParser::kind(const std::string& name)
41     {
42       DEBTRACE( "type_kind: " << name )             
43       _kind=name;
44     }
45   mytype typetypeParser::post()
46     {
47       DEBTRACE( "type_post" )             
48       mytype t;
49       t._kind=_kind;
50       t._name=_name;
51       return t;
52     }
53
54   void seqtypeParser::onStart(const XML_Char* el, const XML_Char** attr)
55     {
56       DEBTRACE( "seqtypeParser::onStart: " << el )             
57       parser* pp=&parser::main_parser;
58       SetUserDataAndPush(pp);
59       pp->init();
60       pp->pre();
61       pp->buildAttr(attr);
62     }
63   void seqtypeParser::onEnd(const char *el,parser* child)
64     {
65       DEBTRACE( "seqtypeParser::onEnd: " << el )             
66     }
67   void seqtypeParser::buildAttr(const XML_Char** attr)
68     {
69       required("name",attr);
70       required("content",attr);
71       for (int i = 0; attr[i]; i += 2) 
72         {
73           if(std::string(attr[i]) == "name")name(attr[i+1]);
74           if(std::string(attr[i]) == "content")content(attr[i+1]);
75         }
76     }
77   void seqtypeParser::name(const std::string& name)
78     {
79       DEBTRACE( "seqtype_name: " << name )             
80       _name=name;
81     }
82   void seqtypeParser::content(const std::string& name)
83     {
84       DEBTRACE( "seqtype_content: " << name )             
85       if(currentProc->typeMap.count(name)==0)
86       {
87         //Check if the typecode is defined in the runtime
88         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(name);
89         if(t==0)
90         {
91           std::stringstream msg;
92           msg << "Type " << name << " does not exist" << " (" <<__FILE__ << ":" << __LINE__ << ")";
93           throw Exception(msg.str());
94         }
95         else
96         {
97           currentProc->typeMap[name]=t;
98           t->incrRef();
99         }
100       }
101       _contentType=currentProc->typeMap[name];
102
103     }
104   ENGINE::TypeCode* seqtypeParser::post()
105     {
106       DEBTRACE( "seqtype_post" )             
107       ENGINE::TypeCode *t = currentProc->createSequenceTc(_name,_name,_contentType);
108       return t;
109     }
110
111   void objtypeParser::onStart(const XML_Char* el, const XML_Char** attr)
112     {
113       DEBTRACE( "objtypeParser::onStart: " << el )             
114       std::string element(el);
115       parser* pp=&parser::main_parser;
116       if(element == "base")pp=&stringtypeParser::stringParser;
117       SetUserDataAndPush(pp);
118       pp->init();
119       pp->pre();
120       pp->buildAttr(attr);
121     }
122   void objtypeParser::onEnd(const char *el,parser* child)
123     {
124       DEBTRACE( "objtypeParser::onEnd: " << el )             
125       std::string element(el);
126       if(element == "base")base(((stringtypeParser*)child)->post());
127     }
128   void objtypeParser::buildAttr(const XML_Char** attr)
129     {
130       required("name",attr);
131       for (int i = 0; attr[i]; i += 2) 
132         {
133           if(std::string(attr[i]) == "name")name(attr[i+1]);
134           if(std::string(attr[i]) == "id")id(attr[i+1]);
135         }
136     }
137   void objtypeParser::pre ()
138     {
139       _id="";
140       _ltc.clear();
141     }
142   void objtypeParser::name(const std::string& name)
143     {
144       DEBTRACE( "objtype_name: " << name )             
145       _name=name;
146     }
147   void objtypeParser::id(const std::string& name)
148     {
149       DEBTRACE( "objtype_id: " << name )             
150       _id=name;
151     }
152   void objtypeParser::base(const std::string& name)
153     {
154       DEBTRACE( "base_name: " << name )             
155       if(currentProc->typeMap.count(name)==0)
156       {
157         //Check if the typecode is defined in the runtime
158         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(name);
159         if(t==0)
160         {
161           std::stringstream msg;
162           msg << "Type " << name << " does not exist" << " (" <<__FILE__ << ":" << __LINE__ << ")";
163           throw Exception(msg.str());
164         }
165         else
166         {
167           currentProc->typeMap[name]=t;
168           t->incrRef();
169         }
170       }
171       if(currentProc->typeMap[name]->kind() != ENGINE::Objref)
172         {
173           std::stringstream msg;
174           msg << "Type " << name << " is not an objref" ;
175           msg << " (" <<__FILE__ << ":" << __LINE__ << ")";
176           throw Exception(msg.str());
177         }
178       _ltc.push_back((ENGINE::TypeCodeObjref *)currentProc->typeMap[name]);
179     }
180   ENGINE::TypeCode * objtypeParser::post()
181     {
182       DEBTRACE( "objtype_post" )             
183       ENGINE::TypeCode *t = currentProc->createInterfaceTc(_id,_name,_ltc);
184       return t;
185     }
186
187   void membertypeParser::buildAttr(const XML_Char** attr)
188     {
189       required("name",attr);
190       required("type",attr);
191       for (int i = 0; attr[i]; i += 2)
192       {
193         if(std::string(attr[i]) == "name")name(attr[i+1]);
194         if(std::string(attr[i]) == "type")type(attr[i+1]);
195       }
196     }
197   void membertypeParser::name(const std::string& name){ _prop._name=name; }
198   void membertypeParser::type(const std::string& name){ _prop._value=name; }
199   myprop membertypeParser::post(){return _prop;}
200
201   void structtypeParser::onStart(const XML_Char* el, const XML_Char** attr)
202     {
203       DEBTRACE( "structtypeParser::onStart: " << el )             
204       std::string element(el);
205       parser* pp=&parser::main_parser;
206       if(element == "member")pp=&membertypeParser::memberParser;
207       SetUserDataAndPush(pp);
208       pp->init();
209       pp->pre();
210       pp->buildAttr(attr);
211     }
212   void structtypeParser::onEnd(const char *el,parser* child)
213     {
214       DEBTRACE( "structtypeParser::onEnd: " << el )             
215       std::string element(el);
216       if(element == "member")member(((membertypeParser*)child)->post());
217     }
218   void structtypeParser::buildAttr(const XML_Char** attr)
219     {
220       required("name",attr);
221       for (int i = 0; attr[i]; i += 2) 
222         {
223           if(std::string(attr[i]) == "name")name(attr[i+1]);
224           if(std::string(attr[i]) == "id")id(attr[i+1]);
225         }
226     }
227   void structtypeParser::pre ()
228     {
229       _id="";
230       _members.clear();
231     }
232   void structtypeParser::name(const std::string& name)
233     {
234       DEBTRACE( "structtype_name: " << name );
235       _name=name;
236     }
237   void structtypeParser::id(const std::string& name)
238     {
239       DEBTRACE( "structtype_id: " << name );
240       _id=name;
241     }
242   void structtypeParser::member (const myprop& prop)
243     {
244       DEBTRACE( "structtype_member: " << prop._name << prop._value );
245       if(currentProc->typeMap.count(prop._value)==0)
246       {
247         //Check if the typecode is defined in the runtime
248         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(prop._value);
249         if(t==0)
250         {
251           std::string msg="Unknown type " + prop._value + " for member " + prop._name + " in struct " + _name;
252           throw Exception(msg);
253         }
254         else
255         {
256           currentProc->typeMap[prop._value]=t;
257           t->incrRef();
258         }
259       }
260
261       _members.push_back(prop);
262     }
263   ENGINE::TypeCode * structtypeParser::post()
264     {
265       DEBTRACE( "structtype_post" );
266       ENGINE::TypeCodeStruct *t;
267       if(currentProc->typeMap.count(_name)!=0)
268         {
269           //reuse a forward declaration
270           ENGINE::TypeCode* tt=currentProc->typeMap[_name];
271           if(tt->kind()==YACS::ENGINE::Struct)
272             {
273               t=(ENGINE::TypeCodeStruct*)tt;
274             }
275           else
276             {
277               std::string msg="Forward declaration must be a struct type but " + std::string(tt->name()) + " is not one" ;
278               throw Exception(msg);
279             }
280         }
281       else
282         {
283           t = (ENGINE::TypeCodeStruct*)currentProc->createStructTc(_id,_name);
284         }
285       std::vector<myprop>::const_iterator iter;
286       for(iter=_members.begin();iter!=_members.end();iter++)
287         {
288           DEBTRACE("member: " << iter->_name << " " <<iter->_value);
289           t->addMember(iter->_name,currentProc->typeMap[iter->_value]);
290         }
291       return t;
292     }
293 }
294