1 # CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
21 Ce module contient le plugin generateur de fichier au format
26 import types,string,re
28 from Noyau import N_CR
29 from Noyau.N_utils import repr_float
30 from Accas import ETAPE,PROC_ETAPE,MACRO_ETAPE,ETAPE_NIVEAU,JDC,FORM_ETAPE
31 from Accas import MCSIMP,MCFACT,MCBLOC,MCList,EVAL
32 from Accas import GEOM,ASSD,MCNUPLET
33 from Accas import COMMENTAIRE,PARAMETRE, PARAMETRE_EVAL,COMMANDE_COMM
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
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 liste= self.generator(obj)
95 elif format == 'standard':
96 self.text=string.join(liste)
97 elif format == 'beautifie':
98 jdc_formate = Formatage(liste,mode='.py')
99 self.text=jdc_formate.formate_jdc()
101 raise "Format pas implémenté : "+format
104 def generator(self,obj):
106 Cette methode joue un role d'aiguillage en fonction du type de obj
107 On pourrait utiliser les méthodes accept et visitxxx à la
108 place (dépend des gouts !!!)
110 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
111 if isinstance(obj,PROC_ETAPE):
112 return self.generPROC_ETAPE(obj)
113 elif isinstance(obj,MACRO_ETAPE):
114 return self.generMACRO_ETAPE(obj)
115 elif isinstance(obj,FORM_ETAPE):
116 return self.generFORM_ETAPE(obj)
117 elif isinstance(obj,ETAPE):
118 return self.generETAPE(obj)
119 elif isinstance(obj,MCFACT):
120 return self.generMCFACT(obj)
121 elif isinstance(obj,MCList):
122 return self.generMCList(obj)
123 elif isinstance(obj,MCBLOC):
124 return self.generMCBLOC(obj)
125 elif isinstance(obj,MCSIMP):
126 return self.generMCSIMP(obj)
127 elif isinstance(obj,ASSD):
128 return self.generASSD(obj)
129 elif isinstance(obj,ETAPE_NIVEAU):
130 return self.generETAPE_NIVEAU(obj)
131 elif isinstance(obj,COMMENTAIRE):
132 return self.generCOMMENTAIRE(obj)
133 # Attention doit etre placé avant PARAMETRE (raison : héritage)
134 elif isinstance(obj,PARAMETRE_EVAL):
135 return self.generPARAMETRE_EVAL(obj)
136 elif isinstance(obj,PARAMETRE):
137 return self.generPARAMETRE(obj)
138 elif isinstance(obj,EVAL):
139 return self.generEVAL(obj)
140 elif isinstance(obj,COMMANDE_COMM):
141 return self.generCOMMANDE_COMM(obj)
142 elif isinstance(obj,JDC):
143 return self.generJDC(obj)
144 elif isinstance(obj,MCNUPLET):
145 return self.generMCNUPLET(obj)
147 raise "Type d'objet non prévu",obj
149 def generJDC(self,obj):
151 Cette méthode convertit un objet JDC en une liste de chaines de
152 caractères à la syntaxe python
155 if obj.definition.l_niveaux == ():
156 # Il n'y a pas de niveaux
157 for etape in obj.etapes:
158 l.append(self.generator(etape))
161 for etape_niveau in obj.etapes_niveaux:
162 l.extend(self.generator(etape_niveau))
164 # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
165 if type(l[-1])==types.ListType:
166 l[-1][-1] = l[-1][-1]+'\n'
167 elif type(l[-1])==types.StringType:
171 def generMCNUPLET(self,obj):
173 Méthode générant une représentation de self permettant son ecriture
174 dans le format python
178 for v in obj.mc_liste:
179 text = re.sub(".*=","",self.generator(v))
184 def generCOMMANDE_COMM(self,obj):
186 Cette méthode convertit un COMMANDE_COMM
187 en une liste de chaines de caractères à la syntaxe python
189 l_lignes = string.split(obj.valeur,'\n')
191 for ligne in l_lignes:
192 txt = txt + '##'+ligne+'\n'
195 def generEVAL(self,obj):
197 Cette méthode convertit un EVAL
198 en une liste de chaines de caractères à la syntaxe python
200 return 'EVAL("""'+ obj.valeur +'""")'
202 def generCOMMENTAIRE(self,obj):
204 Cette méthode convertit un COMMENTAIRE
205 en une liste de chaines de caractères à la syntaxe python
207 # modification pour répondre à la demande de C. Durand, d'éviter
208 # l'ajout systématique d'un dièse, à la suite du commentaire
209 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
211 sans_saut = re.sub("\n$","",obj.valeur)
212 l_lignes = string.split(sans_saut,'\n')
214 for ligne in l_lignes:
215 txt = txt + '#'+ligne+'\n'
217 # suppression du dernier saut de ligne
218 txt = re.sub("\n$","",txt)
221 def generPARAMETRE_EVAL(self,obj):
223 Cette méthode convertit un PARAMETRE_EVAL
224 en une liste de chaines de caractères à la syntaxe python
226 if obj.valeur == None:
227 return obj.nom + ' = None ;\n'
229 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
231 def generPARAMETRE(self,obj):
233 Cette méthode convertit un PARAMETRE
234 en une liste de chaines de caractères à la syntaxe python
236 if type(obj.valeur) == types.StringType:
237 # PN pour corriger le bug a='3+4' au lieu de a= 3+4
238 #return obj.nom + " = '" + obj.valeur + "';\n"
239 return obj.nom + " = " + obj.valeur + ";\n"
241 return obj.nom + ' = ' + str(obj.valeur) + ';\n'
243 def generETAPE_NIVEAU(self,obj):
245 Cette méthode convertit une étape niveau
246 en une liste de chaines de caractères à la syntaxe python
249 if obj.etapes_niveaux == []:
250 for etape in obj.etapes:
251 l.append(self.generator(etape))
253 for etape_niveau in obj.etapes_niveaux:
254 l.extend(self.generator(etape_niveau))
257 def generETAPE(self,obj):
259 Cette méthode convertit une étape
260 en une liste de chaines de caractères à la syntaxe python
263 sdname= self.generator(obj.sd)
267 label=sdname + '='+obj.definition.nom+'('
269 if obj.reuse != None :
270 str = 'reuse ='+ self.generator(obj.reuse) + ','
272 for v in obj.mc_liste:
273 if isinstance(v,MCBLOC) :
274 liste=self.generator(v)
277 elif isinstance(v,MCSIMP) :
278 text=self.generator(v)
279 l.append(v.nom+'='+text)
282 liste=self.generator(v)
283 liste[0]=v.nom+'='+liste[0]
291 def generFORM_ETAPE(self,obj):
293 Méthode particulière pour les objets de type FORMULE
297 if nom == '' : nom = 'sansnom'
298 if len(obj.mc_liste)>0:
299 l.append(nom + ' = FORMULE(')
300 s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''"
304 l.append(nom+' = FORMULE();')
307 def generMACRO_ETAPE(self,obj):
309 Cette méthode convertit une macro-étape
310 en une liste de chaines de caractères à la syntaxe python
312 if obj.definition.nom == 'FORMULE' : return self.gen_formule(obj)
317 sdname= self.generator(obj.sd)+'='
321 label = sdname + obj.definition.nom+'('
323 if obj.reuse != None:
324 # XXX faut il la virgule ou pas ????
325 str = "reuse =" + self.generator(obj.reuse) + ','
327 for v in obj.mc_liste:
328 if isinstance(v,MCBLOC) :
329 liste=self.generator(v)
332 elif isinstance(v,MCSIMP) :
333 text=self.generator(v)
334 l.append(v.nom+'='+text)
337 liste=self.generator(v)
338 liste[0]=v.nom+'='+liste[0]
347 def gen_formule(self,obj):
349 Méthode particuliere aux objets de type FORMULE
355 sdname= self.generator(obj.sd)
359 label=sdname + ' = FORMULE('
361 for v in obj.mc_liste:
363 s= v.nom+':'+sdname+'('+v.valeur+')'
371 def generPROC_ETAPE(self,obj):
373 Cette méthode convertit une PROC étape
374 en une liste de chaines de caractères à la syntaxe python
377 label=obj.definition.nom+'('
379 for v in obj.mc_liste:
380 if isinstance(v,MCBLOC) :
381 liste=self.generator(v)
384 elif isinstance(v,MCSIMP) :
385 text=self.generator(v)
386 l.append(v.nom+'='+text)
389 liste=self.generator(v)
390 liste[0]=v.nom+'='+liste[0]
399 def generASSD(self,obj):
401 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
404 return obj.get_name()
406 def generMCFACT(self,obj):
408 Convertit un objet MCFACT en une liste de chaines de caractères à la
413 for v in obj.mc_liste:
414 if not isinstance(v,MCSIMP) and not isinstance (v,MCBLOC) :
415 # on est en présence d'une entite composée : on récupère une liste
416 liste=self.generator(v)
417 liste[0]=v.nom+'='+liste[0]
419 elif isinstance(v,MCBLOC):
420 liste=self.generator(v)
424 # on est en présence d'un MCSIMP : on récupère une string
425 text =self.generator(v)
426 l.append(v.nom+'='+text)
427 # il faut être plus subtil dans l'ajout de la virgule en différenciant
428 # le cas où elle est obligatoire (si self a des frères cadets
429 # dans self.parent) ou non
430 # (cas où self est seul ou le benjamin de self.parent)
434 def generMCList(self,obj):
436 Convertit un objet MCList en une liste de chaines de caractères à la
442 for mcfact in obj.data:
443 l.append(self.generator(mcfact))
447 def generMCBLOC(self,obj):
449 Convertit un objet MCBLOC en une liste de chaines de caractères à la
453 for v in obj.mc_liste:
454 if isinstance(v,MCBLOC) :
455 liste=self.generator(v)
458 elif isinstance(v,MCList):
459 liste=self.generator(v)
460 liste[0]=v.nom+'='+liste[0]
464 data=self.generator(v)
465 if type(data) == types.ListType:
466 data[0]=v.nom+'='+data[0]
472 def generMCSIMP(self,obj) :
474 Convertit un objet MCSIMP en une liste de chaines de caractères à la
477 if type(obj.valeur) in (types.TupleType,types.ListType) :
479 for val in obj.valeur :
480 if type(val) == types.InstanceType :
481 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
482 s = s + "CO('"+ self.generator(val) +"')"
483 elif val.__class__.__name__ == 'CO':
484 s = s + "CO('"+ self.generator(val) +"')"
485 elif isinstance(val,PARAMETRE):
486 # il ne faut pas prendre la string que retourne gener
487 # mais seulement le nom dans le cas d'un paramètre
490 s = s + self.generator(val)
491 elif type(val) == types.FloatType :
492 # Pour un flottant on utilise str qui a une precision de
493 # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
496 # Pour les autres types on utilise repr
499 if len(obj.valeur) > 1:
503 if type(val) == types.InstanceType :
504 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
505 s = "CO('"+ self.generator(val) +"')"
506 elif val.__class__.__name__ == 'CO':
507 s = "CO('"+ self.generator(val) +"')"
508 elif isinstance(val,PARAMETRE):
509 # il ne faut pas prendre la string que retourne gener
510 # mais seulement le nom dans le cas d'un paramètre
513 s = self.generator(val)
514 elif type(val) == types.FloatType :
515 # Pour un flottant on utilise str
518 # Pour les autres types on utilise repr