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