Salome HOME
995e3c59bc918385654f51221b2f40095c249721
[tools/eficas.git] / generator / generator_asterv5.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
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
28 from Noyau import N_CR
29 from Accas import ETAPE,PROC_ETAPE,MACRO_ETAPE,ETAPE_NIVEAU,JDC,FORM_ETAPE
30 from Accas import MCSIMP,MCFACT,MCBLOC,MCList,EVAL
31 from Accas import GEOM,ASSD
32 from Accas import COMMENTAIRE,PARAMETRE, PARAMETRE_EVAL,COMMANDE_COMM
33 from Formatage import Formatage
34
35 def entryPoint():
36    """
37        Retourne les informations nécessaires pour le chargeur de plugins
38
39        Ces informations sont retournées dans un dictionnaire
40    """
41    return {
42         # Le nom du plugin
43           'name' : 'asterv5',
44         # La factory pour créer une instance du plugin
45           'factory' : AsterGenerator,
46           }
47
48
49 class AsterGenerator:
50    """
51        Ce generateur parcourt un objet de type JDC et produit
52        un fichier au format asterv5
53
54        L'acquisition et le parcours sont réalisés par la méthode
55        generator.gener(objet_jdc,format)
56
57        L'écriture du fichier au format asterv5 est réalisée par appel de la méthode
58        generator.writefile(nom_fichier)
59
60        Ses caractéristiques principales sont exposées dans des attributs 
61        de classe :
62          - extensions : qui donne une liste d'extensions de fichier préconisées
63
64    """
65    # Les extensions de fichier préconisées
66    extensions=('.comm',)
67
68    def __init__(self,cr=None):
69       # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
70       if cr :
71          self.cr=cr
72       else:
73          self.cr=N_CR.CR(debut='CR generateur format asterv5',
74                          fin='fin CR format asterv5')
75       # Le texte au format asterv5 est stocké dans l'attribut text
76       self.text=''
77
78    def writefile(self,filename):
79       fp=open(filename,'w')
80       fp.write(self.text)
81       fp.close()
82
83    def gener(self,obj,format='brut'):
84       """
85           Retourne une représentation du JDC obj sous une
86           forme qui est paramétrée par format.
87           Si format vaut 'brut',      retourne une liste de listes de ...
88           Si format vaut 'standard',  retourne un texte obtenu par concaténation de la liste
89           Si format vaut 'beautifie', retourne le meme texte beautifié
90       """
91       liste= self.generator(obj)
92       if format == 'brut':
93          self.text=liste
94       elif format == 'standard':
95          self.text=string.join(liste)
96       elif format == 'beautifie':
97          jdc_formate = Formatage(liste,sep=':',l_max=72)
98          self.text=jdc_formate.formate_jdc()
99       else:
100          raise "Format pas implémenté : "+format
101       return self.text
102
103    def generator(self,obj):
104       """
105          Cette methode joue un role d'aiguillage en fonction du type de obj
106          On pourrait utiliser les méthodes accept et visitxxx à la
107          place (dépend des gouts !!!)
108       """
109       # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
110       if isinstance(obj,PROC_ETAPE):
111          return self.generPROC_ETAPE(obj)
112       elif isinstance(obj,MACRO_ETAPE):
113          return self.generMACRO_ETAPE(obj)
114       elif isinstance(obj,FORM_ETAPE):
115          return self.generFORM_ETAPE(obj)
116       elif isinstance(obj,ETAPE):
117          return self.generETAPE(obj)
118       elif isinstance(obj,MCFACT):
119          return self.generMCFACT(obj)
120       elif isinstance(obj,MCList):
121          return self.generMCList(obj)
122       elif isinstance(obj,MCBLOC):
123          return self.generMCBLOC(obj)
124       elif isinstance(obj,MCSIMP):
125          return self.generMCSIMP(obj)
126       elif isinstance(obj,ASSD):
127          return self.generASSD(obj)
128       elif isinstance(obj,ETAPE_NIVEAU):
129          return self.generETAPE_NIVEAU(obj)
130       elif isinstance(obj,COMMENTAIRE):
131          return self.generCOMMENTAIRE(obj)
132       # Attention doit etre placé avant PARAMETRE (raison : héritage)
133       elif isinstance(obj,PARAMETRE_EVAL):
134          return self.generPARAMETRE_EVAL(obj)
135       elif isinstance(obj,PARAMETRE):
136          return self.generPARAMETRE(obj)
137       elif isinstance(obj,EVAL):
138          return self.generEVAL(obj)
139       elif isinstance(obj,COMMANDE_COMM):
140          return self.generCOMMANDE_COMM(obj)
141       elif isinstance(obj,JDC):
142          return self.generJDC(obj)
143       else:
144          raise "Type d'objet non prévu",obj
145
146    def generJDC(self,obj):
147       """
148          Cette méthode convertit un objet JDC en une liste de chaines de 
149          caractères à la syntaxe asterv5
150       """
151       l=[]
152       if obj.definition.l_niveaux == ():
153          # Il n'y a pas de niveaux
154          for etape in obj.etapes:
155             l.append(self.generator(etape))
156       else:
157          # Il y a des niveaux
158          for etape_niveau in obj.etapes_niveaux:
159             l.extend(self.generator(etape_niveau))
160       if l != [] : 
161          # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
162          if type(l[-1])==types.ListType:
163             l[-1][-1] = l[-1][-1]+'\n'
164          elif type(l[-1])==types.StringType:
165             l[-1] = l[-1]+'\n' 
166       return l
167
168    def generCOMMANDE_COMM(self,obj):
169       """
170          Cette méthode convertit un COMMANDE_COMM
171          en une liste de chaines de caractères à la syntaxe asterv5
172       """
173       l_lignes = string.split(obj.valeur,'\n')
174       txt=''
175       for ligne in l_lignes:
176           txt = txt + '%%'+ligne+'\n'
177       return txt
178
179    def generEVAL(self,obj):
180       """
181          Cette méthode convertit un EVAL
182          en une liste de chaines de caractères à la syntaxe asterv5
183       """
184       return 'EVAL("'+ obj.valeur +'")'
185
186    def generCOMMENTAIRE(self,obj):
187       """
188          Cette méthode convertit un COMMENTAIRE
189          en une liste de chaines de caractères à la syntaxe asterv5
190       """
191       l_lignes = string.split(obj.valeur,'\n')
192       txt=''
193       for ligne in l_lignes:
194         txt = txt + '%'+ligne+'\n'
195       return txt
196
197    def generPARAMETRE_EVAL(self,obj):
198       """
199          Cette méthode convertit un PARAMETRE_EVAL
200          en une liste de chaines de caractères à la syntaxe asterv5
201       """
202       if obj.valeur == None:
203          return obj.nom + ' = None ;\n'
204       else:
205          return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
206
207    def generPARAMETRE(self,obj):
208       """
209          Cette méthode convertit un PARAMETRE
210          en une liste de chaines de caractères à la syntaxe asterv5
211       """
212       if type(obj.valeur) == types.StringType:
213         return obj.nom + " = '" + obj.valeur + "';\n"
214       else:
215         return obj.nom + ' = ' + str(obj.valeur) + ';\n'
216
217    def generETAPE_NIVEAU(self,obj):
218       """
219          Cette méthode convertit une étape niveau
220          en une liste de chaines de caractères à la syntaxe asterv5
221       """
222       l=[]
223       if obj.etapes_niveaux == []:
224         for etape in obj.etapes:
225           l.append(self.generator(etape))
226       else:
227         for etape_niveau in obj.etapes_niveaux:
228           l.extend(self.generator(etape_niveau))
229       return l
230
231    def generETAPE(self,obj):
232       """
233          Cette méthode convertit une étape
234          en une liste de chaines de caractères à la syntaxe asterv5
235       """
236       try:
237         if obj.reuse != None:
238           sdname= "&" + self.generator(obj.reuse)
239         else:
240           sdname= self.generator(obj.sd)
241       except:
242         sdname='sansnom'
243       l=[]
244       label=sdname + '='+obj.definition.nom+'('
245       l.append(label)
246       for v in obj.mc_liste:
247         if isinstance(v,MCBLOC) or isinstance(v,MCList):
248           liste=self.generator(v)
249           for mocle in liste :
250             l.append(mocle)
251         else:
252           l.append(self.generator(v))
253       if len(l) == 1:
254         l[0]=label+');'
255       else :
256         l.append(');')
257       return l
258
259    def generFORM_ETAPE(self,obj):
260         """
261             Méthode particulière pour les objets de type FORMULE
262         """
263         l=[]
264         nom = obj.get_nom()
265         if nom == '' : nom = 'sansnom'
266         if len(obj.mc_liste)>0:
267             l.append(nom + ' = FORMULE(')
268             s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''"
269             l.append(s)
270             l.append(');')
271         else:
272             l.append(nom+' = FORMULE();')
273         return l
274
275    def generMACRO_ETAPE(self,obj):
276       """
277          Cette méthode convertit une macro-étape
278          en une liste de chaines de caractères à la syntaxe asterv5
279       """
280       if obj.definition.nom == 'FORMULE' : return self.gen_ast_formule(obj)
281       try:
282         if obj.reuse != None:
283           sdname= "&" + self.generator(obj.reuse)+'='
284         elif obj.sd == None:
285           sdname=''
286         else:
287           sdname= self.generator(obj.sd)+'='
288       except:
289         sdname='sansnom='
290       l=[]
291       label = sdname + obj.definition.nom+'('
292       l.append(label)
293       for v in obj.mc_liste:
294         if isinstance(v,MCBLOC) or isinstance(v,MCList):
295           liste=self.generator(v)
296           for mocle in liste :
297             l.append(mocle)
298         else:
299           # MCFACT ou MCSIMP
300           l.append(self.generator(v))
301       if len(l) == 1:
302         l[0]=label+');'
303       else :
304         l.append(');')
305       return l
306
307    def gen_ast_formule(self,obj):
308       """ 
309            Méthode gen_ast particuliere aux objets de type FORMULE 
310       """
311       label='!FORMULE('
312       try:
313         sdname= self.generator(obj.sd)
314       except:
315         sdname='sansnom'
316       l=[]
317       l.append(label)
318       for v in obj.mc_liste:
319         s=''
320         s= v.nom+':'+sdname+'('+v.valeur+')'
321         l.append(s)
322       if len(l) == 1:
323         l[0]=label+');'
324       else :
325         l.append(');')
326       return l
327
328    def generPROC_ETAPE(self,obj):
329       """
330          Cette méthode convertit une étape
331          en une liste de chaines de caractères à la syntaxe asterv5
332       """
333       l=[]
334       label=obj.definition.nom+'('
335       l.append(label)
336       for v in obj.mc_liste:
337         if isinstance(v,MCBLOC) or isinstance(v,MCList):
338           liste=self.generator(v)
339           for mocle in liste :
340             l.append(mocle)
341         else:
342           l.append(self.generator(v))
343       if len(l) == 1:
344         l[0]=label+');'
345       else :
346         l.append(');')
347       return l
348
349    def generMCSIMP(self,obj) :
350       """
351           Convertit un objet MCSIMP en une liste de chaines de caractères à la
352           syntaxe asterv5
353       """
354       if type(obj.valeur) == types.TupleType :
355         s = '('
356         for val in obj.valeur :
357           if s != '(': s = s + ','
358           if type(val) == types.InstanceType :
359             if isinstance(val,PARAMETRE):
360               # il ne faut pas prendre la string que retourne gen_ast
361               # mais seulement le nom dans le cas d'un paramètre
362               s = s + val.nom
363             else:
364               s = s + self.generator(val)
365           elif self.wait_geom(obj):
366             s = s + val
367           elif type(val) == types.FloatType :
368             #s = s + self.repr_float(val)
369             s = s + str(val)
370           else :
371             s = s + `val`
372         s = s + ')'
373         s=obj.nom+':'+s+' '
374         return s
375       else :
376         if type(obj.valeur) == types.InstanceType :
377           if isinstance(obj.valeur,PARAMETRE):
378             # il ne faut pas prendre la string que retourne gen_ast
379             # mais seulement str dans le cas d'un paramètre
380             s = obj.valeur.nom
381           else:
382             s =  self.generator(obj.valeur)
383         elif self.wait_geom(obj):
384             s = obj.valeur
385         elif type(obj.valeur) == types.FloatType :
386             #s = self.repr_float(obj.valeur)
387             s = str(obj.valeur)
388         else :
389           s = `obj.valeur`
390         s=obj.nom+':'+s+' '
391         return s
392
393    def wait_geom(self,obj):
394       for typ in obj.definition.type:
395         if type(typ) == types.ClassType :
396           if issubclass(typ,GEOM) : return 1
397       return 0
398
399    def repr_float(self,valeur):
400       """ 
401           Cette fonction représente le réel valeur comme une chaîne de caractères
402           sous forme mantisse exposant si nécessaire cad si le nombre contient plus de 5 caractères
403           NB : valeur est un réel au format Python ou une chaîne de caractères représentant un réel
404       """
405       if type(valeur) == types.StringType : valeur = eval(valeur)
406       if valeur == 0. : return '0.0'
407       if abs(valeur) > 1. :
408         if abs(valeur) < 10000. : return repr(valeur)
409       else :
410         if abs(valeur) > 0.01 : return repr(valeur)
411       t=repr(valeur)
412       if string.find(t,'e') != -1 or string.find(t,'E') != -1 :
413         # le réel est déjà sous forme mantisse exposant !
414         # --> on remplace e par E
415         t=string.replace(t,'e','E')
416         # --> on doit encore vérifier que la mantisse contient bien un '.'
417         if string.find(t,'.')!= -1:
418           return t
419         else:
420           # -->il faut rajouter le point avant le E
421           t=string.replace(t,'E','.E')
422           return t
423       s=''
424       neg = 0
425       if t[0]=='-':
426         s=s+t[0]
427         t=t[1:]
428       cpt = 0
429       if string.atof(t[0]) == 0.:
430         # réel plus petit que 1
431         neg = 1
432         t=t[2:]
433         cpt=1
434         while string.atof(t[0]) == 0. :
435           cpt = cpt+1
436           t=t[1:]
437         s=s+t[0]+'.'
438         for c in t[1:]:
439           s=s+c
440       else:
441         # réel plus grand que 1
442         s=s+t[0]+'.'
443         if string.atof(t[1:]) == 0.:
444           l=string.split(t[1:],'.')
445           cpt = len(l[0])
446         else:
447           r=0
448           pt=0
449           for c in t[1:]:
450             r=r+1
451             if c != '.' :
452               if pt != 1 : cpt = cpt + 1
453               s=s+c
454             else:
455               pt = 1
456               if r+1 == len(t) or string.atof(t[r+1:]) == 0.:break
457       s=s+'E'+neg*'-'+repr(cpt)
458       return s
459
460    def generASSD(self,obj):
461       """
462           Convertit un objet dérivé d'ASSD en une chaine de caractères à la
463           syntaxe asterv5
464       """
465       return obj.get_name()
466
467    def generMCFACT(self,obj):
468       """
469           Convertit un objet MCFACT en une liste de chaines de caractères à la
470           syntaxe asterv5
471       """
472       l=[]
473       label=obj.nom + ':('
474       l.append(label)
475       for v in obj.mc_liste:
476         if isinstance(v,MCBLOC) or isinstance(v,MCList):
477           liste=self.generator(v)
478           for mocle in liste :
479             l.append(mocle)
480         else:
481           l.append(self.generator(v))
482       l.append(')')
483       return l
484
485    def generMCList(self,obj):
486       """
487           Convertit un objet MCList en une liste de chaines de caractères à la
488           syntaxe asterv5
489       """
490       l=[]
491       for mcfact in obj.data:
492          l.append(self.generator(mcfact))
493       return l
494
495    def generMCBLOC(self,obj):
496       """
497           Convertit un objet MCBLOC en une liste de chaines de caractères à la
498           syntaxe asterv5
499       """
500       l=[]
501       for v in obj.mc_liste:
502         if isinstance(v,MCBLOC) or isinstance(v,MCList):
503           liste=self.generator(v)
504           for mocle in liste :
505             l.append(mocle)
506         else:
507           l.append(self.generator(v))
508       return l
509