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
106 print ('appel a gener avec None')
108 self.appli=obj.get_jdc_root().appli
109 #self.appli=obj.appli
110 liste= self.generator(obj)
114 elif format == 'standard':
115 self.text=''.join(liste)
116 elif format == 'beautifie':
117 jdc_formate = Formatage(liste,mode='.py')
118 #import cProfile, pstats, StringIO
119 #pr = cProfile.Profile()
121 self.text=jdc_formate.formate_jdc()
123 #s = StringIO.StringIO()
124 #sortby = 'cumulative'
125 #ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
127 #print (s.getvalue())
129 elif format == 'Ligne':
130 jdc_formate = FormatageLigne(liste,mode='.py')
131 self.text=jdc_formate.formate_jdc()
133 raise EficasException(tr("Format non implemente ") +format)
136 def generator(self,obj):
138 Cette methode joue un role d'aiguillage en fonction du type de obj
139 On pourrait utiliser les methodes accept et visitxxx a la
140 place (depend des gouts !!!)
142 # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage)
143 if isinstance(obj,Accas.PROC_ETAPE):
144 return self.generPROC_ETAPE(obj)
145 # Attention doit etre place avant MACRO (raison : heritage)
146 elif isinstance(obj,Accas.FORM_ETAPE):
147 return self.generFORM_ETAPE(obj)
148 elif isinstance(obj,Accas.MACRO_ETAPE):
149 return self.generMACRO_ETAPE(obj)
150 elif isinstance(obj,Accas.ETAPE):
151 return self.generETAPE(obj)
152 elif isinstance(obj,Accas.MCFACT):
153 return self.generMCFACT(obj)
154 elif isinstance(obj,Accas.MCList):
155 return self.generMCList(obj)
156 elif isinstance(obj,Accas.MCBLOC):
157 return self.generMCBLOC(obj)
158 elif isinstance(obj,Accas.MCSIMP):
159 return self.generMCSIMP(obj)
160 elif isinstance(obj,Accas.ASSD):
161 return self.generASSD(obj)
162 elif isinstance(obj,Accas.ETAPE_NIVEAU):
163 return self.generETAPE_NIVEAU(obj)
164 elif isinstance(obj,Accas.COMMENTAIRE):
165 return self.generCOMMENTAIRE(obj)
166 # Attention doit etre place avant PARAMETRE (raison : heritage)
167 elif isinstance(obj,Accas.PARAMETRE_EVAL):
168 return self.generPARAMETRE_EVAL(obj)
169 elif isinstance(obj,Accas.PARAMETRE):
170 return self.generPARAMETRE(obj)
171 elif isinstance(obj,Accas.EVAL):
172 return self.generEVAL(obj)
173 elif isinstance(obj,Accas.COMMANDE_COMM):
174 return self.generCOMMANDE_COMM(obj)
175 elif isinstance(obj,Accas.JDC):
176 return self.generJDC(obj)
177 elif isinstance(obj,Accas.MCNUPLET):
178 return self.generMCNUPLET(obj)
179 elif isinstance(obj,ITEM_PARAMETRE):
180 return self.generITEM_PARAMETRE(obj)
181 elif isinstance(obj,Formula):
182 return self.generFormula(obj)
184 raise EficasException(tr("Type d'objet non prevu") +obj)
186 def generJDC(self,obj):
188 Cette methode convertit un objet JDC en une liste de chaines de
189 caracteres a la syntaxe python
192 if obj.definition.l_niveaux == ():
193 # Il n'y a pas de niveaux
194 for etape in obj.etapes:
195 l.append(self.generator(etape))
198 for etape_niveau in obj.etapes_niveaux:
199 l.extend(self.generator(etape_niveau))
201 # Si au moins une etape, on ajoute le retour chariot sur la derniere etape
202 if type(l[-1])==list:
203 l[-1][-1] = l[-1][-1]+'\n'
204 elif type(l[-1])==bytes:
208 def generMCNUPLET(self,obj):
210 Methode generant une representation de self permettant son ecriture
211 dans le format python
215 for v in obj.mc_liste:
216 text = re.sub(".*=","",self.generator(v))
221 def generCOMMANDE_COMM(self,obj):
223 Cette methode convertit un COMMANDE_COMM
224 en une liste de chaines de caracteres a la syntaxe python
226 l_lignes = obj.valeur.split('\n')
228 for ligne in l_lignes:
229 txt = txt + '##'+ligne+'\n'
232 def generEVAL(self,obj):
234 Cette methode convertit un EVAL
235 en une liste de chaines de caracteres a la syntaxe python
237 return 'EVAL("""'+ obj.valeur +'""")'
239 def generCOMMENTAIRE(self,obj):
241 Cette methode convertit un COMMENTAIRE
242 en une liste de chaines de caracteres a la syntaxe python
244 # modification pour repondre a la demande de C. Durand, d'eviter
245 # l'ajout systematique d'un diese, a la suite du commentaire
246 # Dans la chaine de caracteres obj.valeur, on supprime le dernier
248 sans_saut = re.sub("\n$","",obj.valeur)
249 l_lignes = sans_saut.split('\n')
252 for ligne in l_lignes:
253 txt = txt + '#'+ligne+'\n'
255 # suppression du dernier saut de ligne
256 #txt = re.sub("\n$","",txt)
257 # on ajoute un saut de ligne avant
258 pattern=re.compile(" ?\#")
264 def generPARAMETRE_EVAL(self,obj):
266 Cette methode convertit un PARAMETRE_EVAL
267 en une liste de chaines de caracteres a la syntaxe python
269 if obj.valeur == None:
270 return obj.nom + ' = None ;\n'
272 return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
274 def generITEM_PARAMETRE(self,obj):
277 def generFormula(self,obj):
281 def generPARAMETRE(self,obj):
283 Cette methode convertit un PARAMETRE
284 en une liste de chaines de caracteres a la syntaxe python
286 return repr(obj) + ";\n"
288 def generETAPE_NIVEAU(self,obj):
290 Cette methode convertit une etape niveau
291 en une liste de chaines de caracteres a la syntaxe python
294 if obj.etapes_niveaux == []:
295 for etape in obj.etapes:
296 l.append(self.generator(etape))
298 for etape_niveau in obj.etapes_niveaux:
299 l.extend(self.generator(etape_niveau))
302 def generETAPE(self,obj):
304 Cette methode convertit une etape
305 en une liste de chaines de caracteres a la syntaxe python
308 sdname= self.generator(obj.sd)
309 if sdname.find('SD_') != -1: sdname='sansnom'
313 label=sdname + '='+obj.definition.nom+'('
315 if obj.reuse != None :
316 str = 'reuse ='+ self.generator(obj.reuse) + ','
318 for v in obj.mc_liste:
319 if isinstance(v,Accas.MCBLOC) :
320 liste=self.generator(v)
323 elif isinstance(v,Accas.MCSIMP) :
324 text=self.generator(v)
325 l.append(v.nom+'='+text)
328 liste=self.generator(v)
329 liste[0]=v.nom+'='+liste[0]
337 def generFORM_ETAPE(self,obj):
339 Methode particuliere pour les objets de type FORMULE
343 if nom == '' : nom = 'sansnom'
344 l.append(nom + ' = FORMULE(')
345 for v in obj.mc_liste:
346 text=self.generator(v)
347 l.append(v.nom+'='+text)
351 def generMACRO_ETAPE(self,obj):
353 Cette methode convertit une macro-etape
354 en une liste de chaines de caracteres a la syntaxe python
360 sdname= self.generator(obj.sd)+'='
361 if sdname.find('SD_') != -1: sdname=''
365 label = sdname + obj.definition.nom+'('
367 if obj.reuse != None:
368 # XXX faut il la virgule ou pas ????
369 str = "reuse =" + self.generator(obj.reuse) + ','
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 generPROC_ETAPE(self,obj):
393 Cette methode convertit une PROC etape
394 en une liste de chaines de caracteres a la syntaxe python
397 label=obj.definition.nom+'('
399 for v in obj.mc_liste:
400 if isinstance(v,Accas.MCBLOC) :
401 liste=self.generator(v)
404 elif isinstance(v,Accas.MCSIMP) :
405 text=self.generator(v)
406 if text==None : text= ""
407 l.append(v.nom+'='+text)
410 liste=self.generator(v)
411 liste[0]=v.nom+'='+liste[0]
420 def generASSD(self,obj):
422 Convertit un objet derive d'ASSD en une chaine de caracteres a la
425 return obj.get_name()
427 def generMCFACT(self,obj):
429 Convertit un objet MCFACT en une liste de chaines de caracteres a la
434 for v in obj.mc_liste:
435 if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) :
436 # on est en presence d'une entite composee : on recupere une liste
437 liste=self.generator(v)
438 liste[0]=v.nom+'='+liste[0]
440 elif isinstance(v,Accas.MCBLOC):
441 liste=self.generator(v)
445 # on est en presence d'un MCSIMP : on recupere une string
446 text =self.generator(v)
447 if text== None : text =""
448 if v.nom != "Consigne" : l.append(v.nom+'='+text)
449 # il faut etre plus subtil dans l'ajout de la virgule en differenciant
450 # le cas ou elle est obligatoire (si self a des freres cadets
451 # dans self.parent) ou non
452 # (cas ou self est seul ou le benjamin de self.parent)
456 def generMCList(self,obj):
458 Convertit un objet MCList en une liste de chaines de caracteres a la
461 if len(obj.data) > 1:
463 for mcfact in obj.data: l.append(self.generator(mcfact))
466 l= self.generator(obj.data[0])
469 def generMCBLOC(self,obj):
471 Convertit un objet MCBLOC en une liste de chaines de caracteres a la
475 for v in obj.mc_liste:
476 if isinstance(v,Accas.MCBLOC) :
477 liste=self.generator(v)
480 elif isinstance(v,Accas.MCFACT):
481 liste=self.generator(v)
482 elif isinstance(v,Accas.MCList):
483 liste=self.generator(v)
484 liste[0]=v.nom+'='+liste[0]
485 # PN essai de correction bug identation
486 if (hasattr(v,'data')) :
487 if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)):
496 data=self.generator(v)
497 if data==None : data= ""
498 if type(data) == list:
499 data[0]=v.nom+'='+data[0]
506 def format_item(self,valeur,etape,obj,vientDeListe=0):
507 if (type(valeur) == float or 'R' in obj.definition.type) and not(isinstance(valeur,Accas.PARAMETRE)) :
508 # Pour un flottant on utilise str ou repr si on vient d une liste
509 # ou la notation scientifique
510 # On ajoute un . si il n y en a pas dans la valeur
512 if vientDeListe and repr(valeur) != str(valeur) : s=repr(valeur)
513 if (s.find('.')== -1 and s.find('e')== -1 and s.find('E')==-1) : s=s+'.0'
514 clefobj=etape.get_sdname()
515 if self.appli.appliEficas and clefobj in self.appli.appliEficas.dict_reels:
516 if valeur in self.appli.appliEficas.dict_reels[clefobj]:
517 s=self.appli.appliEficas.dict_reels[clefobj][valeur]
519 elif type(valeur) == bytes :
520 if valeur.find('\n') == -1:
521 # pas de retour chariot, on utilise repr
523 elif valeur.find('"""') == -1:
524 # retour chariot mais pas de triple ", on formatte
528 elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods:
529 s = "CO('"+ self.generator(valeur) +"')"
530 elif isinstance(valeur,Accas.ASSD):
531 s = self.generator(valeur)
532 elif isinstance(valeur,Accas.PARAMETRE):
533 # il ne faut pas prendre la string que retourne gener
534 # mais seulement le nom dans le cas d'un parametre
537 #elif type(valeur) == types.InstanceType or isinstance(valeur,object):
538 # if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods :
539 # s = "CO('"+ self.generator(valeur) +"')"
540 # elif isinstance(valeur,Accas.PARAMETRE):
541 # il ne faut pas prendre la string que retourne gener
542 # mais seulement le nom dans le cas d'un parametre
545 # s = self.generator(valeur)
548 # Pour les autres types on utilise repr
552 def generMCSIMP(self,obj) :
554 Convertit un objet MCSIMP en une liste de chaines de caracteres a la
558 if type(obj.valeur) in (tuple,list) :
560 for ss_type in obj.definition.type:
561 if repr(ss_type).find('Tuple') != -1 :
566 #s = str(obj.valeur) +','
567 #obj.valeurFormatee=obj.valeur
568 s = obj.GetText() +','
569 obj.valeurFormatee=obj.GetText()
571 obj.valeurFormatee=[]
572 for val in obj.valeur :
573 s =s +self.format_item(val,obj.etape,obj,1) + ','
575 obj.valeurFormatee.append(val)
577 obj.valeurFormatee.append(self.format_item(val,obj.etape,obj))
578 if len(obj.valeur) >= 1:
580 if obj.valeur==[] or obj.valeur==() : s="(),"
581 if obj.nbrColonnes() :
582 s=self.formatColonnes(obj.nbrColonnes(),obj.valeur,obj)
584 obj.valeurFormatee=obj.valeur
585 s=self.format_item(obj.valeur,obj.etape,obj) + ','
589 def formatColonnes(self,nbrColonnes,listeValeurs,obj):
594 while ( indice < len(listeValeurs) ) :
597 for l in range(nbrColonnes) :
598 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
599 textformat=textformat+texteVariable+" ,"
601 textformat=textformat+"\n"
604 while ( indice < len(listeValeurs) ) :
605 texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj)
606 textformat=textformat+texteVariable+", "
608 textformat=textformat+"\n"
609 textformat=textformat[0:-1]+"),\n"
612 textformat=str(obj.valeur)