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
35 from Extensions.param2 import Formula
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
81 def writefile(self,filename):
86 def gener(self,obj,format='brut'):
88 Retourne une représentation du JDC obj sous une
89 forme qui est paramétrée par format.
90 Si format vaut 'brut', retourne une liste de listes de ...
91 Si format vaut 'standard', retourne un texte obtenu par concaténation de la liste
92 Si format vaut 'beautifie', retourne le meme texte beautifié
94 self.appli=obj.get_jdc_root().appli
96 liste= self.generator(obj)
99 elif format == 'standard':
100 self.text=string.join(liste)
101 elif format == 'beautifie':
102 jdc_formate = Formatage(liste,mode='.py')
103 self.text=jdc_formate.formate_jdc()
105 raise "Format pas implémenté : "+format
108 def generator(self,obj):
110 Cette methode joue un role d'aiguillage en fonction du type de obj
111 On pourrait utiliser les méthodes accept et visitxxx à la
112 place (dépend des gouts !!!)
114 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
116 if isinstance(obj,Accas.PROC_ETAPE):
117 return self.generPROC_ETAPE(obj)
118 # Attention doit etre placé avant MACRO (raison : héritage)
119 elif isinstance(obj,Accas.FORM_ETAPE):
120 return self.generFORM_ETAPE(obj)
121 elif isinstance(obj,Accas.MACRO_ETAPE):
122 return self.generMACRO_ETAPE(obj)
123 elif isinstance(obj,Accas.ETAPE):
124 return self.generETAPE(obj)
125 elif isinstance(obj,Accas.MCFACT):
126 return self.generMCFACT(obj)
127 elif isinstance(obj,Accas.MCList):
128 return self.generMCList(obj)
129 elif isinstance(obj,Accas.MCBLOC):
130 return self.generMCBLOC(obj)
131 elif isinstance(obj,Accas.MCSIMP):
132 return self.generMCSIMP(obj)
133 elif isinstance(obj,Accas.ASSD):
134 return self.generASSD(obj)
135 elif isinstance(obj,Accas.ETAPE_NIVEAU):
136 return self.generETAPE_NIVEAU(obj)
137 elif isinstance(obj,Accas.COMMENTAIRE):
138 return self.generCOMMENTAIRE(obj,premier)
139 # Attention doit etre placé avant PARAMETRE (raison : héritage)
140 elif isinstance(obj,Accas.PARAMETRE_EVAL):
141 return self.generPARAMETRE_EVAL(obj)
142 elif isinstance(obj,Accas.PARAMETRE):
143 return self.generPARAMETRE(obj)
144 elif isinstance(obj,Accas.EVAL):
145 return self.generEVAL(obj)
146 elif isinstance(obj,Accas.COMMANDE_COMM):
147 return self.generCOMMANDE_COMM(obj)
148 elif isinstance(obj,Accas.JDC):
149 return self.generJDC(obj)
150 elif isinstance(obj,Accas.MCNUPLET):
151 return self.generMCNUPLET(obj)
152 elif isinstance(obj,ITEM_PARAMETRE):
153 return self.generITEM_PARAMETRE(obj)
154 elif isinstance(obj,Formula):
155 return self.generFormula(obj)
157 raise "Type d'objet non prévu",obj
160 def generJDC(self,obj):
162 Cette méthode convertit un objet JDC en une liste de chaines de
163 caractères à la syntaxe python
166 if obj.definition.l_niveaux == ():
167 # Il n'y a pas de niveaux
168 for etape in obj.etapes:
169 l.append(self.generator(etape))
172 for etape_niveau in obj.etapes_niveaux:
173 l.extend(self.generator(etape_niveau))
175 # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
176 if type(l[-1])==types.ListType:
177 l[-1][-1] = l[-1][-1]+'\n'
178 elif type(l[-1])==types.StringType:
182 def generMCNUPLET(self,obj):
184 Méthode générant une représentation de self permettant son ecriture
185 dans le format python
189 for v in obj.mc_liste:
190 text = re.sub(".*=","",self.generator(v))
195 def generCOMMANDE_COMM(self,obj):
197 Cette méthode convertit un COMMANDE_COMM
198 en une liste de chaines de caractères à la syntaxe python
200 l_lignes = string.split(obj.valeur,'\n')
202 for ligne in l_lignes:
203 txt = txt + '##'+ligne+'\n'
206 def generEVAL(self,obj):
208 Cette méthode convertit un EVAL
209 en une liste de chaines de caractères à la syntaxe python
211 return 'EVAL("""'+ obj.valeur +'""")'
213 def generCOMMENTAIRE(self,obj,premier=0):
215 Cette méthode convertit un COMMENTAIRE
216 en une liste de chaines de caractères à la syntaxe python
218 # modification pour répondre à la demande de C. Durand, d'éviter
219 # l'ajout systématique d'un dièse, à la suite du commentaire
220 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
222 sans_saut = re.sub("\n$","",obj.valeur)
223 l_lignes = string.split(sans_saut,'\n')
226 for ligne in l_lignes:
227 txt = txt + '#'+ligne+'\n'
229 # suppression du dernier saut de ligne
230 txt = re.sub("\n$","",txt)
231 # on ajoute un saut de ligne avant
232 pattern=re.compile(" ?\#")
234 if m and not premier:
238 def generPARAMETRE_EVAL(self,obj):
240 Cette méthode convertit un PARAMETRE_EVAL
241 en une liste de chaines de caractères à la syntaxe python
243 if obj.valeur == None:
244 return obj.nom + ' = None ;\n'
246 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
248 def generITEM_PARAMETRE(self,obj):
251 def generFormula(self,obj):
255 def generPARAMETRE(self,obj):
257 Cette méthode convertit un PARAMETRE
258 en une liste de chaines de caractères à la syntaxe python
260 return repr(obj) + ";\n"
262 def generETAPE_NIVEAU(self,obj):
264 Cette méthode convertit une étape niveau
265 en une liste de chaines de caractères à la syntaxe python
268 if obj.etapes_niveaux == []:
269 for etape in obj.etapes:
270 l.append(self.generator(etape))
272 for etape_niveau in obj.etapes_niveaux:
273 l.extend(self.generator(etape_niveau))
276 def generETAPE(self,obj):
278 Cette méthode convertit une étape
279 en une liste de chaines de caractères à la syntaxe python
282 sdname= self.generator(obj.sd)
286 label=sdname + '='+obj.definition.nom+'('
288 if obj.reuse != None :
289 str = 'reuse ='+ self.generator(obj.reuse) + ','
291 for v in obj.mc_liste:
292 if isinstance(v,Accas.MCBLOC) :
293 liste=self.generator(v)
296 elif isinstance(v,Accas.MCSIMP) :
297 text=self.generator(v)
298 l.append(v.nom+'='+text)
301 liste=self.generator(v)
302 liste[0]=v.nom+'='+liste[0]
310 def generFORM_ETAPE(self,obj):
312 Méthode particulière pour les objets de type FORMULE
316 if nom == '' : nom = 'sansnom'
317 l.append(nom + ' = FORMULE(')
318 for v in obj.mc_liste:
319 text=self.generator(v)
320 l.append(v.nom+'='+text)
324 def generMACRO_ETAPE(self,obj):
326 Cette méthode convertit une macro-étape
327 en une liste de chaines de caractères à la syntaxe python
333 sdname= self.generator(obj.sd)+'='
337 label = sdname + obj.definition.nom+'('
339 if obj.reuse != None:
340 # XXX faut il la virgule ou pas ????
341 str = "reuse =" + self.generator(obj.reuse) + ','
343 for v in obj.mc_liste:
344 if isinstance(v,Accas.MCBLOC) :
345 liste=self.generator(v)
348 elif isinstance(v,Accas.MCSIMP) :
349 text=self.generator(v)
350 l.append(v.nom+'='+text)
353 liste=self.generator(v)
354 liste[0]=v.nom+'='+liste[0]
363 def generPROC_ETAPE(self,obj):
365 Cette méthode convertit une PROC étape
366 en une liste de chaines de caractères à la syntaxe python
369 label=obj.definition.nom+'('
371 for v in obj.mc_liste:
372 if isinstance(v,Accas.MCBLOC) :
373 liste=self.generator(v)
376 elif isinstance(v,Accas.MCSIMP) :
377 text=self.generator(v)
378 l.append(v.nom+'='+text)
381 liste=self.generator(v)
382 liste[0]=v.nom+'='+liste[0]
391 def generASSD(self,obj):
393 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
396 return obj.get_name()
398 def generMCFACT(self,obj):
400 Convertit un objet MCFACT en une liste de chaines de caractères à la
405 for v in obj.mc_liste:
406 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
407 # on est en présence d'une entite composée : on récupère une liste
408 liste=self.generator(v)
409 liste[0]=v.nom+'='+liste[0]
411 elif isinstance(v,Accas.MCBLOC):
412 liste=self.generator(v)
416 # on est en présence d'un MCSIMP : on récupère une string
417 text =self.generator(v)
418 l.append(v.nom+'='+text)
419 # il faut être plus subtil dans l'ajout de la virgule en différenciant
420 # le cas où elle est obligatoire (si self a des frères cadets
421 # dans self.parent) ou non
422 # (cas où self est seul ou le benjamin de self.parent)
426 def generMCList(self,obj):
428 Convertit un objet MCList en une liste de chaines de caractères à la
431 if len(obj.data) > 1:
433 for mcfact in obj.data: l.append(self.generator(mcfact))
436 l= self.generator(obj.data[0])
439 def generMCBLOC(self,obj):
441 Convertit un objet MCBLOC en une liste de chaines de caractères à la
445 for v in obj.mc_liste:
446 if isinstance(v,Accas.MCBLOC) :
447 liste=self.generator(v)
450 elif isinstance(v,Accas.MCFACT):
451 liste=self.generator(v)
452 elif isinstance(v,Accas.MCList):
453 liste=self.generator(v)
454 liste[0]=v.nom+'='+liste[0]
455 # PN essai de correction bug identation
456 if (hasattr(v,'data')) :
457 if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
466 data=self.generator(v)
467 if type(data) == types.ListType:
468 data[0]=v.nom+'='+data[0]
474 def format_item(self,valeur,etape):
475 if type(valeur) == types.InstanceType :
476 if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
477 s = "CO('"+ self.generator(valeur) +"')"
478 elif isinstance(valeur,Accas.PARAMETRE):
479 # il ne faut pas prendre la string que retourne gener
480 # mais seulement le nom dans le cas d'un paramètre
483 s = self.generator(valeur)
484 elif type(valeur) == types.FloatType :
485 # Pour un flottant on utilise str
486 # ou la notation scientifique
488 clefobj=etape.get_sdname()
489 if self.appli.dict_reels.has_key(clefobj):
490 if self.appli.dict_reels[clefobj].has_key(valeur):
491 s=self.appli.dict_reels[clefobj][valeur]
492 elif type(valeur) == types.StringType :
493 if valeur.find('\n') == -1:
494 # pas de retour chariot, on utilise repr
496 elif valeur.find('"""') == -1:
497 # retour chariot mais pas de triple ", on formatte
502 # Pour les autres types on utilise repr
507 def generMCSIMP(self,obj) :
509 Convertit un objet MCSIMP en une liste de chaines de caractères à la
512 if type(obj.valeur) in (types.TupleType,types.ListType) :
514 for val in obj.valeur :
515 s =s +self.format_item(val,obj.etape) + ','
516 if len(obj.valeur) > 1:
518 if obj.nbrColonnes() :
519 s=self.formatColonnes(obj.nbrColonnes(),s)
521 s=self.format_item(obj.valeur,obj.etape) + ','
525 def formatColonnes(self,nbrColonnes,text):
528 liste=text.split(",")
531 while ( indice < len(liste) -2 ) :
532 for l in range(nbrColonnes) :
533 textformat=textformat+liste[indice]+","
535 textformat=textformat+"\n"
536 textformat=textformat+"),"