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