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