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
25 from __future__ import absolute_import
27 from builtins import str
28 from builtins import object
29 from builtins import range
35 from Noyau import N_CR
36 from Noyau.N_utils import repr_float
39 from Extensions.parametre import ITEM_PARAMETRE
40 from .Formatage import Formatage
41 from .Formatage import FormatageLigne
42 from Extensions.param2 import Formula
43 from Extensions.eficas_exception import EficasException
44 from Extensions.i18n import tr
49 Retourne les informations necessaires pour le chargeur de plugins
51 Ces informations sont retournees dans un dictionnaire
56 # La factory pour creer une instance du plugin
57 'factory' : PythonGenerator,
61 class PythonGenerator(object):
63 Ce generateur parcourt un objet de type JDC et produit
64 un fichier au format python
66 L'acquisition et le parcours sont realises par la methode
67 generator.gener(objet_jdc,format)
69 L'ecriture du fichier au format ini par appel de la methode
70 generator.writefile(nom_fichier)
72 Ses caracteristiques principales sont exposees dans des attributs
74 - extensions : qui donne une liste d'extensions de fichier preconisees
77 # Les extensions de fichier preconisees
80 def __init__(self,cr=None):
81 # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
85 self.cr=N_CR.CR(debut='CR generateur format python pour python',
86 fin='fin CR format python pour python')
87 # Le texte au format python est stocke dans l'attribut text
91 def writefile(self,filename):
96 def gener(self,obj,format='brut',config=None,appli=None):
98 Retourne une representation du JDC obj sous une
99 forme qui est parametree par format.
100 Si format vaut 'brut', retourne une liste de listes de ...
101 Si format vaut 'standard', retourne un texte obtenu par concatenation de la liste
102 Si format vaut 'beautifie', retourne le meme texte beautifie
105 self.appli=obj.get_jdc_root().appli
106 #self.appli=obj.appli
107 liste= self.generator(obj)
111 elif format == 'standard':
112 self.text=''.join(liste)
113 elif format == 'beautifie':
114 jdc_formate = Formatage(liste,mode='.py')
115 #import cProfile, pstats, StringIO
116 #pr = cProfile.Profile()
118 self.text=jdc_formate.formate_jdc()
120 #s = StringIO.StringIO()
121 #sortby = 'cumulative'
122 #ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
124 #print (s.getvalue())
126 elif format == 'Ligne':
127 jdc_formate = FormatageLigne(liste,mode='.py')
128 self.text=jdc_formate.formate_jdc()
130 raise EficasException(tr("Format non implemente ") +format)
133 def generator(self,obj):
135 Cette methode joue un role d'aiguillage en fonction du type de obj
136 On pourrait utiliser les methodes accept et visitxxx a la
137 place (depend des gouts !!!)
139 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage)
140 if isinstance(obj,Accas.PROC_ETAPE):
141 return self.generPROC_ETAPE(obj)
142 # Attention doit etre place avant MACRO (raison : heritage)
143 elif isinstance(obj,Accas.FORM_ETAPE):
144 return self.generFORM_ETAPE(obj)
145 elif isinstance(obj,Accas.MACRO_ETAPE):
146 return self.generMACRO_ETAPE(obj)
147 elif isinstance(obj,Accas.ETAPE):
148 return self.generETAPE(obj)
149 elif isinstance(obj,Accas.MCFACT):
150 return self.generMCFACT(obj)
151 elif isinstance(obj,Accas.MCList):
152 return self.generMCList(obj)
153 elif isinstance(obj,Accas.MCBLOC):
154 return self.generMCBLOC(obj)
155 elif isinstance(obj,Accas.MCSIMP):
156 return self.generMCSIMP(obj)
157 elif isinstance(obj,Accas.ASSD):
158 return self.generASSD(obj)
159 elif isinstance(obj,Accas.ETAPE_NIVEAU):
160 return self.generETAPE_NIVEAU(obj)
161 elif isinstance(obj,Accas.COMMENTAIRE):
162 return self.generCOMMENTAIRE(obj)
163 # Attention doit etre place avant PARAMETRE (raison : heritage)
164 elif isinstance(obj,Accas.PARAMETRE_EVAL):
165 return self.generPARAMETRE_EVAL(obj)
166 elif isinstance(obj,Accas.PARAMETRE):
167 return self.generPARAMETRE(obj)
168 elif isinstance(obj,Accas.EVAL):
169 return self.generEVAL(obj)
170 elif isinstance(obj,Accas.COMMANDE_COMM):
171 return self.generCOMMANDE_COMM(obj)
172 elif isinstance(obj,Accas.JDC):
173 return self.generJDC(obj)
174 elif isinstance(obj,Accas.MCNUPLET):
175 return self.generMCNUPLET(obj)
176 elif isinstance(obj,ITEM_PARAMETRE):
177 return self.generITEM_PARAMETRE(obj)
178 elif isinstance(obj,Formula):
179 return self.generFormula(obj)
181 raise EficasException(tr("Type d'objet non prevu") +obj)
183 def generJDC(self,obj):
185 Cette methode convertit un objet JDC en une liste de chaines de
186 caracteres a la syntaxe python
189 if obj.definition.l_niveaux == ():
190 # Il n'y a pas de niveaux
191 for etape in obj.etapes:
192 l.append(self.generator(etape))
195 for etape_niveau in obj.etapes_niveaux:
196 l.extend(self.generator(etape_niveau))
198 # Si au moins une etape, on ajoute le retour chariot sur la derniere etape
199 if type(l[-1])==list:
200 l[-1][-1] = l[-1][-1]+'\n'
201 elif type(l[-1])==bytes:
205 def generMCNUPLET(self,obj):
207 Methode generant une representation de self permettant son ecriture
208 dans le format python
212 for v in obj.mc_liste:
213 text = re.sub(".*=","",self.generator(v))
218 def generCOMMANDE_COMM(self,obj):
220 Cette methode convertit un COMMANDE_COMM
221 en une liste de chaines de caracteres a la syntaxe python
223 l_lignes = obj.valeur.split('\n')
225 for ligne in l_lignes:
226 txt = txt + '##'+ligne+'\n'
229 def generEVAL(self,obj):
231 Cette methode convertit un EVAL
232 en une liste de chaines de caracteres a la syntaxe python
234 return 'EVAL("""'+ obj.valeur +'""")'
236 def generCOMMENTAIRE(self,obj):
238 Cette methode convertit un COMMENTAIRE
239 en une liste de chaines de caracteres a la syntaxe python
241 # modification pour repondre a la demande de C. Durand, d'eviter
242 # l'ajout systematique d'un diese, a la suite du commentaire
243 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
245 sans_saut = re.sub("\n$","",obj.valeur)
246 l_lignes = sans_saut.split('\n')
249 for ligne in l_lignes:
250 txt = txt + '#'+ligne+'\n'
252 # suppression du dernier saut de ligne
253 #txt = re.sub("\n$","",txt)
254 # on ajoute un saut de ligne avant
255 pattern=re.compile(" ?\#")
261 def generPARAMETRE_EVAL(self,obj):
263 Cette methode convertit un PARAMETRE_EVAL
264 en une liste de chaines de caracteres a la syntaxe python
266 if obj.valeur == None:
267 return obj.nom + ' = None ;\n'
269 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
271 def generITEM_PARAMETRE(self,obj):
274 def generFormula(self,obj):
278 def generPARAMETRE(self,obj):
280 Cette methode convertit un PARAMETRE
281 en une liste de chaines de caracteres a la syntaxe python
283 return repr(obj) + ";\n"
285 def generETAPE_NIVEAU(self,obj):
287 Cette methode convertit une etape niveau
288 en une liste de chaines de caracteres a la syntaxe python
291 if obj.etapes_niveaux == []:
292 for etape in obj.etapes:
293 l.append(self.generator(etape))
295 for etape_niveau in obj.etapes_niveaux:
296 l.extend(self.generator(etape_niveau))
299 def generETAPE(self,obj):
301 Cette methode convertit une etape
302 en une liste de chaines de caracteres a la syntaxe python
305 sdname= self.generator(obj.sd)
306 if sdname.find('SD_') != -1: sdname='sansnom'
310 label=sdname + '='+obj.definition.nom+'('
312 if obj.reuse != None :
313 str = 'reuse ='+ self.generator(obj.reuse) + ','
315 for v in obj.mc_liste:
316 if isinstance(v,Accas.MCBLOC) :
317 liste=self.generator(v)
320 elif isinstance(v,Accas.MCSIMP) :
321 text=self.generator(v)
322 l.append(v.nom+'='+text)
325 liste=self.generator(v)
326 liste[0]=v.nom+'='+liste[0]
334 def generFORM_ETAPE(self,obj):
336 Methode particuliere pour les objets de type FORMULE
340 if nom == '' : nom = 'sansnom'
341 l.append(nom + ' = FORMULE(')
342 for v in obj.mc_liste:
343 text=self.generator(v)
344 l.append(v.nom+'='+text)
348 def generMACRO_ETAPE(self,obj):
350 Cette methode convertit une macro-etape
351 en une liste de chaines de caracteres a la syntaxe python
357 sdname= self.generator(obj.sd)+'='
358 if sdname.find('SD_') != -1: sdname=''
362 label = sdname + obj.definition.nom+'('
364 if obj.reuse != None:
365 # XXX faut il la virgule ou pas ????
366 str = "reuse =" + self.generator(obj.reuse) + ','
368 for v in obj.mc_liste:
369 if isinstance(v,Accas.MCBLOC) :
370 liste=self.generator(v)
373 elif isinstance(v,Accas.MCSIMP) :
374 text=self.generator(v)
375 l.append(v.nom+'='+text)
378 liste=self.generator(v)
379 liste[0]=v.nom+'='+liste[0]
388 def generPROC_ETAPE(self,obj):
390 Cette methode convertit une PROC etape
391 en une liste de chaines de caracteres a la syntaxe python
394 label=obj.definition.nom+'('
396 for v in obj.mc_liste:
397 if isinstance(v,Accas.MCBLOC) :
398 liste=self.generator(v)
401 elif isinstance(v,Accas.MCSIMP) :
402 text=self.generator(v)
403 if text==None : text= ""
404 l.append(v.nom+'='+text)
407 liste=self.generator(v)
408 liste[0]=v.nom+'='+liste[0]
417 def generASSD(self,obj):
419 Convertit un objet derive d'ASSD en une chaine de caracteres a la
422 return obj.get_name()
424 def generMCFACT(self,obj):
426 Convertit un objet MCFACT en une liste de chaines de caracteres a la
431 for v in obj.mc_liste:
432 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
433 # on est en presence d'une entite composee : on recupere une liste
434 liste=self.generator(v)
435 liste[0]=v.nom+'='+liste[0]
437 elif isinstance(v,Accas.MCBLOC):
438 liste=self.generator(v)
442 # on est en presence d'un MCSIMP : on recupere une string
443 text =self.generator(v)
444 if text== None : text =""
445 if v.nom != "Consigne" : l.append(v.nom+'='+text)
446 # il faut etre plus subtil dans l'ajout de la virgule en differenciant
447 # le cas ou elle est obligatoire (si self a des freres cadets
448 # dans self.parent) ou non
449 # (cas ou self est seul ou le benjamin de self.parent)
453 def generMCList(self,obj):
455 Convertit un objet MCList en une liste de chaines de caracteres a la
458 if len(obj.data) > 1:
460 for mcfact in obj.data: l.append(self.generator(mcfact))
463 l= self.generator(obj.data[0])
466 def generMCBLOC(self,obj):
468 Convertit un objet MCBLOC en une liste de chaines de caracteres a la
472 for v in obj.mc_liste:
473 if isinstance(v,Accas.MCBLOC) :
474 liste=self.generator(v)
477 elif isinstance(v,Accas.MCFACT):
478 liste=self.generator(v)
479 elif isinstance(v,Accas.MCList):
480 liste=self.generator(v)
481 liste[0]=v.nom+'='+liste[0]
482 # PN essai de correction bug identation
483 if (hasattr(v,'data')) :
484 if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
493 data=self.generator(v)
494 if data==None : data= ""
495 if type(data) == list:
496 data[0]=v.nom+'='+data[0]
503 def format_item(self,valeur,etape,obj,vientDeListe=0):
504 if (type(valeur) == float or 'R' in obj.definition.type) and not(isinstance(valeur,Accas.PARAMETRE)) :
505 # Pour un flottant on utilise str ou repr si on vient d une liste
506 # ou la notation scientifique
507 # On ajoute un . si il n y en a pas dans la valeur
509 if vientDeListe and repr(valeur) != str(valeur) : s=repr(valeur)
510 if (s.find('.')== -1 and s.find('e')== -1 and s.find('E')==-1) : s=s+'.0'
511 clefobj=etape.get_sdname()
512 if self.appli.appliEficas and clefobj in self.appli.appliEficas.dict_reels:
513 if valeur in self.appli.appliEficas.dict_reels[clefobj]:
514 s=self.appli.appliEficas.dict_reels[clefobj][valeur]
516 elif type(valeur) == bytes :
517 if valeur.find('\n') == -1:
518 # pas de retour chariot, on utilise repr
520 elif valeur.find('"""') == -1:
521 # retour chariot mais pas de triple ", on formatte
525 elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods:
526 s = "CO('"+ self.generator(valeur) +"')"
527 elif isinstance(valeur,Accas.ASSD):
528 s = self.generator(valeur)
529 elif isinstance(valeur,Accas.PARAMETRE):
530 # il ne faut pas prendre la string que retourne gener
531 # mais seulement le nom dans le cas d'un parametre
534 #elif type(valeur) == types.InstanceType or isinstance(valeur,object):
535 # if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
536 # s = "CO('"+ self.generator(valeur) +"')"
537 # elif isinstance(valeur,Accas.PARAMETRE):
538 # il ne faut pas prendre la string que retourne gener
539 # mais seulement le nom dans le cas d'un parametre
542 # s = self.generator(valeur)
545 # Pour les autres types on utilise repr
549 def generMCSIMP(self,obj) :
551 Convertit un objet MCSIMP en une liste de chaines de caracteres a la
555 if type(obj.valeur) in (tuple,list) :
557 for ss_type in obj.definition.type:
558 if repr(ss_type).find('Tuple') != -1 :
563 #s = str(obj.valeur) +','
564 #obj.valeurFormatee=obj.valeur
565 s = obj.GetText() +','
566 obj.valeurFormatee=obj.GetText()
568 obj.valeurFormatee=[]
569 for val in obj.valeur :
570 s =s +self.format_item(val,obj.etape,obj,1) + ','
572 obj.valeurFormatee.append(val)
574 obj.valeurFormatee.append(self.format_item(val,obj.etape,obj))
575 if len(obj.valeur) >= 1:
577 if obj.valeur==[] or obj.valeur==() : s="(),"
578 if obj.nbrColonnes() :
579 s=self.formatColonnes(obj.nbrColonnes(),obj.valeur,obj)
581 obj.valeurFormatee=obj.valeur
582 s=self.format_item(obj.valeur,obj.etape,obj) + ','
586 def formatColonnes(self,nbrColonnes,listeValeurs,obj):
591 while ( indice < len(listeValeurs) ) :
594 for l in range(nbrColonnes) :
595 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
596 textformat=textformat+texteVariable+" ,"
598 textformat=textformat+"\n"
601 while ( indice < len(listeValeurs) ) :
602 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
603 textformat=textformat+texteVariable+", "
605 textformat=textformat+"\n"
606 textformat=textformat[0:-1]+"),\n"
609 textformat=str(obj.valeur)