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
33 from Extensions.parametre import ITEM_PARAMETRE
34 from Formatage import Formatage
38 Retourne les informations nécessaires pour le chargeur de plugins
40 Ces informations sont retournées dans un dictionnaire
45 # La factory pour créer une instance du plugin
46 'factory' : PythonGenerator,
50 class PythonGenerator:
52 Ce generateur parcourt un objet de type JDC et produit
53 un fichier au format python
55 L'acquisition et le parcours sont réalisés par la méthode
56 generator.gener(objet_jdc,format)
58 L'écriture du fichier au format ini par appel de la méthode
59 generator.writefile(nom_fichier)
61 Ses caractéristiques principales sont exposées dans des attributs
63 - extensions : qui donne une liste d'extensions de fichier préconisées
66 # Les extensions de fichier préconisées
69 def __init__(self,cr=None):
70 # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
74 self.cr=N_CR.CR(debut='CR generateur format python pour python',
75 fin='fin CR format python pour python')
76 # 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 self.appli=obj.get_jdc_root().appli
95 liste= self.generator(obj)
98 elif format == 'standard':
99 self.text=string.join(liste)
100 elif format == 'beautifie':
101 jdc_formate = Formatage(liste,mode='.py')
102 self.text=jdc_formate.formate_jdc()
104 raise "Format pas implémenté : "+format
107 def generator(self,obj):
109 Cette methode joue un role d'aiguillage en fonction du type de obj
110 On pourrait utiliser les méthodes accept et visitxxx à la
111 place (dépend des gouts !!!)
113 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
114 if isinstance(obj,Accas.PROC_ETAPE):
115 return self.generPROC_ETAPE(obj)
116 # Attention doit etre placé avant MACRO (raison : héritage)
117 elif isinstance(obj,Accas.FORM_ETAPE):
118 return self.generFORM_ETAPE(obj)
119 elif isinstance(obj,Accas.MACRO_ETAPE):
120 return self.generMACRO_ETAPE(obj)
121 elif isinstance(obj,Accas.ETAPE):
122 return self.generETAPE(obj)
123 elif isinstance(obj,Accas.MCFACT):
124 return self.generMCFACT(obj)
125 elif isinstance(obj,Accas.MCList):
126 return self.generMCList(obj)
127 elif isinstance(obj,Accas.MCBLOC):
128 return self.generMCBLOC(obj)
129 elif isinstance(obj,Accas.MCSIMP):
130 return self.generMCSIMP(obj)
131 elif isinstance(obj,Accas.ASSD):
132 return self.generASSD(obj)
133 elif isinstance(obj,Accas.ETAPE_NIVEAU):
134 return self.generETAPE_NIVEAU(obj)
135 elif isinstance(obj,Accas.COMMENTAIRE):
136 return self.generCOMMENTAIRE(obj)
137 # Attention doit etre placé avant PARAMETRE (raison : héritage)
138 elif isinstance(obj,Accas.PARAMETRE_EVAL):
139 return self.generPARAMETRE_EVAL(obj)
140 elif isinstance(obj,Accas.PARAMETRE):
141 return self.generPARAMETRE(obj)
142 elif isinstance(obj,Accas.EVAL):
143 return self.generEVAL(obj)
144 elif isinstance(obj,Accas.COMMANDE_COMM):
145 return self.generCOMMANDE_COMM(obj)
146 elif isinstance(obj,Accas.JDC):
147 return self.generJDC(obj)
148 elif isinstance(obj,Accas.MCNUPLET):
149 return self.generMCNUPLET(obj)
150 elif isinstance(obj,ITEM_PARAMETRE):
151 return self.generITEM_PARAMETRE(obj)
153 raise "Type d'objet non prévu",obj
155 def generJDC(self,obj):
157 Cette méthode convertit un objet JDC en une liste de chaines de
158 caractères à la syntaxe python
161 if obj.definition.l_niveaux == ():
162 # Il n'y a pas de niveaux
163 for etape in obj.etapes:
164 l.append(self.generator(etape))
167 for etape_niveau in obj.etapes_niveaux:
168 l.extend(self.generator(etape_niveau))
170 # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
171 if type(l[-1])==types.ListType:
172 l[-1][-1] = l[-1][-1]+'\n'
173 elif type(l[-1])==types.StringType:
177 def generMCNUPLET(self,obj):
179 Méthode générant une représentation de self permettant son ecriture
180 dans le format python
184 for v in obj.mc_liste:
185 text = re.sub(".*=","",self.generator(v))
190 def generCOMMANDE_COMM(self,obj):
192 Cette méthode convertit un COMMANDE_COMM
193 en une liste de chaines de caractères à la syntaxe python
195 l_lignes = string.split(obj.valeur,'\n')
197 for ligne in l_lignes:
198 txt = txt + '##'+ligne+'\n'
201 def generEVAL(self,obj):
203 Cette méthode convertit un EVAL
204 en une liste de chaines de caractères à la syntaxe python
206 return 'EVAL("""'+ obj.valeur +'""")'
208 def generCOMMENTAIRE(self,obj):
210 Cette méthode convertit un COMMENTAIRE
211 en une liste de chaines de caractères à la syntaxe python
213 # modification pour répondre à la demande de C. Durand, d'éviter
214 # l'ajout systématique d'un dièse, à la suite du commentaire
215 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
217 sans_saut = re.sub("\n$","",obj.valeur)
218 l_lignes = string.split(sans_saut,'\n')
220 for ligne in l_lignes:
221 txt = txt + '#'+ligne+'\n'
223 # suppression du dernier saut de ligne
224 txt = re.sub("\n$","",txt)
227 def generPARAMETRE_EVAL(self,obj):
229 Cette méthode convertit un PARAMETRE_EVAL
230 en une liste de chaines de caractères à la syntaxe python
232 if obj.valeur == None:
233 return obj.nom + ' = None ;\n'
235 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
237 def generITEM_PARAMETRE(self,obj):
240 def generPARAMETRE(self,obj):
242 Cette méthode convertit un PARAMETRE
243 en une liste de chaines de caractères à la syntaxe python
245 if type(obj.valeur) == types.StringType:
246 # PN pour corriger le bug a='3+4' au lieu de a= 3+4
247 #return obj.nom + " = '" + obj.valeur + "';\n"
248 return obj.nom + " = " + obj.valeur + ";\n"
250 return obj.nom + ' = ' + str(obj.valeur) + ';\n'
252 def generETAPE_NIVEAU(self,obj):
254 Cette méthode convertit une étape niveau
255 en une liste de chaines de caractères à la syntaxe python
258 if obj.etapes_niveaux == []:
259 for etape in obj.etapes:
260 l.append(self.generator(etape))
262 for etape_niveau in obj.etapes_niveaux:
263 l.extend(self.generator(etape_niveau))
266 def generETAPE(self,obj):
268 Cette méthode convertit une étape
269 en une liste de chaines de caractères à la syntaxe python
272 sdname= self.generator(obj.sd)
276 label=sdname + '='+obj.definition.nom+'('
278 if obj.reuse != None :
279 str = 'reuse ='+ self.generator(obj.reuse) + ','
281 for v in obj.mc_liste:
282 if isinstance(v,Accas.MCBLOC) :
283 liste=self.generator(v)
286 elif isinstance(v,Accas.MCSIMP) :
287 text=self.generator(v)
288 l.append(v.nom+'='+text)
291 liste=self.generator(v)
292 liste[0]=v.nom+'='+liste[0]
300 def generFORM_ETAPE(self,obj):
302 Méthode particulière pour les objets de type FORMULE
306 if nom == '' : nom = 'sansnom'
307 l.append(nom + ' = FORMULE(')
308 for v in obj.mc_liste:
309 text=self.generator(v)
310 l.append(v.nom+'='+text)
314 def generMACRO_ETAPE(self,obj):
316 Cette méthode convertit une macro-étape
317 en une liste de chaines de caractères à la syntaxe python
323 sdname= self.generator(obj.sd)+'='
327 label = sdname + obj.definition.nom+'('
329 if obj.reuse != None:
330 # XXX faut il la virgule ou pas ????
331 str = "reuse =" + self.generator(obj.reuse) + ','
333 for v in obj.mc_liste:
334 if isinstance(v,Accas.MCBLOC) :
335 liste=self.generator(v)
338 elif isinstance(v,Accas.MCSIMP) :
339 text=self.generator(v)
340 l.append(v.nom+'='+text)
343 liste=self.generator(v)
344 liste[0]=v.nom+'='+liste[0]
353 def generPROC_ETAPE(self,obj):
355 Cette méthode convertit une PROC étape
356 en une liste de chaines de caractères à la syntaxe python
359 label=obj.definition.nom+'('
361 for v in obj.mc_liste:
362 if isinstance(v,Accas.MCBLOC) :
363 liste=self.generator(v)
366 elif isinstance(v,Accas.MCSIMP) :
367 text=self.generator(v)
368 l.append(v.nom+'='+text)
371 liste=self.generator(v)
372 liste[0]=v.nom+'='+liste[0]
381 def generASSD(self,obj):
383 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
386 return obj.get_name()
388 def generMCFACT(self,obj):
390 Convertit un objet MCFACT en une liste de chaines de caractères à la
395 for v in obj.mc_liste:
396 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
397 # on est en présence d'une entite composée : on récupère une liste
398 liste=self.generator(v)
399 liste[0]=v.nom+'='+liste[0]
401 elif isinstance(v,Accas.MCBLOC):
402 liste=self.generator(v)
406 # on est en présence d'un MCSIMP : on récupère une string
407 text =self.generator(v)
408 l.append(v.nom+'='+text)
409 # il faut être plus subtil dans l'ajout de la virgule en différenciant
410 # le cas où elle est obligatoire (si self a des frères cadets
411 # dans self.parent) ou non
412 # (cas où self est seul ou le benjamin de self.parent)
416 def generMCList(self,obj):
418 Convertit un objet MCList en une liste de chaines de caractères à la
421 if len(obj.data) > 1:
423 for mcfact in obj.data: l.append(self.generator(mcfact))
426 l= self.generator(obj.data[0])
429 def generMCBLOC(self,obj):
431 Convertit un objet MCBLOC en une liste de chaines de caractères à la
435 for v in obj.mc_liste:
436 if isinstance(v,Accas.MCBLOC) :
437 liste=self.generator(v)
440 elif isinstance(v,Accas.MCList):
441 liste=self.generator(v)
442 liste[0]=v.nom+'='+liste[0]
446 data=self.generator(v)
447 if type(data) == types.ListType:
448 data[0]=v.nom+'='+data[0]
454 def generMCSIMP(self,obj) :
456 Convertit un objet MCSIMP en une liste de chaines de caractères à la
459 if type(obj.valeur) in (types.TupleType,types.ListType) :
461 for val in obj.valeur :
462 if type(val) == types.InstanceType :
463 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
464 s = s + "CO('"+ self.generator(val) +"')"
465 elif val.__class__.__name__ == 'CO':
466 s = s + "CO('"+ self.generator(val) +"')"
467 elif isinstance(val,Accas.PARAMETRE):
468 # il ne faut pas prendre la string que retourne gener
469 # mais seulement le nom dans le cas d'un paramètre
472 s = s + self.generator(val)
473 elif type(val) == types.FloatType :
474 # Pour un flottant on utilise str qui a une precision de
475 # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
478 clefobj=obj.GetNomConcept()
479 if self.appli.dict_reels.has_key(clefobj):
480 if self.appli.dict_reels[clefobj].has_key(val):
481 s2=self.appli.dict_reels[clefobj][val]
486 # Pour les autres types on utilise repr
489 if len(obj.valeur) > 1:
493 if type(val) == types.InstanceType :
494 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
495 s = "CO('"+ self.generator(val) +"')"
496 elif val.__class__.__name__ == 'CO':
497 s = "CO('"+ self.generator(val) +"')"
498 elif isinstance(val,Accas.PARAMETRE):
499 # il ne faut pas prendre la string que retourne gener
500 # mais seulement le nom dans le cas d'un paramètre
502 elif isinstance(val,Extensions.parametre.PARAMETRE):
505 s = self.generator(val)
506 elif type(val) == types.FloatType :
507 # Pour un flottant on utilise str
508 # ou la notation scientifique
511 clefobj=obj.GetNomConcept()
512 if self.appli.dict_reels.has_key(clefobj):
513 if self.appli.dict_reels[clefobj].has_key(val):
514 s=self.appli.dict_reels[clefobj][val]
518 # Pour les autres types on utilise repr
519 if isinstance(val,Extensions.parametre.PARAMETRE):