]> SALOME platform Git repositories - tools/eficas.git/blob - generator/generator_python.py
Salome HOME
CCAR: merge de la version de developpement V1_12a2 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       i=1
224       for ligne in l_lignes:
225         txt = txt + '#'+ligne+'\n'
226
227       # suppression du dernier saut de ligne
228       #txt = re.sub("\n$","",txt)
229       # on ajoute un saut de ligne avant
230       pattern=re.compile(" ?\#")
231       m=pattern.match(txt)
232       if m:
233          txt="\n"+txt
234       return txt
235
236    def generPARAMETRE_EVAL(self,obj):
237       """
238          Cette méthode convertit un PARAMETRE_EVAL
239          en une liste de chaines de caractères à la syntaxe python
240       """
241       if obj.valeur == None:
242          return obj.nom + ' = None ;\n'
243       else:
244          return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
245
246    def generITEM_PARAMETRE(self,obj):
247        return repr(obj) 
248
249    def generFormula(self,obj):
250        #return repr(obj) 
251        return str(obj) 
252
253    def generPARAMETRE(self,obj):
254       """
255          Cette méthode convertit un PARAMETRE
256          en une liste de chaines de caractères à la syntaxe python
257       """
258       return repr(obj) + ";\n"
259
260    def generETAPE_NIVEAU(self,obj):
261       """
262          Cette méthode convertit une étape niveau
263          en une liste de chaines de caractères à la syntaxe python
264       """
265       l=[]
266       if obj.etapes_niveaux == []:
267         for etape in obj.etapes:
268           l.append(self.generator(etape))
269       else:
270         for etape_niveau in obj.etapes_niveaux:
271           l.extend(self.generator(etape_niveau))
272       return l
273
274    def generETAPE(self,obj):
275       """
276          Cette méthode convertit une étape
277          en une liste de chaines de caractères à la syntaxe python
278       """
279       try:
280         sdname= self.generator(obj.sd)
281       except:
282         sdname='sansnom'
283       l=[]
284       label=sdname + '='+obj.definition.nom+'('
285       l.append(label)
286       if obj.reuse != None :
287         str = 'reuse ='+ self.generator(obj.reuse) + ','
288         l.append(str)
289       for v in obj.mc_liste:
290         if isinstance(v,Accas.MCBLOC) :
291           liste=self.generator(v)
292           for mocle in liste :
293             l.append(mocle)
294         elif isinstance(v,Accas.MCSIMP) :
295           text=self.generator(v)
296           l.append(v.nom+'='+text)
297         else:
298           # MCFACT ou MCList
299           liste=self.generator(v)
300           liste[0]=v.nom+'='+liste[0]
301           l.append(liste)
302       if len(l) == 1:
303         l[0]=label+');'
304       else :
305         l.append(');')
306       return l
307
308    def generFORM_ETAPE(self,obj):
309         """
310             Méthode particulière pour les objets de type FORMULE
311         """
312         l=[]
313         nom = obj.get_nom()
314         if nom == '' : nom = 'sansnom'
315         l.append(nom + ' = FORMULE(')
316         for v in obj.mc_liste:
317             text=self.generator(v)
318             l.append(v.nom+'='+text)
319         l.append(');')
320         return l
321
322    def generMACRO_ETAPE(self,obj):
323       """
324          Cette méthode convertit une macro-étape
325          en une liste de chaines de caractères à la syntaxe python
326       """
327       try:
328         if obj.sd == None:
329           sdname=''
330         else:
331           sdname= self.generator(obj.sd)+'='
332       except:
333         sdname='sansnom='
334       l=[]
335       label = sdname + obj.definition.nom+'('
336       l.append(label)
337       if obj.reuse != None:
338          # XXX faut il la virgule ou pas ????
339          str = "reuse =" + self.generator(obj.reuse) + ','
340          l.append(str)
341       for v in obj.mc_liste:
342         if isinstance(v,Accas.MCBLOC) :
343           liste=self.generator(v)
344           for mocle in liste :
345             l.append(mocle)
346         elif isinstance(v,Accas.MCSIMP) :
347           text=self.generator(v)
348           l.append(v.nom+'='+text)
349         else:
350           # MCFACT ou MCList
351           liste=self.generator(v)
352           liste[0]=v.nom+'='+liste[0]
353           l.append(liste)
354
355       if len(l) == 1:
356         l[0]=label+');'
357       else :
358         l.append(');')
359       return l
360
361    def generPROC_ETAPE(self,obj):
362       """
363          Cette méthode convertit une PROC étape
364          en une liste de chaines de caractères à la syntaxe python
365       """
366       l=[]
367       label=obj.definition.nom+'('
368       l.append(label)
369       for v in obj.mc_liste:
370         if isinstance(v,Accas.MCBLOC) :
371           liste=self.generator(v)
372           for mocle in liste :
373             l.append(mocle)
374         elif isinstance(v,Accas.MCSIMP) :
375           text=self.generator(v)
376           l.append(v.nom+'='+text)
377         else:
378           # MCFACT ou MCList
379           liste=self.generator(v)
380           liste[0]=v.nom+'='+liste[0]
381           l.append(liste)
382
383       if len(l) == 1:
384         l[0]=label+');'
385       else :
386         l.append(');')
387       return l
388
389    def generASSD(self,obj):
390       """
391           Convertit un objet dérivé d'ASSD en une chaine de caractères à la
392           syntaxe python
393       """
394       return obj.get_name()
395
396    def generMCFACT(self,obj):
397       """
398           Convertit un objet MCFACT en une liste de chaines de caractères à la
399           syntaxe python
400       """
401       l=[]
402       l.append('_F(')
403       for v in obj.mc_liste:
404          if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
405            # on est en présence d'une entite composée : on récupère une liste
406            liste=self.generator(v)
407            liste[0]=v.nom+'='+liste[0]
408            l.append(liste)
409          elif isinstance(v,Accas.MCBLOC):
410            liste=self.generator(v)
411            for arg in liste :
412              l.append(arg)
413          else:
414            # on est en présence d'un MCSIMP : on récupère une string
415            text =self.generator(v)
416            l.append(v.nom+'='+text)
417       # il faut être plus subtil dans l'ajout de la virgule en différenciant 
418       # le cas où elle est obligatoire (si self a des frères cadets 
419       # dans self.parent) ou non
420       # (cas où self est seul ou le benjamin de self.parent)
421       l.append('),')
422       return l
423
424    def generMCList(self,obj):
425       """
426           Convertit un objet MCList en une liste de chaines de caractères à la
427           syntaxe python
428       """
429       if len(obj.data) > 1:
430          l=['(']
431          for mcfact in obj.data: l.append(self.generator(mcfact))
432          l.append('),')
433       else:
434          l= self.generator(obj.data[0])
435       return l
436
437    def generMCBLOC(self,obj):
438       """
439           Convertit un objet MCBLOC en une liste de chaines de caractères à la
440           syntaxe python
441       """
442       l=[]
443       for v in obj.mc_liste:
444         if isinstance(v,Accas.MCBLOC) :
445           liste=self.generator(v)
446           for mocle in liste :
447             l.append(mocle)
448         elif isinstance(v,Accas.MCFACT):
449           liste=self.generator(v)
450         elif isinstance(v,Accas.MCList):
451           liste=self.generator(v)
452           liste[0]=v.nom+'='+liste[0]
453           # PN  essai de correction bug identation
454           if (hasattr(v,'data')) :
455             if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
456                l.append(liste)
457             else:
458                for mocle in liste :
459                  l.append(mocle)
460           else :
461              for mocle in liste :
462                l.append(mocle)
463         else:
464           data=self.generator(v)
465           if type(data) == types.ListType:
466             data[0]=v.nom+'='+data[0]
467           else:
468             data=v.nom+'='+data
469           l.append(data)
470       return l
471
472
473    def format_item(self,valeur,etape):
474       if type(valeur) == types.FloatType :
475          # Pour un flottant on utilise str
476          # ou la notation scientifique
477          s = str(valeur)
478          clefobj=etape.get_sdname()
479          if self.appli and self.appli.dict_reels.has_key(clefobj):
480            if self.appli.dict_reels[clefobj].has_key(valeur):
481              s=self.appli.dict_reels[clefobj][valeur]
482       elif type(valeur) == types.StringType :
483          if valeur.find('\n') == -1:
484             # pas de retour chariot, on utilise repr
485             s = repr(valeur)
486          elif valeur.find('"""') == -1:
487             # retour chariot mais pas de triple ", on formatte
488             s='"""'+valeur+'"""'
489          else:
490             s = repr(valeur)
491       elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods:
492          s = "CO('"+ self.generator(valeur) +"')"
493       elif isinstance(valeur,Accas.ASSD):
494          s = self.generator(valeur)
495       elif isinstance(valeur,Accas.PARAMETRE):
496          # il ne faut pas prendre la string que retourne gener
497          # mais seulement le nom dans le cas d'un paramètre
498          s = valeur.nom
499
500       #elif type(valeur) == types.InstanceType or isinstance(valeur,object):
501       #   if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
502       #      s = "CO('"+ self.generator(valeur) +"')"
503       #   elif isinstance(valeur,Accas.PARAMETRE):
504             # il ne faut pas prendre la string que retourne gener
505             # mais seulement le nom dans le cas d'un paramètre
506       #      s = valeur.nom
507       #   else:
508       #      print valeur
509       #      s = self.generator(valeur)
510
511       else :
512          # Pour les autres types on utilise repr
513          s = repr(valeur)
514       return s
515
516    def generMCSIMP(self,obj) :
517       """
518           Convertit un objet MCSIMP en une liste de chaines de caractères à la
519           syntaxe python
520       """
521       if type(obj.valeur) in (types.TupleType,types.ListType) :
522          s = ''
523          for val in obj.valeur :
524             s =s +self.format_item(val,obj.etape) + ','
525          if len(obj.valeur) > 1:
526             s = '(' + s + '),'
527          if obj.nbrColonnes() :
528             s=self.formatColonnes(obj.nbrColonnes(),s)
529       else :
530          s=self.format_item(obj.valeur,obj.etape) + ','
531       return s
532
533
534    def formatColonnes(self,nbrColonnes,text):
535       try :
536       #if 1 == 1 :
537         liste=text.split(",")
538         indice=0
539         textformat=""
540         while ( indice < len(liste) -2  ) :
541           for l in range(nbrColonnes) :
542             textformat=textformat+liste[indice]+","
543             indice=indice+1
544           textformat=textformat+"\n"
545         textformat=textformat+"),"
546       except :
547       #else :
548          textformat=text
549       return textformat