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 return obj.nom + " = '" + obj.valeur + "';\n"
239 return obj.nom + ' = ' + str(obj.valeur) + ';\n'
241 def generETAPE_NIVEAU(self,obj):
243 Cette méthode convertit une étape niveau
244 en une liste de chaines de caractères à la syntaxe python
247 if obj.etapes_niveaux == []:
248 for etape in obj.etapes:
249 l.append(self.generator(etape))
251 for etape_niveau in obj.etapes_niveaux:
252 l.extend(self.generator(etape_niveau))
255 def generETAPE(self,obj):
257 Cette méthode convertit une étape
258 en une liste de chaines de caractères à la syntaxe python
261 sdname= self.generator(obj.sd)
265 label=sdname + '='+obj.definition.nom+'('
267 if obj.reuse != None :
268 str = 'reuse ='+ self.generator(obj.reuse) + ','
270 for v in obj.mc_liste:
271 if isinstance(v,MCBLOC) :
272 liste=self.generator(v)
275 elif isinstance(v,MCSIMP) :
276 text=self.generator(v)
277 l.append(v.nom+'='+text)
280 liste=self.generator(v)
281 liste[0]=v.nom+'='+liste[0]
289 def generFORM_ETAPE(self,obj):
291 Méthode particulière pour les objets de type FORMULE
295 if nom == '' : nom = 'sansnom'
296 if len(obj.mc_liste)>0:
297 l.append(nom + ' = FORMULE(')
298 s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''"
302 l.append(nom+' = FORMULE();')
305 def generMACRO_ETAPE(self,obj):
307 Cette méthode convertit une macro-étape
308 en une liste de chaines de caractères à la syntaxe python
310 if obj.definition.nom == 'FORMULE' : return self.gen_formule(obj)
315 sdname= self.generator(obj.sd)+'='
319 label = sdname + obj.definition.nom+'('
321 if obj.reuse != None:
322 # XXX faut il la virgule ou pas ????
323 str = "reuse =" + self.generator(obj.reuse) + ','
325 for v in obj.mc_liste:
326 if isinstance(v,MCBLOC) :
327 liste=self.generator(v)
330 elif isinstance(v,MCSIMP) :
331 text=self.generator(v)
332 l.append(v.nom+'='+text)
335 liste=self.generator(v)
336 liste[0]=v.nom+'='+liste[0]
345 def gen_formule(self,obj):
347 Méthode particuliere aux objets de type FORMULE
353 sdname= self.generator(obj.sd)
357 label=sdname + ' = FORMULE('
359 for v in obj.mc_liste:
361 s= v.nom+':'+sdname+'('+v.valeur+')'
369 def generPROC_ETAPE(self,obj):
371 Cette méthode convertit une PROC étape
372 en une liste de chaines de caractères à la syntaxe python
375 label=obj.definition.nom+'('
377 for v in obj.mc_liste:
378 if isinstance(v,MCBLOC) :
379 liste=self.generator(v)
382 elif isinstance(v,MCSIMP) :
383 text=self.generator(v)
384 l.append(v.nom+'='+text)
387 liste=self.generator(v)
388 liste[0]=v.nom+'='+liste[0]
397 def generASSD(self,obj):
399 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
402 return obj.get_name()
404 def generMCFACT(self,obj):
406 Convertit un objet MCFACT en une liste de chaines de caractères à la
411 for v in obj.mc_liste:
412 if not isinstance(v,MCSIMP) and not isinstance (v,MCBLOC) :
413 # on est en présence d'une entite composée : on récupère une liste
414 liste=self.generator(v)
415 liste[0]=v.nom+'='+liste[0]
417 elif isinstance(v,MCBLOC):
418 liste=self.generator(v)
422 # on est en présence d'un MCSIMP : on récupère une string
423 text =self.generator(v)
424 l.append(v.nom+'='+text)
425 # il faut être plus subtil dans l'ajout de la virgule en différenciant
426 # le cas où elle est obligatoire (si self a des frères cadets
427 # dans self.parent) ou non
428 # (cas où self est seul ou le benjamin de self.parent)
432 def generMCList(self,obj):
434 Convertit un objet MCList en une liste de chaines de caractères à la
440 for mcfact in obj.data:
441 l.append(self.generator(mcfact))
445 def generMCBLOC(self,obj):
447 Convertit un objet MCBLOC en une liste de chaines de caractères à la
451 for v in obj.mc_liste:
452 if isinstance(v,MCBLOC) :
453 liste=self.generator(v)
456 elif isinstance(v,MCList):
457 liste=self.generator(v)
458 liste[0]=v.nom+'='+liste[0]
462 data=self.generator(v)
463 if type(data) == types.ListType:
464 data[0]=v.nom+'='+data[0]
470 def generMCSIMP(self,obj) :
472 Convertit un objet MCSIMP en une liste de chaines de caractères à la
475 if type(obj.valeur) in (types.TupleType,types.ListType) :
477 for val in obj.valeur :
478 if type(val) == types.InstanceType :
479 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
480 s = s + "CO('"+ self.generator(val) +"')"
481 elif val.__class__.__name__ == 'CO':
482 s = s + "CO('"+ self.generator(val) +"')"
483 elif isinstance(val,PARAMETRE):
484 # il ne faut pas prendre la string que retourne gener
485 # mais seulement le nom dans le cas d'un paramètre
488 s = s + self.generator(val)
489 elif type(val) == types.FloatType :
490 # Pour un flottant on utilise str qui a une precision de
491 # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
494 # Pour les autres types on utilise repr
497 if len(obj.valeur) > 1:
501 if type(val) == types.InstanceType :
502 if hasattr(obj.etape,'sdprods') and val in obj.etape.sdprods :
503 s = "CO('"+ self.generator(val) +"')"
504 elif val.__class__.__name__ == 'CO':
505 s = "CO('"+ self.generator(val) +"')"
506 elif isinstance(val,PARAMETRE):
507 # il ne faut pas prendre la string que retourne gener
508 # mais seulement le nom dans le cas d'un paramètre
511 s = self.generator(val)
512 elif type(val) == types.FloatType :
513 # Pour un flottant on utilise str
516 # Pour les autres types on utilise repr