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