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',config=None):
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)
115 if isinstance(obj,Accas.PROC_ETAPE):
116 return self.generPROC_ETAPE(obj)
117 # Attention doit etre placé avant MACRO (raison : héritage)
118 elif isinstance(obj,Accas.FORM_ETAPE):
119 return self.generFORM_ETAPE(obj)
120 elif isinstance(obj,Accas.MACRO_ETAPE):
121 return self.generMACRO_ETAPE(obj)
122 elif isinstance(obj,Accas.ETAPE):
123 return self.generETAPE(obj)
124 elif isinstance(obj,Accas.MCFACT):
125 return self.generMCFACT(obj)
126 elif isinstance(obj,Accas.MCList):
127 return self.generMCList(obj)
128 elif isinstance(obj,Accas.MCBLOC):
129 return self.generMCBLOC(obj)
130 elif isinstance(obj,Accas.MCSIMP):
131 return self.generMCSIMP(obj)
132 elif isinstance(obj,Accas.ASSD):
133 return self.generASSD(obj)
134 elif isinstance(obj,Accas.ETAPE_NIVEAU):
135 return self.generETAPE_NIVEAU(obj)
136 elif isinstance(obj,Accas.COMMENTAIRE):
137 return self.generCOMMENTAIRE(obj)
138 # Attention doit etre placé avant PARAMETRE (raison : héritage)
139 elif isinstance(obj,Accas.PARAMETRE_EVAL):
140 return self.generPARAMETRE_EVAL(obj)
141 elif isinstance(obj,Accas.PARAMETRE):
142 return self.generPARAMETRE(obj)
143 elif isinstance(obj,Accas.EVAL):
144 return self.generEVAL(obj)
145 elif isinstance(obj,Accas.COMMANDE_COMM):
146 return self.generCOMMANDE_COMM(obj)
147 elif isinstance(obj,Accas.JDC):
148 return self.generJDC(obj)
149 elif isinstance(obj,Accas.MCNUPLET):
150 return self.generMCNUPLET(obj)
151 elif isinstance(obj,ITEM_PARAMETRE):
152 return self.generITEM_PARAMETRE(obj)
153 elif isinstance(obj,Formula):
154 return self.generFormula(obj)
156 raise "Type d'objet non prevu",obj
158 def generJDC(self,obj):
160 Cette méthode convertit un objet JDC en une liste de chaines de
161 caractères à la syntaxe python
164 if obj.definition.l_niveaux == ():
165 # Il n'y a pas de niveaux
166 for etape in obj.etapes:
167 l.append(self.generator(etape))
170 for etape_niveau in obj.etapes_niveaux:
171 l.extend(self.generator(etape_niveau))
173 # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
174 if type(l[-1])==types.ListType:
175 l[-1][-1] = l[-1][-1]+'\n'
176 elif type(l[-1])==types.StringType:
180 def generMCNUPLET(self,obj):
182 Méthode générant une représentation de self permettant son ecriture
183 dans le format python
187 for v in obj.mc_liste:
188 text = re.sub(".*=","",self.generator(v))
193 def generCOMMANDE_COMM(self,obj):
195 Cette méthode convertit un COMMANDE_COMM
196 en une liste de chaines de caractères à la syntaxe python
198 l_lignes = string.split(obj.valeur,'\n')
200 for ligne in l_lignes:
201 txt = txt + '##'+ligne+'\n'
204 def generEVAL(self,obj):
206 Cette méthode convertit un EVAL
207 en une liste de chaines de caractères à la syntaxe python
209 return 'EVAL("""'+ obj.valeur +'""")'
211 def generCOMMENTAIRE(self,obj):
213 Cette méthode convertit un COMMENTAIRE
214 en une liste de chaines de caractères à la syntaxe python
216 # modification pour répondre à la demande de C. Durand, d'éviter
217 # l'ajout systématique d'un dièse, à la suite du commentaire
218 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
220 sans_saut = re.sub("\n$","",obj.valeur)
221 l_lignes = string.split(sans_saut,'\n')
224 for ligne in l_lignes:
225 txt = txt + '#'+ligne+'\n'
227 # suppression du dernier saut de ligne
228 #txt = re.sub("\n$","",txt)
229 # on ajoute un saut de ligne avant
230 pattern=re.compile(" ?\#")
236 def generPARAMETRE_EVAL(self,obj):
238 Cette méthode convertit un PARAMETRE_EVAL
239 en une liste de chaines de caractères à la syntaxe python
241 if obj.valeur == None:
242 return obj.nom + ' = None ;\n'
244 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
246 def generITEM_PARAMETRE(self,obj):
249 def generFormula(self,obj):
253 def generPARAMETRE(self,obj):
255 Cette méthode convertit un PARAMETRE
256 en une liste de chaines de caractères à la syntaxe python
258 return repr(obj) + ";\n"
260 def generETAPE_NIVEAU(self,obj):
262 Cette méthode convertit une étape niveau
263 en une liste de chaines de caractères à la syntaxe python
266 if obj.etapes_niveaux == []:
267 for etape in obj.etapes:
268 l.append(self.generator(etape))
270 for etape_niveau in obj.etapes_niveaux:
271 l.extend(self.generator(etape_niveau))
274 def generETAPE(self,obj):
276 Cette méthode convertit une étape
277 en une liste de chaines de caractères à la syntaxe python
280 sdname= self.generator(obj.sd)
284 label=sdname + '='+obj.definition.nom+'('
286 if obj.reuse != None :
287 str = 'reuse ='+ self.generator(obj.reuse) + ','
289 for v in obj.mc_liste:
290 if isinstance(v,Accas.MCBLOC) :
291 liste=self.generator(v)
294 elif isinstance(v,Accas.MCSIMP) :
295 text=self.generator(v)
296 l.append(v.nom+'='+text)
299 liste=self.generator(v)
300 liste[0]=v.nom+'='+liste[0]
308 def generFORM_ETAPE(self,obj):
310 Méthode particulière pour les objets de type FORMULE
314 if nom == '' : nom = 'sansnom'
315 l.append(nom + ' = FORMULE(')
316 for v in obj.mc_liste:
317 text=self.generator(v)
318 l.append(v.nom+'='+text)
322 def generMACRO_ETAPE(self,obj):
324 Cette méthode convertit une macro-étape
325 en une liste de chaines de caractères à la syntaxe python
331 sdname= self.generator(obj.sd)+'='
335 label = sdname + obj.definition.nom+'('
337 if obj.reuse != None:
338 # XXX faut il la virgule ou pas ????
339 str = "reuse =" + self.generator(obj.reuse) + ','
341 for v in obj.mc_liste:
342 if isinstance(v,Accas.MCBLOC) :
343 liste=self.generator(v)
346 elif isinstance(v,Accas.MCSIMP) :
347 text=self.generator(v)
348 l.append(v.nom+'='+text)
351 liste=self.generator(v)
352 liste[0]=v.nom+'='+liste[0]
361 def generPROC_ETAPE(self,obj):
363 Cette méthode convertit une PROC étape
364 en une liste de chaines de caractères à la syntaxe python
367 label=obj.definition.nom+'('
369 for v in obj.mc_liste:
370 if isinstance(v,Accas.MCBLOC) :
371 liste=self.generator(v)
374 elif isinstance(v,Accas.MCSIMP) :
375 text=self.generator(v)
376 l.append(v.nom+'='+text)
379 liste=self.generator(v)
380 liste[0]=v.nom+'='+liste[0]
389 def generASSD(self,obj):
391 Convertit un objet dérivé d'ASSD en une chaine de caractères à la
394 return obj.get_name()
396 def generMCFACT(self,obj):
398 Convertit un objet MCFACT en une liste de chaines de caractères à la
403 for v in obj.mc_liste:
404 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
405 # on est en présence d'une entite composée : on récupère une liste
406 liste=self.generator(v)
407 liste[0]=v.nom+'='+liste[0]
409 elif isinstance(v,Accas.MCBLOC):
410 liste=self.generator(v)
414 # on est en présence d'un MCSIMP : on récupère une string
415 text =self.generator(v)
416 l.append(v.nom+'='+text)
417 # il faut être plus subtil dans l'ajout de la virgule en différenciant
418 # le cas où elle est obligatoire (si self a des frères cadets
419 # dans self.parent) ou non
420 # (cas où self est seul ou le benjamin de self.parent)
424 def generMCList(self,obj):
426 Convertit un objet MCList en une liste de chaines de caractères à la
429 if len(obj.data) > 1:
431 for mcfact in obj.data: l.append(self.generator(mcfact))
434 l= self.generator(obj.data[0])
437 def generMCBLOC(self,obj):
439 Convertit un objet MCBLOC en une liste de chaines de caractères à la
443 for v in obj.mc_liste:
444 if isinstance(v,Accas.MCBLOC) :
445 liste=self.generator(v)
448 elif isinstance(v,Accas.MCFACT):
449 liste=self.generator(v)
450 elif isinstance(v,Accas.MCList):
451 liste=self.generator(v)
452 liste[0]=v.nom+'='+liste[0]
453 # PN essai de correction bug identation
454 if (hasattr(v,'data')) :
455 if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
464 data=self.generator(v)
465 if type(data) == types.ListType:
466 data[0]=v.nom+'='+data[0]
473 def format_item(self,valeur,etape):
474 if type(valeur) == types.FloatType :
475 # Pour un flottant on utilise str
476 # ou la notation scientifique
478 clefobj=etape.get_sdname()
479 if self.appli.appliEficas and self.appli.appliEficas.dict_reels.has_key(clefobj):
480 if self.appli.appliEficas.dict_reels[clefobj].has_key(valeur):
481 s=self.appli.appliEficas.dict_reels[clefobj][valeur]
482 elif type(valeur) == types.StringType :
483 if valeur.find('\n') == -1:
484 # pas de retour chariot, on utilise repr
486 elif valeur.find('"""') == -1:
487 # retour chariot mais pas de triple ", on formatte
491 elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods:
492 s = "CO('"+ self.generator(valeur) +"')"
493 elif isinstance(valeur,Accas.ASSD):
494 s = self.generator(valeur)
495 elif isinstance(valeur,Accas.PARAMETRE):
496 # il ne faut pas prendre la string que retourne gener
497 # mais seulement le nom dans le cas d'un paramètre
500 #elif type(valeur) == types.InstanceType or isinstance(valeur,object):
501 # if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
502 # s = "CO('"+ self.generator(valeur) +"')"
503 # elif isinstance(valeur,Accas.PARAMETRE):
504 # il ne faut pas prendre la string que retourne gener
505 # mais seulement le nom dans le cas d'un paramètre
509 # s = self.generator(valeur)
512 # Pour les autres types on utilise repr
516 def generMCSIMP(self,obj) :
518 Convertit un objet MCSIMP en une liste de chaines de caractères à la
522 if type(obj.valeur) in (types.TupleType,types.ListType) :
524 for ss_type in obj.definition.type:
525 if repr(ss_type).find('Tuple') != -1 :
530 s = str(obj.valeur) +','
532 for val in obj.valeur :
533 s =s +self.format_item(val,obj.etape) + ','
534 if len(obj.valeur) > 1:
536 if obj.nbrColonnes() :
537 s=self.formatColonnes(obj.nbrColonnes(),s)
539 s=self.format_item(obj.valeur,obj.etape) + ','
543 def formatColonnes(self,nbrColonnes,text):
546 liste=text.split(",")
549 while ( indice < len(liste) -2 ) :
550 for l in range(nbrColonnes) :
551 textformat=textformat+liste[indice]+","
553 textformat=textformat+"\n"
554 textformat=textformat+"),"