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
79 def writefile(self,filename):
84 def gener(self,obj,format='brut'):
86 Retourne une représentation du JDC obj sous une
87 forme qui est paramétrée par format.
88 Si format vaut 'brut', retourne une liste de listes de ...
89 Si format vaut 'standard', retourne un texte obtenu par concaténation de la liste
90 Si format vaut 'beautifie', retourne le meme texte beautifié
92 self.appli=obj.get_jdc_root().appli
94 liste= self.generator(obj)
97 elif format == 'standard':
98 self.text=string.join(liste)
99 elif format == 'beautifie':
100 jdc_formate = Formatage(liste,mode='.py')
101 self.text=jdc_formate.formate_jdc()
103 raise "Format pas implémenté : "+format
106 def generator(self,obj):
108 Cette methode joue un role d'aiguillage en fonction du type de obj
109 On pourrait utiliser les méthodes accept et visitxxx à la
110 place (dépend des gouts !!!)
112 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
113 if isinstance(obj,Accas.PROC_ETAPE):
114 return self.generPROC_ETAPE(obj)
115 # Attention doit etre placé avant MACRO (raison : héritage)
116 elif isinstance(obj,Accas.FORM_ETAPE):
117 return self.generFORM_ETAPE(obj)
118 elif isinstance(obj,Accas.MACRO_ETAPE):
119 return self.generMACRO_ETAPE(obj)
120 elif isinstance(obj,Accas.ETAPE):
121 return self.generETAPE(obj)
122 elif isinstance(obj,Accas.MCFACT):
123 return self.generMCFACT(obj)
124 elif isinstance(obj,Accas.MCList):
125 return self.generMCList(obj)
126 elif isinstance(obj,Accas.MCBLOC):
127 return self.generMCBLOC(obj)
128 elif isinstance(obj,Accas.MCSIMP):
129 return self.generMCSIMP(obj)
130 elif isinstance(obj,Accas.ASSD):
131 return self.generASSD(obj)
132 elif isinstance(obj,Accas.ETAPE_NIVEAU):
133 return self.generETAPE_NIVEAU(obj)
134 elif isinstance(obj,Accas.COMMENTAIRE):
135 return self.generCOMMENTAIRE(obj)
136 # Attention doit etre placé avant PARAMETRE (raison : héritage)
137 elif isinstance(obj,Accas.PARAMETRE_EVAL):
138 return self.generPARAMETRE_EVAL(obj)
139 elif isinstance(obj,Accas.PARAMETRE):
140 return self.generPARAMETRE(obj)
141 elif isinstance(obj,Accas.EVAL):
142 return self.generEVAL(obj)
143 elif isinstance(obj,Accas.COMMANDE_COMM):
144 return self.generCOMMANDE_COMM(obj)
145 elif isinstance(obj,Accas.JDC):
146 return self.generJDC(obj)
147 elif isinstance(obj,Accas.MCNUPLET):
148 return self.generMCNUPLET(obj)
149 elif isinstance(obj,ITEM_PARAMETRE):
150 return self.generITEM_PARAMETRE(obj)
152 raise "Type d'objet non prévu",obj
154 def generJDC(self,obj):
156 Cette méthode convertit un objet JDC en une liste de chaines de
157 caractères à la syntaxe python
160 if obj.definition.l_niveaux == ():
161 # Il n'y a pas de niveaux
162 for etape in obj.etapes:
163 l.append(self.generator(etape))
166 for etape_niveau in obj.etapes_niveaux:
167 l.extend(self.generator(etape_niveau))
169 # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
170 if type(l[-1])==types.ListType:
171 l[-1][-1] = l[-1][-1]+'\n'
172 elif type(l[-1])==types.StringType:
176 def generMCNUPLET(self,obj):
178 Méthode générant une représentation de self permettant son ecriture
179 dans le format python
183 for v in obj.mc_liste:
184 text = re.sub(".*=","",self.generator(v))
189 def generCOMMANDE_COMM(self,obj):
191 Cette méthode convertit un COMMANDE_COMM
192 en une liste de chaines de caractères à la syntaxe python
194 l_lignes = string.split(obj.valeur,'\n')
196 for ligne in l_lignes:
197 txt = txt + '##'+ligne+'\n'
200 def generEVAL(self,obj):
202 Cette méthode convertit un EVAL
203 en une liste de chaines de caractères à la syntaxe python
205 return 'EVAL("""'+ obj.valeur +'""")'
207 def generCOMMENTAIRE(self,obj):
209 Cette méthode convertit un COMMENTAIRE
210 en une liste de chaines de caractères à la syntaxe python
212 # modification pour répondre à la demande de C. Durand, d'éviter
213 # l'ajout systématique d'un dièse, à la suite du commentaire
214 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
216 sans_saut = re.sub("\n$","",obj.valeur)
217 l_lignes = string.split(sans_saut,'\n')
219 for ligne in l_lignes:
220 txt = txt + '#'+ligne+'\n'
222 # suppression du dernier saut de ligne
223 txt = re.sub("\n$","",txt)
226 def generPARAMETRE_EVAL(self,obj):
228 Cette méthode convertit un PARAMETRE_EVAL
229 en une liste de chaines de caractères à la syntaxe python
231 if obj.valeur == None:
232 return obj.nom + ' = None ;\n'
234 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
236 def generITEM_PARAMETRE(self,obj):
239 def generPARAMETRE(self,obj):
241 Cette méthode convertit un PARAMETRE
242 en une liste de chaines de caractères à la syntaxe python
244 if type(obj.valeur) == types.StringType:
245 # PN pour corriger le bug a='3+4' au lieu de a= 3+4
246 #return obj.nom + " = '" + obj.valeur + "';\n"
247 return obj.nom + " = " + obj.valeur + ";\n"
249 return obj.nom + ' = ' + str(obj.valeur) + ';\n'
251 def generETAPE_NIVEAU(self,obj):
253 Cette méthode convertit une étape niveau
254 en une liste de chaines de caractères à la syntaxe python
257 if obj.etapes_niveaux == []:
258 for etape in obj.etapes:
259 l.append(self.generator(etape))
261 for etape_niveau in obj.etapes_niveaux:
262 l.extend(self.generator(etape_niveau))
265 def generETAPE(self,obj):
267 Cette méthode convertit une étape
268 en une liste de chaines de caractères à la syntaxe python
271 sdname= self.generator(obj.sd)
275 label=sdname + '='+obj.definition.nom+'('
277 if obj.reuse != None :
278 str = 'reuse ='+ self.generator(obj.reuse) + ','
280 for v in obj.mc_liste:
281 if isinstance(v,Accas.MCBLOC) :
282 liste=self.generator(v)
285 elif isinstance(v,Accas.MCSIMP) :
286 text=self.generator(v)
287 l.append(v.nom+'='+text)
290 liste=self.generator(v)
291 liste[0]=v.nom+'='+liste[0]
299 def generFORM_ETAPE(self,obj):
301 Méthode particulière pour les objets de type FORMULE
305 if nom == '' : nom = 'sansnom'
306 l.append(nom + ' = FORMULE(')
307 for v in obj.mc_liste:
308 text=self.generator(v)
309 l.append(v.nom+'='+text)
313 def generMACRO_ETAPE(self,obj):
315 Cette méthode convertit une macro-étape
316 en une liste de chaines de caractères à la syntaxe python
322 sdname= self.generator(obj.sd)+'='
326 label = sdname + obj.definition.nom+'('
328 if obj.reuse != None:
329 # XXX faut il la virgule ou pas ????
330 str = "reuse =" + self.generator(obj.reuse) + ','
332 for v in obj.mc_liste:
333 if isinstance(v,Accas.MCBLOC) :
334 liste=self.generator(v)
337 elif isinstance(v,Accas.MCSIMP) :
338 text=self.generator(v)
339 l.append(v.nom+'='+text)
342 liste=self.generator(v)
343 liste[0]=v.nom+'='+liste[0]
352 def generPROC_ETAPE(self,obj):
354 Cette méthode convertit une PROC étape
355 en une liste de chaines de caractères à la syntaxe python
358 label=obj.definition.nom+'('
360 for v in obj.mc_liste:
361 if isinstance(v,Accas.MCBLOC) :
362 liste=self.generator(v)
365 elif isinstance(v,Accas.MCSIMP) :
366 text=self.generator(v)
367 l.append(v.nom+'='+text)
370 liste=self.generator(v)
371 liste[0]=v.nom+'='+liste[0]
380 def generASSD(self,obj):
382 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
385 return obj.get_name()
387 def generMCFACT(self,obj):
389 Convertit un objet MCFACT en une liste de chaines de caractères à la
394 for v in obj.mc_liste:
395 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
396 # on est en présence d'une entite composée : on récupère une liste
397 liste=self.generator(v)
398 liste[0]=v.nom+'='+liste[0]
400 elif isinstance(v,Accas.MCBLOC):
401 liste=self.generator(v)
405 # on est en présence d'un MCSIMP : on récupère une string
406 text =self.generator(v)
407 l.append(v.nom+'='+text)
408 # il faut être plus subtil dans l'ajout de la virgule en différenciant
409 # le cas où elle est obligatoire (si self a des frères cadets
410 # dans self.parent) ou non
411 # (cas où self est seul ou le benjamin de self.parent)
415 def generMCList(self,obj):
417 Convertit un objet MCList en une liste de chaines de caractères à la
420 if len(obj.data) > 1:
422 for mcfact in obj.data: l.append(self.generator(mcfact))
425 l= self.generator(obj.data[0])
428 def generMCBLOC(self,obj):
430 Convertit un objet MCBLOC en une liste de chaines de caractères à la
434 for v in obj.mc_liste:
435 if isinstance(v,Accas.MCBLOC) :
436 liste=self.generator(v)
439 elif isinstance(v,Accas.MCList):
440 liste=self.generator(v)
441 liste[0]=v.nom+'='+liste[0]
445 data=self.generator(v)
446 if type(data) == types.ListType:
447 data[0]=v.nom+'='+data[0]
453 def generMCSIMP(self,obj) :
455 Convertit un objet MCSIMP en une liste de chaines de caractères à la
458 if type(obj.valeur) in (types.TupleType,types.ListType) :
460 for val in obj.valeur :
461 if type(val) == types.InstanceType :
462 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
463 s = s + "CO('"+ self.generator(val) +"')"
464 elif val.__class__.__name__ == 'CO':
465 s = s + "CO('"+ self.generator(val) +"')"
466 elif isinstance(val,Accas.PARAMETRE):
467 # il ne faut pas prendre la string que retourne gener
468 # mais seulement le nom dans le cas d'un paramètre
471 s = s + self.generator(val)
472 elif type(val) == types.FloatType :
473 # Pour un flottant on utilise str qui a une precision de
474 # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
477 clefobj=obj.GetNomConcept()
478 if self.appli.dict_reels.has_key(clefobj):
479 if self.appli.dict_reels[clefobj].has_key(val):
480 s2=self.appli.dict_reels[clefobj][val]
485 # Pour les autres types on utilise repr
488 if len(obj.valeur) > 1:
492 if type(val) == types.InstanceType :
493 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
494 s = "CO('"+ self.generator(val) +"')"
495 elif val.__class__.__name__ == 'CO':
496 s = "CO('"+ self.generator(val) +"')"
497 elif isinstance(val,Accas.PARAMETRE):
498 # il ne faut pas prendre la string que retourne gener
499 # mais seulement le nom dans le cas d'un paramètre
502 s = self.generator(val)
503 elif type(val) == types.FloatType :
504 # Pour un flottant on utilise str
505 # ou la notation scientifique
508 clefobj=obj.GetNomConcept()
509 if self.appli.dict_reels.has_key(clefobj):
510 if self.appli.dict_reels[clefobj].has_key(val):
511 s=self.appli.dict_reels[clefobj][val]
515 # Pour les autres types on utilise repr