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
32 from Extensions.parametre import ITEM_PARAMETRE
33 from Formatage import Formatage
37 Retourne les informations nécessaires pour le chargeur de plugins
39 Ces informations sont retournées dans un dictionnaire
44 # La factory pour créer une instance du plugin
45 'factory' : PythonGenerator,
49 class PythonGenerator:
51 Ce generateur parcourt un objet de type JDC et produit
52 un fichier au format python
54 L'acquisition et le parcours sont réalisés par la méthode
55 generator.gener(objet_jdc,format)
57 L'écriture du fichier au format ini par appel de la méthode
58 generator.writefile(nom_fichier)
60 Ses caractéristiques principales sont exposées dans des attributs
62 - extensions : qui donne une liste d'extensions de fichier préconisées
65 # Les extensions de fichier préconisées
68 def __init__(self,cr=None):
69 # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
73 self.cr=N_CR.CR(debut='CR generateur format python pour python',
74 fin='fin CR format python pour python')
75 # Le texte au format python est stocké dans l'attribut text
78 def writefile(self,filename):
83 def gener(self,obj,format='brut'):
85 Retourne une représentation du JDC obj sous une
86 forme qui est paramétrée par format.
87 Si format vaut 'brut', retourne une liste de listes de ...
88 Si format vaut 'standard', retourne un texte obtenu par concaténation de la liste
89 Si format vaut 'beautifie', retourne le meme texte beautifié
91 liste= self.generator(obj)
94 elif format == 'standard':
95 self.text=string.join(liste)
96 elif format == 'beautifie':
97 jdc_formate = Formatage(liste,mode='.py')
98 self.text=jdc_formate.formate_jdc()
100 raise "Format pas implémenté : "+format
103 def generator(self,obj):
105 Cette methode joue un role d'aiguillage en fonction du type de obj
106 On pourrait utiliser les méthodes accept et visitxxx à la
107 place (dépend des gouts !!!)
109 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
110 if isinstance(obj,Accas.PROC_ETAPE):
111 return self.generPROC_ETAPE(obj)
112 # Attention doit etre placé avant MACRO (raison : héritage)
113 elif isinstance(obj,Accas.FORM_ETAPE):
114 return self.generFORM_ETAPE(obj)
115 elif isinstance(obj,Accas.MACRO_ETAPE):
116 return self.generMACRO_ETAPE(obj)
117 elif isinstance(obj,Accas.ETAPE):
118 return self.generETAPE(obj)
119 elif isinstance(obj,Accas.MCFACT):
120 return self.generMCFACT(obj)
121 elif isinstance(obj,Accas.MCList):
122 return self.generMCList(obj)
123 elif isinstance(obj,Accas.MCBLOC):
124 return self.generMCBLOC(obj)
125 elif isinstance(obj,Accas.MCSIMP):
126 return self.generMCSIMP(obj)
127 elif isinstance(obj,Accas.ASSD):
128 return self.generASSD(obj)
129 elif isinstance(obj,Accas.ETAPE_NIVEAU):
130 return self.generETAPE_NIVEAU(obj)
131 elif isinstance(obj,Accas.COMMENTAIRE):
132 return self.generCOMMENTAIRE(obj)
133 # Attention doit etre placé avant PARAMETRE (raison : héritage)
134 elif isinstance(obj,Accas.PARAMETRE_EVAL):
135 return self.generPARAMETRE_EVAL(obj)
136 elif isinstance(obj,Accas.PARAMETRE):
137 return self.generPARAMETRE(obj)
138 elif isinstance(obj,Accas.EVAL):
139 return self.generEVAL(obj)
140 elif isinstance(obj,Accas.COMMANDE_COMM):
141 return self.generCOMMANDE_COMM(obj)
142 elif isinstance(obj,Accas.JDC):
143 return self.generJDC(obj)
144 elif isinstance(obj,Accas.MCNUPLET):
145 return self.generMCNUPLET(obj)
146 elif isinstance(obj,ITEM_PARAMETRE):
147 return self.generITEM_PARAMETRE(obj)
149 raise "Type d'objet non prévu",obj
151 def generJDC(self,obj):
153 Cette méthode convertit un objet JDC en une liste de chaines de
154 caractères à la syntaxe python
157 if obj.definition.l_niveaux == ():
158 # Il n'y a pas de niveaux
159 for etape in obj.etapes:
160 l.append(self.generator(etape))
163 for etape_niveau in obj.etapes_niveaux:
164 l.extend(self.generator(etape_niveau))
166 # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
167 if type(l[-1])==types.ListType:
168 l[-1][-1] = l[-1][-1]+'\n'
169 elif type(l[-1])==types.StringType:
173 def generMCNUPLET(self,obj):
175 Méthode générant une représentation de self permettant son ecriture
176 dans le format python
180 for v in obj.mc_liste:
181 text = re.sub(".*=","",self.generator(v))
186 def generCOMMANDE_COMM(self,obj):
188 Cette méthode convertit un COMMANDE_COMM
189 en une liste de chaines de caractères à la syntaxe python
191 l_lignes = string.split(obj.valeur,'\n')
193 for ligne in l_lignes:
194 txt = txt + '##'+ligne+'\n'
197 def generEVAL(self,obj):
199 Cette méthode convertit un EVAL
200 en une liste de chaines de caractères à la syntaxe python
202 return 'EVAL("""'+ obj.valeur +'""")'
204 def generCOMMENTAIRE(self,obj):
206 Cette méthode convertit un COMMENTAIRE
207 en une liste de chaines de caractères à la syntaxe python
209 # modification pour répondre à la demande de C. Durand, d'éviter
210 # l'ajout systématique d'un dièse, à la suite du commentaire
211 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
213 sans_saut = re.sub("\n$","",obj.valeur)
214 l_lignes = string.split(sans_saut,'\n')
216 for ligne in l_lignes:
217 txt = txt + '#'+ligne+'\n'
219 # suppression du dernier saut de ligne
220 txt = re.sub("\n$","",txt)
223 def generPARAMETRE_EVAL(self,obj):
225 Cette méthode convertit un PARAMETRE_EVAL
226 en une liste de chaines de caractères à la syntaxe python
228 if obj.valeur == None:
229 return obj.nom + ' = None ;\n'
231 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
233 def generITEM_PARAMETRE(self,obj):
236 def generPARAMETRE(self,obj):
238 Cette méthode convertit un PARAMETRE
239 en une liste de chaines de caractères à la syntaxe python
241 if type(obj.valeur) == types.StringType:
242 # PN pour corriger le bug a='3+4' au lieu de a= 3+4
243 #return obj.nom + " = '" + obj.valeur + "';\n"
244 return obj.nom + " = " + obj.valeur + ";\n"
246 return obj.nom + ' = ' + str(obj.valeur) + ';\n'
248 def generETAPE_NIVEAU(self,obj):
250 Cette méthode convertit une étape niveau
251 en une liste de chaines de caractères à la syntaxe python
254 if obj.etapes_niveaux == []:
255 for etape in obj.etapes:
256 l.append(self.generator(etape))
258 for etape_niveau in obj.etapes_niveaux:
259 l.extend(self.generator(etape_niveau))
262 def generETAPE(self,obj):
264 Cette méthode convertit une étape
265 en une liste de chaines de caractères à la syntaxe python
268 sdname= self.generator(obj.sd)
272 label=sdname + '='+obj.definition.nom+'('
274 if obj.reuse != None :
275 str = 'reuse ='+ self.generator(obj.reuse) + ','
277 for v in obj.mc_liste:
278 if isinstance(v,Accas.MCBLOC) :
279 liste=self.generator(v)
282 elif isinstance(v,Accas.MCSIMP) :
283 text=self.generator(v)
284 l.append(v.nom+'='+text)
287 liste=self.generator(v)
288 liste[0]=v.nom+'='+liste[0]
296 def generFORM_ETAPE(self,obj):
298 Méthode particulière pour les objets de type FORMULE
302 if nom == '' : nom = 'sansnom'
303 l.append(nom + ' = FORMULE(')
304 for v in obj.mc_liste:
305 text=self.generator(v)
306 l.append(v.nom+'='+text)
310 def generMACRO_ETAPE(self,obj):
312 Cette méthode convertit une macro-étape
313 en une liste de chaines de caractères à la syntaxe python
319 sdname= self.generator(obj.sd)+'='
323 label = sdname + obj.definition.nom+'('
325 if obj.reuse != None:
326 # XXX faut il la virgule ou pas ????
327 str = "reuse =" + self.generator(obj.reuse) + ','
329 for v in obj.mc_liste:
330 if isinstance(v,Accas.MCBLOC) :
331 liste=self.generator(v)
334 elif isinstance(v,Accas.MCSIMP) :
335 text=self.generator(v)
336 l.append(v.nom+'='+text)
339 liste=self.generator(v)
340 liste[0]=v.nom+'='+liste[0]
349 def generPROC_ETAPE(self,obj):
351 Cette méthode convertit une PROC étape
352 en une liste de chaines de caractères à la syntaxe python
355 label=obj.definition.nom+'('
357 for v in obj.mc_liste:
358 if isinstance(v,Accas.MCBLOC) :
359 liste=self.generator(v)
362 elif isinstance(v,Accas.MCSIMP) :
363 text=self.generator(v)
364 l.append(v.nom+'='+text)
367 liste=self.generator(v)
368 liste[0]=v.nom+'='+liste[0]
377 def generASSD(self,obj):
379 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
382 return obj.get_name()
384 def generMCFACT(self,obj):
386 Convertit un objet MCFACT en une liste de chaines de caractères à la
391 for v in obj.mc_liste:
392 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
393 # on est en présence d'une entite composée : on récupère une liste
394 liste=self.generator(v)
395 liste[0]=v.nom+'='+liste[0]
397 elif isinstance(v,Accas.MCBLOC):
398 liste=self.generator(v)
402 # on est en présence d'un MCSIMP : on récupère une string
403 text =self.generator(v)
404 l.append(v.nom+'='+text)
405 # il faut être plus subtil dans l'ajout de la virgule en différenciant
406 # le cas où elle est obligatoire (si self a des frères cadets
407 # dans self.parent) ou non
408 # (cas où self est seul ou le benjamin de self.parent)
412 def generMCList(self,obj):
414 Convertit un objet MCList en une liste de chaines de caractères à la
417 if len(obj.data) > 1:
419 for mcfact in obj.data: l.append(self.generator(mcfact))
422 l= self.generator(obj.data[0])
425 def generMCBLOC(self,obj):
427 Convertit un objet MCBLOC en une liste de chaines de caractères à la
431 for v in obj.mc_liste:
432 if isinstance(v,Accas.MCBLOC) :
433 liste=self.generator(v)
436 elif isinstance(v,Accas.MCList):
437 liste=self.generator(v)
438 liste[0]=v.nom+'='+liste[0]
442 data=self.generator(v)
443 if type(data) == types.ListType:
444 data[0]=v.nom+'='+data[0]
450 def generMCSIMP(self,obj) :
452 Convertit un objet MCSIMP en une liste de chaines de caractères à la
455 if type(obj.valeur) in (types.TupleType,types.ListType) :
457 for val in obj.valeur :
458 if type(val) == types.InstanceType :
459 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
460 s = s + "CO('"+ self.generator(val) +"')"
461 elif val.__class__.__name__ == 'CO':
462 s = s + "CO('"+ self.generator(val) +"')"
463 elif isinstance(val,Accas.PARAMETRE):
464 # il ne faut pas prendre la string que retourne gener
465 # mais seulement le nom dans le cas d'un paramètre
468 s = s + self.generator(val)
469 elif type(val) == types.FloatType :
470 # Pour un flottant on utilise str qui a une precision de
471 # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
474 # Pour les autres types on utilise repr
477 if len(obj.valeur) > 1:
481 if type(val) == types.InstanceType :
482 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
483 s = "CO('"+ self.generator(val) +"')"
484 elif val.__class__.__name__ == 'CO':
485 s = "CO('"+ self.generator(val) +"')"
486 elif isinstance(val,Accas.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 = self.generator(val)
492 elif type(val) == types.FloatType :
493 # Pour un flottant on utilise str
496 # Pour les autres types on utilise repr