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 l.append(nom + ' = FORMULE(')
300 for v in obj.mc_liste:
301 text=self.generator(v)
302 l.append(v.nom+'='+text)
306 def generMACRO_ETAPE(self,obj):
308 Cette méthode convertit une macro-étape
309 en une liste de chaines de caractères à la syntaxe python
311 if obj.definition.nom == 'FORMULE' : return self.gen_formule(obj)
316 sdname= self.generator(obj.sd)+'='
320 label = sdname + obj.definition.nom+'('
322 if obj.reuse != None:
323 # XXX faut il la virgule ou pas ????
324 str = "reuse =" + self.generator(obj.reuse) + ','
326 for v in obj.mc_liste:
327 if isinstance(v,MCBLOC) :
328 liste=self.generator(v)
331 elif isinstance(v,MCSIMP) :
332 text=self.generator(v)
333 l.append(v.nom+'='+text)
336 liste=self.generator(v)
337 liste[0]=v.nom+'='+liste[0]
346 def gen_formule(self,obj):
348 Méthode particuliere aux objets de type FORMULE
354 sdname= self.generator(obj.sd)
358 label=sdname + ' = FORMULE('
360 for v in obj.mc_liste:
362 s= v.nom+':'+sdname+'('+v.valeur+')'
370 def generPROC_ETAPE(self,obj):
372 Cette méthode convertit une PROC étape
373 en une liste de chaines de caractères à la syntaxe python
376 label=obj.definition.nom+'('
378 for v in obj.mc_liste:
379 if isinstance(v,MCBLOC) :
380 liste=self.generator(v)
383 elif isinstance(v,MCSIMP) :
384 text=self.generator(v)
385 l.append(v.nom+'='+text)
388 liste=self.generator(v)
389 liste[0]=v.nom+'='+liste[0]
398 def generASSD(self,obj):
400 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
403 return obj.get_name()
405 def generMCFACT(self,obj):
407 Convertit un objet MCFACT en une liste de chaines de caractères à la
412 for v in obj.mc_liste:
413 if not isinstance(v,MCSIMP) and not isinstance (v,MCBLOC) :
414 # on est en présence d'une entite composée : on récupère une liste
415 liste=self.generator(v)
416 liste[0]=v.nom+'='+liste[0]
418 elif isinstance(v,MCBLOC):
419 liste=self.generator(v)
423 # on est en présence d'un MCSIMP : on récupère une string
424 text =self.generator(v)
425 l.append(v.nom+'='+text)
426 # il faut être plus subtil dans l'ajout de la virgule en différenciant
427 # le cas où elle est obligatoire (si self a des frères cadets
428 # dans self.parent) ou non
429 # (cas où self est seul ou le benjamin de self.parent)
433 def generMCList(self,obj):
435 Convertit un objet MCList en une liste de chaines de caractères à la
441 for mcfact in obj.data:
442 l.append(self.generator(mcfact))
446 def generMCBLOC(self,obj):
448 Convertit un objet MCBLOC en une liste de chaines de caractères à la
452 for v in obj.mc_liste:
453 if isinstance(v,MCBLOC) :
454 liste=self.generator(v)
457 elif isinstance(v,MCList):
458 liste=self.generator(v)
459 liste[0]=v.nom+'='+liste[0]
463 data=self.generator(v)
464 if type(data) == types.ListType:
465 data[0]=v.nom+'='+data[0]
471 def generMCSIMP(self,obj) :
473 Convertit un objet MCSIMP en une liste de chaines de caractères à la
476 if type(obj.valeur) in (types.TupleType,types.ListType) :
478 for val in obj.valeur :
479 if type(val) == types.InstanceType :
480 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
481 s = s + "CO('"+ self.generator(val) +"')"
482 elif val.__class__.__name__ == 'CO':
483 s = s + "CO('"+ self.generator(val) +"')"
484 elif isinstance(val,PARAMETRE):
485 # il ne faut pas prendre la string que retourne gener
486 # mais seulement le nom dans le cas d'un paramètre
489 s = s + self.generator(val)
490 elif type(val) == types.FloatType :
491 # Pour un flottant on utilise str qui a une precision de
492 # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
495 # Pour les autres types on utilise repr
498 if len(obj.valeur) > 1:
502 if type(val) == types.InstanceType :
503 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
504 s = "CO('"+ self.generator(val) +"')"
505 elif val.__class__.__name__ == 'CO':
506 s = "CO('"+ self.generator(val) +"')"
507 elif isinstance(val,PARAMETRE):
508 # il ne faut pas prendre la string que retourne gener
509 # mais seulement le nom dans le cas d'un paramètre
512 s = self.generator(val)
513 elif type(val) == types.FloatType :
514 # Pour un flottant on utilise str
517 # Pour les autres types on utilise repr