Salome HOME
This commit was generated by cvs2git to track changes on a CVS vendor
[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
63        - extensions : qui donne une liste d'extensions de fichier préconisées
64
65    """
66    # Les extensions de fichier préconisées
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 stocké 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 représentation du JDC obj sous une
87           forme qui est paramétrée par format.
88           Si format vaut 'brut',      retourne une liste de listes de ...
89           Si format vaut 'standard',  retourne un texte obtenu par concaténation de la liste
90           Si format vaut 'beautifie', retourne le meme texte beautifié
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 "Format pas implémenté : "+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 méthodes accept et visitxxx à la
108          place (dépend des gouts !!!)
109       """
110       # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
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 placé avant PARAMETRE (raison : héritage)
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 "Type d'objet non prévu",obj
146
147    def generJDC(self,obj):
148       """
149          Cette méthode convertit un objet JDC en une liste de chaines de 
150          caractères à 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 étape, on ajoute le retour chariot sur la dernière étape
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 méthode convertit un COMMANDE_COMM
172          en une liste de chaines de caractères à 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 méthode convertit un EVAL
183          en une liste de chaines de caractères à la syntaxe asterv5
184       """
185       return 'EVAL("'+ obj.valeur +'")'
186
187    def generCOMMENTAIRE(self,obj):
188       """
189          Cette méthode convertit un COMMENTAIRE
190          en une liste de chaines de caractères à 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 méthode convertit un PARAMETRE_EVAL
201          en une liste de chaines de caractères à 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 méthode convertit un PARAMETRE
211          en une liste de chaines de caractères à 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 méthode convertit une étape niveau
221          en une liste de chaines de caractères à 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 méthode convertit une étape
235          en une liste de chaines de caractères à 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             Méthode particulière 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 méthode convertit une macro-étape
279          en une liste de chaines de caractères à 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            Méthode 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 méthode convertit une étape
332          en une liste de chaines de caractères à 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 caractères à 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 paramètre
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           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         else :
388           s = `obj.valeur`
389         s=obj.nom+':'+s+' '
390         return s
391
392    def wait_geom(self,obj):
393       for typ in obj.definition.type:
394         if type(typ) == types.ClassType :
395           if issubclass(typ,GEOM) : return 1
396       return 0
397
398    def repr_float(self,valeur):
399       """ 
400           Cette fonction représente le réel valeur comme une chaîne de caractères
401           sous forme mantisse exposant si nécessaire cad si le nombre contient plus de 5 caractères
402           NB : valeur est un réel au format Python ou une chaîne de caractères représentant un réel
403       """
404       if type(valeur) == types.StringType : valeur = eval(valeur)
405       if valeur == 0. : return '0.0'
406       if abs(valeur) > 1. :
407         if abs(valeur) < 10000. : return repr(valeur)
408       else :
409         if abs(valeur) > 0.01 : return repr(valeur)
410       t=repr(valeur)
411       if string.find(t,'e') != -1 or string.find(t,'E') != -1 :
412         # le réel est déjà sous forme mantisse exposant !
413         # --> on remplace e par E
414         t=string.replace(t,'e','E')
415         # --> on doit encore vérifier que la mantisse contient bien un '.'
416         if string.find(t,'.')!= -1:
417           return t
418         else:
419           # -->il faut rajouter le point avant le E
420           t=string.replace(t,'E','.E')
421           return t
422       s=''
423       neg = 0
424       if t[0]=='-':
425         s=s+t[0]
426         t=t[1:]
427       cpt = 0
428       if string.atof(t[0]) == 0.:
429         # réel plus petit que 1
430         neg = 1
431         t=t[2:]
432         cpt=1
433         while string.atof(t[0]) == 0. :
434           cpt = cpt+1
435           t=t[1:]
436         s=s+t[0]+'.'
437         for c in t[1:]:
438           s=s+c
439       else:
440         # réel plus grand que 1
441         s=s+t[0]+'.'
442         if string.atof(t[1:]) == 0.:
443           l=string.split(t[1:],'.')
444           cpt = len(l[0])
445         else:
446           r=0
447           pt=0
448           for c in t[1:]:
449             r=r+1
450             if c != '.' :
451               if pt != 1 : cpt = cpt + 1
452               s=s+c
453             else:
454               pt = 1
455               if r+1 == len(t) or string.atof(t[r+1:]) == 0.:break
456       s=s+'E'+neg*'-'+repr(cpt)
457       return s
458
459    def generASSD(self,obj):
460       """
461           Convertit un objet dérivé d'ASSD en une chaine de caractères à la
462           syntaxe asterv5
463       """
464       return obj.get_name()
465
466    def generMCFACT(self,obj):
467       """
468           Convertit un objet MCFACT en une liste de chaines de caractères à la
469           syntaxe asterv5
470       """
471       l=[]
472       label=obj.nom + ':('
473       l.append(label)
474       for v in obj.mc_liste:
475         if isinstance(v,MCBLOC) or isinstance(v,MCList):
476           liste=self.generator(v)
477           for mocle in liste :
478             l.append(mocle)
479         else:
480           l.append(self.generator(v))
481       l.append(')')
482       return l
483
484    def generMCList(self,obj):
485       """
486           Convertit un objet MCList en une liste de chaines de caractères à la
487           syntaxe asterv5
488       """
489       l=[]
490       for mcfact in obj.data:
491          l.append(self.generator(mcfact))
492       return l
493
494    def generMCBLOC(self,obj):
495       """
496           Convertit un objet MCBLOC en une liste de chaines de caractères à la
497           syntaxe asterv5
498       """
499       l=[]
500       for v in obj.mc_liste:
501         if isinstance(v,MCBLOC) or isinstance(v,MCList):
502           liste=self.generator(v)
503           for mocle in liste :
504             l.append(mocle)
505         else:
506           l.append(self.generator(v))
507       return l
508