1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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
32 from Extensions.parametre import ITEM_PARAMETRE
33 from Formatage import Formatage
34 from Extensions.param2 import Formula
38 Retourne les informations necessaires pour le chargeur de plugins
40 Ces informations sont retournees dans un dictionnaire
45 # La factory pour creer 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 realises par la methode
56 generator.gener(objet_jdc,format)
58 L'ecriture du fichier au format ini par appel de la methode
59 generator.writefile(nom_fichier)
61 Ses caracteristiques principales sont exposees dans des attributs
63 - extensions : qui donne une liste d'extensions de fichier preconisees
66 # Les extensions de fichier preconisees
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 stocke dans l'attribut text
80 def writefile(self,filename):
85 def gener(self,obj,format='brut',config=None):
87 Retourne une representation du JDC obj sous une
88 forme qui est parametree par format.
89 Si format vaut 'brut', retourne une liste de listes de ...
90 Si format vaut 'standard', retourne un texte obtenu par concatenation de la liste
91 Si format vaut 'beautifie', retourne le meme texte beautifie
93 self.appli=obj.get_jdc_root().appli
95 liste= self.generator(obj)
98 elif format == 'standard':
99 self.text=string.join(liste)
100 elif format == 'beautifie':
101 jdc_formate = Formatage(liste,mode='.py')
102 self.text=jdc_formate.formate_jdc()
104 raise "Format pas implemente : "+format
107 def generator(self,obj):
109 Cette methode joue un role d'aiguillage en fonction du type de obj
110 On pourrait utiliser les methodes accept et visitxxx a la
111 place (depend des gouts !!!)
113 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage)
114 if isinstance(obj,Accas.PROC_ETAPE):
115 return self.generPROC_ETAPE(obj)
116 # Attention doit etre place avant MACRO (raison : heritage)
117 elif isinstance(obj,Accas.FORM_ETAPE):
118 return self.generFORM_ETAPE(obj)
119 elif isinstance(obj,Accas.MACRO_ETAPE):
120 return self.generMACRO_ETAPE(obj)
121 elif isinstance(obj,Accas.ETAPE):
122 return self.generETAPE(obj)
123 elif isinstance(obj,Accas.MCFACT):
124 return self.generMCFACT(obj)
125 elif isinstance(obj,Accas.MCList):
126 return self.generMCList(obj)
127 elif isinstance(obj,Accas.MCBLOC):
128 return self.generMCBLOC(obj)
129 elif isinstance(obj,Accas.MCSIMP):
130 return self.generMCSIMP(obj)
131 elif isinstance(obj,Accas.ASSD):
132 return self.generASSD(obj)
133 elif isinstance(obj,Accas.ETAPE_NIVEAU):
134 return self.generETAPE_NIVEAU(obj)
135 elif isinstance(obj,Accas.COMMENTAIRE):
136 return self.generCOMMENTAIRE(obj)
137 # Attention doit etre place avant PARAMETRE (raison : heritage)
138 elif isinstance(obj,Accas.PARAMETRE_EVAL):
139 return self.generPARAMETRE_EVAL(obj)
140 elif isinstance(obj,Accas.PARAMETRE):
141 return self.generPARAMETRE(obj)
142 elif isinstance(obj,Accas.EVAL):
143 return self.generEVAL(obj)
144 elif isinstance(obj,Accas.COMMANDE_COMM):
145 return self.generCOMMANDE_COMM(obj)
146 elif isinstance(obj,Accas.JDC):
147 return self.generJDC(obj)
148 elif isinstance(obj,Accas.MCNUPLET):
149 return self.generMCNUPLET(obj)
150 elif isinstance(obj,ITEM_PARAMETRE):
151 return self.generITEM_PARAMETRE(obj)
152 elif isinstance(obj,Formula):
153 return self.generFormula(obj)
155 raise "Type d'objet non prevu",obj
157 def generJDC(self,obj):
159 Cette methode convertit un objet JDC en une liste de chaines de
160 caracteres a la syntaxe python
163 if obj.definition.l_niveaux == ():
164 # Il n'y a pas de niveaux
165 for etape in obj.etapes:
166 l.append(self.generator(etape))
169 for etape_niveau in obj.etapes_niveaux:
170 l.extend(self.generator(etape_niveau))
172 # Si au moins une etape, on ajoute le retour chariot sur la derniere etape
173 if type(l[-1])==types.ListType:
174 l[-1][-1] = l[-1][-1]+'\n'
175 elif type(l[-1])==types.StringType:
179 def generMCNUPLET(self,obj):
181 Methode generant une representation de self permettant son ecriture
182 dans le format python
186 for v in obj.mc_liste:
187 text = re.sub(".*=","",self.generator(v))
192 def generCOMMANDE_COMM(self,obj):
194 Cette methode convertit un COMMANDE_COMM
195 en une liste de chaines de caracteres a la syntaxe python
197 l_lignes = string.split(obj.valeur,'\n')
199 for ligne in l_lignes:
200 txt = txt + '##'+ligne+'\n'
203 def generEVAL(self,obj):
205 Cette methode convertit un EVAL
206 en une liste de chaines de caracteres a la syntaxe python
208 return 'EVAL("""'+ obj.valeur +'""")'
210 def generCOMMENTAIRE(self,obj):
212 Cette methode convertit un COMMENTAIRE
213 en une liste de chaines de caracteres a la syntaxe python
215 # modification pour repondre a la demande de C. Durand, d'eviter
216 # l'ajout systematique d'un diese, a la suite du commentaire
217 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
219 sans_saut = re.sub("\n$","",obj.valeur)
220 l_lignes = string.split(sans_saut,'\n')
223 for ligne in l_lignes:
224 txt = txt + '#'+ligne+'\n'
226 # suppression du dernier saut de ligne
227 #txt = re.sub("\n$","",txt)
228 # on ajoute un saut de ligne avant
229 pattern=re.compile(" ?\#")
235 def generPARAMETRE_EVAL(self,obj):
237 Cette methode convertit un PARAMETRE_EVAL
238 en une liste de chaines de caracteres a la syntaxe python
240 if obj.valeur == None:
241 return obj.nom + ' = None ;\n'
243 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
245 def generITEM_PARAMETRE(self,obj):
248 def generFormula(self,obj):
252 def generPARAMETRE(self,obj):
254 Cette methode convertit un PARAMETRE
255 en une liste de chaines de caracteres a la syntaxe python
257 return repr(obj) + ";\n"
259 def generETAPE_NIVEAU(self,obj):
261 Cette methode convertit une etape niveau
262 en une liste de chaines de caracteres a la syntaxe python
265 if obj.etapes_niveaux == []:
266 for etape in obj.etapes:
267 l.append(self.generator(etape))
269 for etape_niveau in obj.etapes_niveaux:
270 l.extend(self.generator(etape_niveau))
273 def generETAPE(self,obj):
275 Cette methode convertit une etape
276 en une liste de chaines de caracteres a la syntaxe python
279 sdname= self.generator(obj.sd)
280 if string.find(sdname,'SD_') != -1: sdname='sansnom'
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 Methode particuliere 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 methode convertit une macro-etape
325 en une liste de chaines de caracteres a 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 methode convertit une PROC etape
364 en une liste de chaines de caracteres a 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 derive d'ASSD en une chaine de caracteres a la
394 return obj.get_name()
396 def generMCFACT(self,obj):
398 Convertit un objet MCFACT en une liste de chaines de caracteres a 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 presence d'une entite composee : on recupere 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 presence d'un MCSIMP : on recupere une string
415 text =self.generator(v)
416 l.append(v.nom+'='+text)
417 if obj.nom=="Observers": print l
418 # il faut etre plus subtil dans l'ajout de la virgule en differenciant
419 # le cas ou elle est obligatoire (si self a des freres cadets
420 # dans self.parent) ou non
421 # (cas ou self est seul ou le benjamin de self.parent)
425 def generMCList(self,obj):
427 Convertit un objet MCList en une liste de chaines de caracteres a la
430 if len(obj.data) > 1:
432 for mcfact in obj.data:
433 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 caracteres a 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]
475 def format_item(self,valeur,etape,obj):
476 if (type(valeur) == types.FloatType or 'R' in obj.definition.type) and not(isinstance(valeur,Accas.PARAMETRE)) :
477 # Pour un flottant on utilise str
478 # ou la notation scientifique
479 # On ajoute un . si il n y en a pas dans la valeur
481 if (s.find('.')== -1 and s.find('e')== -1 and s.find('E')==-1) : s=s+'.0'
482 clefobj=etape.get_sdname()
483 if self.appli.appliEficas and self.appli.appliEficas.dict_reels.has_key(clefobj):
484 if self.appli.appliEficas.dict_reels[clefobj].has_key(valeur):
485 s=self.appli.appliEficas.dict_reels[clefobj][valeur]
487 elif type(valeur) == types.StringType :
488 if valeur.find('\n') == -1:
489 # pas de retour chariot, on utilise repr
491 elif valeur.find('"""') == -1:
492 # retour chariot mais pas de triple ", on formatte
496 elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods:
497 s = "CO('"+ self.generator(valeur) +"')"
498 elif isinstance(valeur,Accas.ASSD):
499 s = self.generator(valeur)
500 elif isinstance(valeur,Accas.PARAMETRE):
501 # il ne faut pas prendre la string que retourne gener
502 # mais seulement le nom dans le cas d'un parametre
505 #elif type(valeur) == types.InstanceType or isinstance(valeur,object):
506 # if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
507 # s = "CO('"+ self.generator(valeur) +"')"
508 # elif isinstance(valeur,Accas.PARAMETRE):
509 # il ne faut pas prendre la string que retourne gener
510 # mais seulement le nom dans le cas d'un parametre
514 # s = self.generator(valeur)
517 # Pour les autres types on utilise repr
521 def generMCSIMP(self,obj) :
523 Convertit un objet MCSIMP en une liste de chaines de caracteres a la
527 if type(obj.valeur) in (types.TupleType,types.ListType) :
529 for ss_type in obj.definition.type:
530 if repr(ss_type).find('Tuple') != -1 :
535 s = str(obj.valeur) +','
536 obj.valeurFormatee=obj.valeur
538 obj.valeurFormatee=[]
539 for val in obj.valeur :
540 s =s +self.format_item(val,obj.etape,obj) + ','
541 obj.valeurFormatee.append(self.format_item(val,obj.etape,obj))
542 if len(obj.valeur) > 1:
544 if obj.valeur==[] : s="(),"
545 if obj.nbrColonnes() :
546 s=self.formatColonnes(obj.nbrColonnes(),obj.valeur,obj)
548 obj.valeurFormatee=obj.valeur
549 s=self.format_item(obj.valeur,obj.etape,obj) + ','
553 def formatColonnes(self,nbrColonnes,listeValeurs,obj):
559 while ( indice < len(listeValeurs) ) :
562 for l in range(nbrColonnes) :
563 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
564 textformat=textformat+texteVariable+" ,"
566 textformat=textformat+"\n"
569 while ( indice < len(listeValeurs) ) :
570 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
571 textformat=textformat+texteVariable+", "
573 textformat=textformat+"\n"
574 textformat=textformat[0:-1]+"),\n"
577 textformat=str(obj.valeur)