Salome HOME
dernieres modifs
[tools/eficas.git] / generator / generator_asterv5.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 """
21     Ce module contient le plugin generateur de fichier au format asterv5 pour EFICAS.
22
23
24 """
25 import traceback
26 import types,string
27 from Extensions.i18n import tr
28 from Extensions.eficas_exception import EficasException
29 from Noyau import N_CR
30 from Accas import ETAPE,PROC_ETAPE,MACRO_ETAPE,ETAPE_NIVEAU,JDC,FORM_ETAPE
31 from Accas import MCSIMP,MCFACT,MCBLOC,MCList,EVAL
32 from Accas import GEOM,ASSD
33 from Accas import COMMENTAIRE,PARAMETRE, PARAMETRE_EVAL,COMMANDE_COMM
34 from Formatage import Formatage
35
36 def entryPoint():
37    """
38        Retourne les informations necessaires pour le chargeur de plugins
39
40        Ces informations sont retournees dans un dictionnaire
41    """
42    return {
43         # Le nom du plugin
44           'name' : 'asterv5',
45         # La factory pour creer une instance du plugin
46           'factory' : AsterGenerator,
47           }
48
49
50 class AsterGenerator:
51    """
52        Ce generateur parcourt un objet de type JDC et produit
53        un fichier au format asterv5
54
55        L'acquisition et le parcours sont realises par la methode
56        generator.gener(objet_jdc,format)
57
58        L'ecriture du fichier au format asterv5 est realisee par appel de la methode
59        generator.writefile(nom_fichier)
60
61        Ses caracteristiques principales sont exposees dans des attributs 
62        de classe :
63          - extensions : qui donne une liste d'extensions de fichier preconisees
64
65    """
66    # Les extensions de fichier preconisees
67    extensions=('.comm',)
68
69    def __init__(self,cr=None):
70       # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
71       if cr :
72          self.cr=cr
73       else:
74          self.cr=N_CR.CR(debut='CR generateur format asterv5',
75                          fin='fin CR format asterv5')
76       # Le texte au format asterv5 est stocke dans l'attribut text
77       self.text=''
78
79    def writefile(self,filename):
80       fp=open(filename,'w')
81       fp.write(self.text)
82       fp.close()
83
84    def gener(self,obj,format='brut'):
85       """
86           Retourne une representation du JDC obj sous une
87           forme qui est parametree par format.
88           Si format vaut 'brut',      retourne une liste de listes de ...
89           Si format vaut 'standard',  retourne un texte obtenu par concatenation de la liste
90           Si format vaut 'beautifie', retourne le meme texte beautifie
91       """
92       liste= self.generator(obj)
93       if format == 'brut':
94          self.text=liste
95       elif format == 'standard':
96          self.text=string.join(liste)
97       elif format == 'beautifie':
98          jdc_formate = Formatage(liste,sep=':',l_max=72)
99          self.text=jdc_formate.formate_jdc()
100       else:
101          raise EficasException(tr("Format pas implemente : %s", format))
102       return self.text
103
104    def generator(self,obj):
105       """
106          Cette methode joue un role d'aiguillage en fonction du type de obj
107          On pourrait utiliser les methodes accept et visitxxx à la
108          place (depend des gouts !!!)
109       """
110       # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage)
111       if isinstance(obj,PROC_ETAPE):
112          return self.generPROC_ETAPE(obj)
113       elif isinstance(obj,MACRO_ETAPE):
114          return self.generMACRO_ETAPE(obj)
115       elif isinstance(obj,FORM_ETAPE):
116          return self.generFORM_ETAPE(obj)
117       elif isinstance(obj,ETAPE):
118          return self.generETAPE(obj)
119       elif isinstance(obj,MCFACT):
120          return self.generMCFACT(obj)
121       elif isinstance(obj,MCList):
122          return self.generMCList(obj)
123       elif isinstance(obj,MCBLOC):
124          return self.generMCBLOC(obj)
125       elif isinstance(obj,MCSIMP):
126          return self.generMCSIMP(obj)
127       elif isinstance(obj,ASSD):
128          return self.generASSD(obj)
129       elif isinstance(obj,ETAPE_NIVEAU):
130          return self.generETAPE_NIVEAU(obj)
131       elif isinstance(obj,COMMENTAIRE):
132          return self.generCOMMENTAIRE(obj)
133       # Attention doit etre place avant PARAMETRE (raison : heritage)
134       elif isinstance(obj,PARAMETRE_EVAL):
135          return self.generPARAMETRE_EVAL(obj)
136       elif isinstance(obj,PARAMETRE):
137          return self.generPARAMETRE(obj)
138       elif isinstance(obj,EVAL):
139          return self.generEVAL(obj)
140       elif isinstance(obj,COMMANDE_COMM):
141          return self.generCOMMANDE_COMM(obj)
142       elif isinstance(obj,JDC):
143          return self.generJDC(obj)
144       else:
145          raise EficasException(tr("Type d'objet non prevu : %s", repr(obj)))
146
147    def generJDC(self,obj):
148       """
149          Cette methode convertit un objet JDC en une liste de chaines de 
150          caracteres à la syntaxe asterv5
151       """
152       l=[]
153       if obj.definition.l_niveaux == ():
154          # Il n'y a pas de niveaux
155          for etape in obj.etapes:
156             l.append(self.generator(etape))
157       else:
158          # Il y a des niveaux
159          for etape_niveau in obj.etapes_niveaux:
160             l.extend(self.generator(etape_niveau))
161       if l != [] : 
162          # Si au moins une etape, on ajoute le retour chariot sur la derniere etape
163          if type(l[-1])==types.ListType:
164             l[-1][-1] = l[-1][-1]+'\n'
165          elif type(l[-1])==types.StringType:
166             l[-1] = l[-1]+'\n' 
167       return l
168
169    def generCOMMANDE_COMM(self,obj):
170       """
171          Cette methode convertit un COMMANDE_COMM
172          en une liste de chaines de caracteres à la syntaxe asterv5
173       """
174       l_lignes = string.split(obj.valeur,'\n')
175       txt=''
176       for ligne in l_lignes:
177           txt = txt + '%%'+ligne+'\n'
178       return txt
179
180    def generEVAL(self,obj):
181       """
182          Cette methode convertit un EVAL
183          en une liste de chaines de caracteres à la syntaxe asterv5
184       """
185       return 'EVAL(u"'+ obj.valeur +'")'
186
187    def generCOMMENTAIRE(self,obj):
188       """
189          Cette methode convertit un COMMENTAIRE
190          en une liste de chaines de caracteres à la syntaxe asterv5
191       """
192       l_lignes = string.split(obj.valeur,'\n')
193       txt=''
194       for ligne in l_lignes:
195         txt = txt + '%'+ligne+'\n'
196       return txt
197
198    def generPARAMETRE_EVAL(self,obj):
199       """
200          Cette methode convertit un PARAMETRE_EVAL
201          en une liste de chaines de caracteres à la syntaxe asterv5
202       """
203       if obj.valeur == None:
204          return obj.nom + ' = None ;\n'
205       else:
206          return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
207
208    def generPARAMETRE(self,obj):
209       """
210          Cette methode convertit un PARAMETRE
211          en une liste de chaines de caracteres à la syntaxe asterv5
212       """
213       if type(obj.valeur) == types.StringType:
214         return obj.nom + " = '" + obj.valeur + "';\n"
215       else:
216         return obj.nom + ' = ' + str(obj.valeur) + ';\n'
217
218    def generETAPE_NIVEAU(self,obj):
219       """
220          Cette methode convertit une etape niveau
221          en une liste de chaines de caracteres à la syntaxe asterv5
222       """
223       l=[]
224       if obj.etapes_niveaux == []:
225         for etape in obj.etapes:
226           l.append(self.generator(etape))
227       else:
228         for etape_niveau in obj.etapes_niveaux:
229           l.extend(self.generator(etape_niveau))
230       return l
231
232    def generETAPE(self,obj):
233       """
234          Cette methode convertit une etape
235          en une liste de chaines de caracteres à la syntaxe asterv5
236       """
237       try:
238         if obj.reuse != None:
239           sdname= "&" + self.generator(obj.reuse)
240         else:
241           sdname= self.generator(obj.sd)
242       except:
243         sdname='sansnom'
244       l=[]
245       label=sdname + '='+obj.definition.nom+'('
246       l.append(label)
247       for v in obj.mc_liste:
248         if isinstance(v,MCBLOC) or isinstance(v,MCList):
249           liste=self.generator(v)
250           for mocle in liste :
251             l.append(mocle)
252         else:
253           l.append(self.generator(v))
254       if len(l) == 1:
255         l[0]=label+');'
256       else :
257         l.append(');')
258       return l
259
260    def generFORM_ETAPE(self,obj):
261         """
262             Methode particuliere pour les objets de type FORMULE
263         """
264         l=[]
265         nom = obj.get_nom()
266         if nom == '' : nom = 'sansnom'
267         if len(obj.mc_liste)>0:
268             l.append(nom + ' = FORMULE(')
269             s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''"
270             l.append(s)
271             l.append(');')
272         else:
273             l.append(nom+' = FORMULE();')
274         return l
275
276    def generMACRO_ETAPE(self,obj):
277       """
278          Cette methode convertit une macro-etape
279          en une liste de chaines de caracteres à la syntaxe asterv5
280       """
281       if obj.definition.nom == 'FORMULE' : return self.gen_ast_formule(obj)
282       try:
283         if obj.reuse != None:
284           sdname= "&" + self.generator(obj.reuse)+'='
285         elif obj.sd == None:
286           sdname=''
287         else:
288           sdname= self.generator(obj.sd)+'='
289       except:
290         sdname='sansnom='
291       l=[]
292       label = sdname + obj.definition.nom+'('
293       l.append(label)
294       for v in obj.mc_liste:
295         if isinstance(v,MCBLOC) or isinstance(v,MCList):
296           liste=self.generator(v)
297           for mocle in liste :
298             l.append(mocle)
299         else:
300           # MCFACT ou MCSIMP
301           l.append(self.generator(v))
302       if len(l) == 1:
303         l[0]=label+');'
304       else :
305         l.append(');')
306       return l
307
308    def gen_ast_formule(self,obj):
309       """ 
310            Methode gen_ast particuliere aux objets de type FORMULE 
311       """
312       label='!FORMULE('
313       try:
314         sdname= self.generator(obj.sd)
315       except:
316         sdname='sansnom'
317       l=[]
318       l.append(label)
319       for v in obj.mc_liste:
320         s=''
321         s= v.nom+':'+sdname+'('+v.valeur+')'
322         l.append(s)
323       if len(l) == 1:
324         l[0]=label+');'
325       else :
326         l.append(');')
327       return l
328
329    def generPROC_ETAPE(self,obj):
330       """
331          Cette methode convertit une etape
332          en une liste de chaines de caracteres à la syntaxe asterv5
333       """
334       l=[]
335       label=obj.definition.nom+'('
336       l.append(label)
337       for v in obj.mc_liste:
338         if isinstance(v,MCBLOC) or isinstance(v,MCList):
339           liste=self.generator(v)
340           for mocle in liste :
341             l.append(mocle)
342         else:
343           l.append(self.generator(v))
344       if len(l) == 1:
345         l[0]=label+');'
346       else :
347         l.append(');')
348       return l
349
350    def generMCSIMP(self,obj) :
351       """
352           Convertit un objet MCSIMP en une liste de chaines de caracteres à la
353           syntaxe asterv5
354       """
355       if type(obj.valeur) == types.TupleType :
356         s = '('
357         for val in obj.valeur :
358           if s != '(': s = s + ','
359           if type(val) == types.InstanceType :
360             if isinstance(val,PARAMETRE):
361               # il ne faut pas prendre la string que retourne gen_ast
362               # mais seulement le nom dans le cas d'un parametre
363               s = s + val.nom
364             else:
365               s = s + self.generator(val)
366           elif self.wait_geom(obj):
367             s = s + val
368           elif type(val) == types.FloatType :
369             #s = s + self.repr_float(val)
370             s = s + str(val)
371           else :
372             s = s + `val`
373         s = s + ')'
374         s=obj.nom+':'+s+' '
375         return s
376       else :
377         if type(obj.valeur) == types.InstanceType :
378           if isinstance(obj.valeur,PARAMETRE):
379             # il ne faut pas prendre la string que retourne gen_ast
380             # mais seulement str dans le cas d'un parametre
381             s = obj.valeur.nom
382           else:
383             s =  self.generator(obj.valeur)
384         elif self.wait_geom(obj):
385             s = obj.valeur
386         elif type(obj.valeur) == types.FloatType :
387             #s = self.repr_float(obj.valeur)
388             s = str(obj.valeur)
389         else :
390           s = `obj.valeur`
391         s=obj.nom+':'+s+' '
392         return s
393
394    def wait_geom(self,obj):
395       for typ in obj.definition.type:
396         if type(typ) == types.ClassType :
397           if issubclass(typ,GEOM) : return 1
398       return 0
399
400    def repr_float(self,valeur):
401       """ 
402           Cette fonction represente le reel valeur comme une chaîne de caracteres
403           sous forme mantisse exposant si necessaire cad si le nombre contient plus de 5 caracteres
404           NB : valeur est un reel au format Python ou une chaîne de caracteres representant un reel
405       """
406       if type(valeur) == types.StringType : valeur = eval(valeur)
407       if valeur == 0. : return '0.0'
408       if abs(valeur) > 1. :
409         if abs(valeur) < 10000. : return repr(valeur)
410       else :
411         if abs(valeur) > 0.01 : return repr(valeur)
412       t=repr(valeur)
413       if string.find(t,'e') != -1 or string.find(t,'E') != -1 :
414         # le reel est dejà sous forme mantisse exposant !
415         # --> on remplace e par E
416         t=string.replace(t,'e','E')
417         # --> on doit encore verifier que la mantisse contient bien un '.'
418         if string.find(t,'.')!= -1:
419           return t
420         else:
421           # -->il faut rajouter le point avant le E
422           t=string.replace(t,'E','.E')
423           return t
424       s=''
425       neg = 0
426       if t[0]=='-':
427         s=s+t[0]
428         t=t[1:]
429       cpt = 0
430       if string.atof(t[0]) == 0.:
431         # reel plus petit que 1
432         neg = 1
433         t=t[2:]
434         cpt=1
435         while string.atof(t[0]) == 0. :
436           cpt = cpt+1
437           t=t[1:]
438         s=s+t[0]+'.'
439         for c in t[1:]:
440           s=s+c
441       else:
442         # reel plus grand que 1
443         s=s+t[0]+'.'
444         if string.atof(t[1:]) == 0.:
445           l=string.split(t[1:],'.')
446           cpt = len(l[0])
447         else:
448           r=0
449           pt=0
450           for c in t[1:]:
451             r=r+1
452             if c != '.' :
453               if pt != 1 : cpt = cpt + 1
454               s=s+c
455             else:
456               pt = 1
457               if r+1 == len(t) or string.atof(t[r+1:]) == 0.:break
458       s=s+'E'+neg*'-'+repr(cpt)
459       return s
460
461    def generASSD(self,obj):
462       """
463           Convertit un objet derive d'ASSD en une chaine de caracteres à la
464           syntaxe asterv5
465       """
466       return obj.get_name()
467
468    def generMCFACT(self,obj):
469       """
470           Convertit un objet MCFACT en une liste de chaines de caracteres à la
471           syntaxe asterv5
472       """
473       l=[]
474       label=obj.nom + ':('
475       l.append(label)
476       for v in obj.mc_liste:
477         if isinstance(v,MCBLOC) or isinstance(v,MCList):
478           liste=self.generator(v)
479           for mocle in liste :
480             l.append(mocle)
481         else:
482           l.append(self.generator(v))
483       l.append(')')
484       return l
485
486    def generMCList(self,obj):
487       """
488           Convertit un objet MCList en une liste de chaines de caracteres à la
489           syntaxe asterv5
490       """
491       l=[]
492       for mcfact in obj.data:
493          l.append(self.generator(mcfact))
494       return l
495
496    def generMCBLOC(self,obj):
497       """
498           Convertit un objet MCBLOC en une liste de chaines de caracteres à la
499           syntaxe asterv5
500       """
501       l=[]
502       for v in obj.mc_liste:
503         if isinstance(v,MCBLOC) or isinstance(v,MCList):
504           liste=self.generator(v)
505           for mocle in liste :
506             l.append(mocle)
507         else:
508           l.append(self.generator(v))
509       return l
510