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.
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.
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.
20 # ======================================================================
22 Ce module contient le plugin generateur de fichier au format
27 import types,string,re
29 from Noyau import N_CR
30 from Noyau.N_utils import repr_float
31 from Accas import ETAPE,PROC_ETAPE,MACRO_ETAPE,ETAPE_NIVEAU,JDC,FORM_ETAPE
32 from Accas import MCSIMP,MCFACT,MCBLOC,MCList,EVAL
33 from Accas import GEOM,ASSD,MCNUPLET
34 from Accas import COMMENTAIRE,PARAMETRE, PARAMETRE_EVAL,COMMANDE_COMM
35 from Formatage import Formatage
39 Retourne les informations nécessaires pour le chargeur de plugins
41 Ces informations sont retournées dans un dictionnaire
46 # La factory pour créer une instance du plugin
47 'factory' : PythonGenerator,
51 class PythonGenerator:
53 Ce generateur parcourt un objet de type JDC et produit
54 un fichier au format python
56 L'acquisition et le parcours sont réalisés par la méthode
57 generator.gener(objet_jdc,format)
59 L'écriture du fichier au format ini par appel de la méthode
60 generator.writefile(nom_fichier)
62 Ses caractéristiques principales sont exposées dans des attributs
64 - extensions : qui donne une liste d'extensions de fichier préconisées
67 # Les extensions de fichier préconisées
70 def __init__(self,cr=None):
71 # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
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
80 def writefile(self,filename):
85 def gener(self,obj,format='brut'):
87 Retourne une représentation du JDC obj sous une
88 forme qui est paramétrée par format.
89 Si format vaut 'brut', retourne une liste de listes de ...
90 Si format vaut 'standard', retourne un texte obtenu par concaténation de la liste
91 Si format vaut 'beautifie', retourne le meme texte beautifié
93 liste= self.generator(obj)
96 elif format == 'standard':
97 self.text=string.join(liste)
98 elif format == 'beautifie':
99 jdc_formate = Formatage(liste,mode='.py')
100 self.text=jdc_formate.formate_jdc()
102 raise "Format pas implémenté : "+format
105 def generator(self,obj):
107 Cette methode joue un role d'aiguillage en fonction du type de obj
108 On pourrait utiliser les méthodes accept et visitxxx à la
109 place (dépend des gouts !!!)
111 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
112 if isinstance(obj,PROC_ETAPE):
113 return self.generPROC_ETAPE(obj)
114 elif isinstance(obj,MACRO_ETAPE):
115 return self.generMACRO_ETAPE(obj)
116 elif isinstance(obj,FORM_ETAPE):
117 return self.generFORM_ETAPE(obj)
118 elif isinstance(obj,ETAPE):
119 return self.generETAPE(obj)
120 elif isinstance(obj,MCFACT):
121 return self.generMCFACT(obj)
122 elif isinstance(obj,MCList):
123 return self.generMCList(obj)
124 elif isinstance(obj,MCBLOC):
125 return self.generMCBLOC(obj)
126 elif isinstance(obj,MCSIMP):
127 return self.generMCSIMP(obj)
128 elif isinstance(obj,ASSD):
129 return self.generASSD(obj)
130 elif isinstance(obj,ETAPE_NIVEAU):
131 return self.generETAPE_NIVEAU(obj)
132 elif isinstance(obj,COMMENTAIRE):
133 return self.generCOMMENTAIRE(obj)
134 # Attention doit etre placé avant PARAMETRE (raison : héritage)
135 elif isinstance(obj,PARAMETRE_EVAL):
136 return self.generPARAMETRE_EVAL(obj)
137 elif isinstance(obj,PARAMETRE):
138 return self.generPARAMETRE(obj)
139 elif isinstance(obj,EVAL):
140 return self.generEVAL(obj)
141 elif isinstance(obj,COMMANDE_COMM):
142 return self.generCOMMANDE_COMM(obj)
143 elif isinstance(obj,JDC):
144 return self.generJDC(obj)
145 elif isinstance(obj,MCNUPLET):
146 return self.generMCNUPLET(obj)
148 raise "Type d'objet non prévu",obj
150 def generJDC(self,obj):
152 Cette méthode convertit un objet JDC en une liste de chaines de
153 caractères à la syntaxe python
156 if obj.definition.l_niveaux == ():
157 # Il n'y a pas de niveaux
158 for etape in obj.etapes:
159 l.append(self.generator(etape))
162 for etape_niveau in obj.etapes_niveaux:
163 l.extend(self.generator(etape_niveau))
165 # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
166 if type(l[-1])==types.ListType:
167 l[-1][-1] = l[-1][-1]+'\n'
168 elif type(l[-1])==types.StringType:
172 def generMCNUPLET(self,obj):
174 Méthode générant une représentation de self permettant son ecriture
175 dans le format python
179 for v in obj.mc_liste:
180 text = re.sub(".*=","",self.generator(v))
185 def generCOMMANDE_COMM(self,obj):
187 Cette méthode convertit un COMMANDE_COMM
188 en une liste de chaines de caractères à la syntaxe python
190 l_lignes = string.split(obj.valeur,'\n')
192 for ligne in l_lignes:
193 txt = txt + '##'+ligne+'\n'
196 def generEVAL(self,obj):
198 Cette méthode convertit un EVAL
199 en une liste de chaines de caractères à la syntaxe python
201 return 'EVAL("""'+ obj.valeur +'""")'
203 def generCOMMENTAIRE(self,obj):
205 Cette méthode convertit un COMMENTAIRE
206 en une liste de chaines de caractères à la syntaxe python
208 # modification pour répondre à la demande de C. Durand, d'éviter
209 # l'ajout systématique d'un dièse, à la suite du commentaire
210 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
212 sans_saut = re.sub("\n$","",obj.valeur)
213 l_lignes = string.split(sans_saut,'\n')
215 for ligne in l_lignes:
216 txt = txt + '#'+ligne+'\n'
218 # suppression du dernier saut de ligne
219 txt = re.sub("\n$","",txt)
222 def generPARAMETRE_EVAL(self,obj):
224 Cette méthode convertit un PARAMETRE_EVAL
225 en une liste de chaines de caractères à la syntaxe python
227 if obj.valeur == None:
228 return obj.nom + ' = None ;\n'
230 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
232 def generPARAMETRE(self,obj):
234 Cette méthode convertit un PARAMETRE
235 en une liste de chaines de caractères à la syntaxe python
237 if type(obj.valeur) == types.StringType:
238 # PN pour corriger le bug a='3+4' au lieu de a= 3+4
239 #return obj.nom + " = '" + obj.valeur + "';\n"
240 return obj.nom + " = " + obj.valeur + ";\n"
242 return obj.nom + ' = ' + str(obj.valeur) + ';\n'
244 def generETAPE_NIVEAU(self,obj):
246 Cette méthode convertit une étape niveau
247 en une liste de chaines de caractères à la syntaxe python
250 if obj.etapes_niveaux == []:
251 for etape in obj.etapes:
252 l.append(self.generator(etape))
254 for etape_niveau in obj.etapes_niveaux:
255 l.extend(self.generator(etape_niveau))
258 def generETAPE(self,obj):
260 Cette méthode convertit une étape
261 en une liste de chaines de caractères à la syntaxe python
264 sdname= self.generator(obj.sd)
268 label=sdname + '='+obj.definition.nom+'('
270 if obj.reuse != None :
271 str = 'reuse ='+ self.generator(obj.reuse) + ','
273 for v in obj.mc_liste:
274 if isinstance(v,MCBLOC) :
275 liste=self.generator(v)
278 elif isinstance(v,MCSIMP) :
279 text=self.generator(v)
280 l.append(v.nom+'='+text)
283 liste=self.generator(v)
284 liste[0]=v.nom+'='+liste[0]
292 def generFORM_ETAPE(self,obj):
294 Méthode particulière pour les objets de type FORMULE
298 if nom == '' : nom = 'sansnom'
299 if len(obj.mc_liste)>0:
300 l.append(nom + ' = FORMULE(')
301 s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''"
305 l.append(nom+' = FORMULE();')
308 def generMACRO_ETAPE(self,obj):
310 Cette méthode convertit une macro-étape
311 en une liste de chaines de caractères à la syntaxe python
313 if obj.definition.nom == 'FORMULE' : return self.gen_formule(obj)
318 sdname= self.generator(obj.sd)+'='
322 label = sdname + obj.definition.nom+'('
324 if obj.reuse != None:
325 # XXX faut il la virgule ou pas ????
326 str = "reuse =" + self.generator(obj.reuse) + ','
328 for v in obj.mc_liste:
329 if isinstance(v,MCBLOC) :
330 liste=self.generator(v)
333 elif isinstance(v,MCSIMP) :
334 text=self.generator(v)
335 l.append(v.nom+'='+text)
338 liste=self.generator(v)
339 liste[0]=v.nom+'='+liste[0]
348 def gen_formule(self,obj):
350 Méthode particuliere aux objets de type FORMULE
356 sdname= self.generator(obj.sd)
360 label=sdname + ' = FORMULE('
362 for v in obj.mc_liste:
364 s= v.nom+':'+sdname+'('+v.valeur+')'
372 def generPROC_ETAPE(self,obj):
374 Cette méthode convertit une PROC étape
375 en une liste de chaines de caractères à la syntaxe python
378 label=obj.definition.nom+'('
380 for v in obj.mc_liste:
381 if isinstance(v,MCBLOC) :
382 liste=self.generator(v)
385 elif isinstance(v,MCSIMP) :
386 text=self.generator(v)
387 l.append(v.nom+'='+text)
390 liste=self.generator(v)
391 liste[0]=v.nom+'='+liste[0]
400 def generASSD(self,obj):
402 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
405 return obj.get_name()
407 def generMCFACT(self,obj):
409 Convertit un objet MCFACT en une liste de chaines de caractères à la
414 for v in obj.mc_liste:
415 if not isinstance(v,MCSIMP) and not isinstance (v,MCBLOC) :
416 # on est en présence d'une entite composée : on récupère une liste
417 liste=self.generator(v)
418 liste[0]=v.nom+'='+liste[0]
420 elif isinstance(v,MCBLOC):
421 liste=self.generator(v)
425 # on est en présence d'un MCSIMP : on récupère une string
426 text =self.generator(v)
427 l.append(v.nom+'='+text)
428 # il faut être plus subtil dans l'ajout de la virgule en différenciant
429 # le cas où elle est obligatoire (si self a des frères cadets
430 # dans self.parent) ou non
431 # (cas où self est seul ou le benjamin de self.parent)
435 def generMCList(self,obj):
437 Convertit un objet MCList en une liste de chaines de caractères à la
443 for mcfact in obj.data:
444 l.append(self.generator(mcfact))
448 def generMCBLOC(self,obj):
450 Convertit un objet MCBLOC en une liste de chaines de caractères à la
454 for v in obj.mc_liste:
455 if isinstance(v,MCBLOC) :
456 liste=self.generator(v)
459 elif isinstance(v,MCList):
460 liste=self.generator(v)
461 liste[0]=v.nom+'='+liste[0]
465 data=self.generator(v)
466 if type(data) == types.ListType:
467 data[0]=v.nom+'='+data[0]
473 def generMCSIMP(self,obj) :
475 Convertit un objet MCSIMP en une liste de chaines de caractères à la
478 if type(obj.valeur) in (types.TupleType,types.ListType) :
480 for val in obj.valeur :
481 if type(val) == types.InstanceType :
482 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
483 s = s + "CO('"+ self.generator(val) +"')"
484 elif val.__class__.__name__ == 'CO':
485 s = s + "CO('"+ self.generator(val) +"')"
486 elif isinstance(val,PARAMETRE):
487 # il ne faut pas prendre la string que retourne gener
488 # mais seulement le nom dans le cas d'un paramètre
491 s = s + self.generator(val)
492 elif type(val) == types.FloatType :
493 # Pour un flottant on utilise str qui a une precision de
494 # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
497 # Pour les autres types on utilise repr
500 if len(obj.valeur) > 1:
504 if type(val) == types.InstanceType :
505 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
506 s = "CO('"+ self.generator(val) +"')"
507 elif val.__class__.__name__ == 'CO':
508 s = "CO('"+ self.generator(val) +"')"
509 elif isinstance(val,PARAMETRE):
510 # il ne faut pas prendre la string que retourne gener
511 # mais seulement le nom dans le cas d'un paramètre
514 s = self.generator(val)
515 elif type(val) == types.FloatType :
516 # Pour un flottant on utilise str
519 # Pour les autres types on utilise repr