Salome HOME
legere difference ds VARIABLES_TO_BE...
[tools/eficas.git] / convert / convert_TELEMAC.py
1 # Copyright (C) 2007-2013   EDF R&D
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19 from __future__ import absolute_import
20
21
22 import re
23 from Extensions.i18n import tr
24
25
26 from .convert_python import PythonParser
27 import six
28 from six.moves import range
29 try:
30   basestring
31 except NameError:
32   basestring = str
33
34 pattern_comment_slash        = re.compile(r"^\s*/")
35 pattern_comment_slash_vide   = re.compile(r"^\s*/\s*$")
36 pattern_comment_tiret        = re.compile(r"^\s*/-*/*$")
37 pattern_eta   = re.compile(r".*&ETA.*")
38 pattern_fin   = re.compile(r".*&FIN.*")
39 pattern_oui   = re.compile(r"^\s*(oui|OUI|YES|yes|TRUE|true|vrai|VRAI)\s*$")
40 pattern_non   = re.compile(r"^\s*(non|NON|NO|no|FALSE|false|faux|FAUX)\s*$")
41 pattern_blanc = re.compile(r"^\s*$")
42 pattern_listeVide = re.compile(r"^\s*'\s*'\s*$")
43 pattern_commence_par_quote=re.compile(r'^\s*[\'"].*')
44 pattern_finit_par_virgule_ou_affect=re.compile(r'^.*(,|;|=|:)\s*$')
45
46 pattern_ligne=re.compile(r'^\s*(?P<ident>[^=:]*)\s*[:=]\s*(?P<reste>.*)$')
47
48 pattern_variables=re.compile (r"^\s*(?P<ident>VARIABLES FOR GRAPHIC PRINTOUTS|VARIABLES POUR LES SORTIES GRAPHIQUES)\s*[:=]\s*(?P<valeur>[A-Za-z]+(\d*|\*)(,[A-Za-z]+(\d*|\*))*)\s*(?P<reste>.*)$")
49
50 # Attention aux listes de flottants
51 pattern_liste=re.compile(r'^\s*(?P<valeur>[+-.\w]+(\s*;\s*[+-.\w]+)+)\s*(?P<reste>.*)$')
52 pattern_liste_texte=re.compile(r"^\s*(?P<valeur>('.*(';\s*))+('.*'\s*)?)(?P<reste>.*)$")
53 pattern_flottant=re.compile(r'^\s*(?P<valeur>[+-]?((\d+(\.\d*)?)|(\.\d+))([dDeE][+-]?\d+)?)\s*(?P<reste>.*)$')
54 pattern_texteQuote  = re.compile (r"^\s*(?P<valeur>'[^']+(''[^']+)*')\s*(?P<reste>.*)$")
55 pattern_texteSimple = re.compile (r"(?P<valeur>(^|\s)\s*[\w\.-]+)\s*(?P<reste>.*)$")
56 pattern_texteVide   = re.compile (r"^\s*(?P<valeur>'')\s*(?P<reste>.*)$")
57
58 pattern_ContientDouble=re.compile (r"^.*''.*$")
59
60 # le pattern texte reconnait
61 #nom1 nom 2 : ou = chaine entre '
62 # avec eventuellement  des quotes au milieu par exemple
63 # TITRE = 'TELEMAC 2D : GOUTTE D''EAU DANS UN BASSIN$'
64 # m.group("texte") va rendre 'TELEMAC 2D : GOUTTE D''EAU DANS UN BASSIN$'
65
66
67 #Si le code n est pas Telemac
68 try :
69    from enum_Telemac2d_auto       import TelemacdicoEn
70 except :
71    pass
72
73 from Extensions import localisation
74
75
76
77 def entryPoint():
78    """
79    Return a dictionary containing the description needed to load the plugin
80    """
81    return {
82           'name' : 'TELEMAC',
83           'factory' : TELEMACParser
84           }
85
86 class TELEMACParser(PythonParser):
87    """
88    This converter works like PythonParser, except that it also initializes all
89    model variables to None in order to avoid Python syntax errors when loading
90    a file with a different or inexistent definition of variables.
91    """
92
93    def convert(self, outformat, appli=None):
94
95
96       from Accas import A_BLOC, A_FACT, A_SIMP
97       self.dicoCasToCata=appli.readercata.dicoCasToCata
98       self.dicoInverse=appli.readercata.dicoInverse
99       self.dicoMC=appli.readercata.dicoMC
100       self.Ordre_Des_Commandes=appli.readercata.Ordre_Des_Commandes
101
102       if appli.langue=='fr' :
103           from enum_Telemac2d_auto       import DicoEnumCasFrToEnumCasEn
104           for k in DicoEnumCasFrToEnumCasEn :
105               TelemacdicoEn[k]=DicoEnumCasFrToEnumCasEn[k]
106
107       text=""
108       self.dictSimp={}
109
110       l_lignes_texte_all = self.text.split('\n')
111       l_lignes_texte = []
112       listeComment = []
113       dicoComment={}
114       dicoCommentSimp={}
115       dicoCommentMC={}
116       texteComment=""
117       debut=True
118       trouveComment = 0
119       for l  in l_lignes_texte_all :
120         if pattern_eta.match(l) : continue
121         if pattern_fin.match(l) : continue
122         if pattern_blanc.match(l) : continue
123
124         if not(pattern_comment_slash.match(l)):
125               l_lignes_texte.append(l)
126               if trouveComment :
127                  if debut:  dicoComment['debut']=texteComment
128                  else : dicoComment[l]=texteComment
129                  trouveComment = 0
130                  texteComment=""
131               if debut : debut = False
132
133         if pattern_comment_slash.match(l):
134              #if pattern_comment_slash_vide.match(l) : continue
135              if pattern_comment_tiret.match(l) : continue
136              texteComment+=l.replace ('/','',1)
137              texteComment+='\n'
138              trouveComment=1
139
140       if texteComment != "" : dicoComment['fin']= texteComment
141
142
143       l_lignes=[]
144       i=0
145       while (i < len(l_lignes_texte)) :
146           ligne=l_lignes_texte[i]
147           i=i+1
148           if not(pattern_finit_par_virgule_ou_affect.match(ligne)):
149              l_lignes.append(ligne)
150              continue
151           nouvelle_ligne=ligne
152           while (i < len(l_lignes_texte)):
153              ligne_traitee=l_lignes_texte[i]
154              i=i+1
155              nouvelle_ligne += ligne_traitee
156              if not(pattern_finit_par_virgule_ou_affect.match(ligne_traitee)):
157                 l_lignes.append(nouvelle_ligne)
158                 break
159
160
161       for ligne in l_lignes :
162           if pattern_comment_slash.match(ligne) : continue
163           #PN : deja teste
164           #if pattern_eta.match(ligne) : continue
165           #if pattern_fin.match(ligne) : continue
166           #if pattern_blanc.match(ligne) : continue
167
168
169           finLigne=ligne
170           while finLigne != "" :
171               if pattern_comment_slash.match(finLigne) : finLigne=""; continue
172               valeur=""
173               if pattern_variables.match(finLigne) :
174                  m=pattern_variables.match(finLigne)
175                  simpCas=self.traiteIdent(m.group('ident'))
176                  valeur=m.group('valeur')
177                  finLigne=m.group('reste')
178                  self.dictSimp[simpCas]=valeur
179                  continue
180
181
182               m=pattern_ligne.match(finLigne)
183               if m == None :
184                  #print( "________________________________________________")
185                  print ('pb avec ****', finLigne , '**** dans ', ligne)
186                  #print( "________________________________________________")
187                  break
188
189               simpCas=self.traiteIdent(m.group('ident'))
190               if not simpCas :
191                  finLigne=m.group('reste')
192                  continue
193
194               finLigne=m.group('reste')
195               # attention, l ordre des if est important
196               if pattern_liste.match(finLigne) :
197                  m=pattern_liste.match(finLigne)
198               elif pattern_liste_texte.match(finLigne) :
199                  m=pattern_liste_texte.match(finLigne)
200               elif pattern_texteQuote.match(finLigne) :
201                  m=pattern_texteQuote.match(finLigne)
202               elif pattern_flottant.match(finLigne) :
203                  m=pattern_flottant.match(finLigne)
204               elif pattern_texteVide.match(finLigne):
205                  m=pattern_texteVide.match(finLigne)
206               elif pattern_texteSimple.match(finLigne):
207                  m=pattern_texteSimple.match(finLigne)
208               else :
209                  #print ("________________________________________________")
210                  print ('pb avec ****', finLigne , '**** dans ', ligne)
211                  print ("non match")
212                  #print ("________________________________________________")
213                  break
214
215
216               valeur=m.group('valeur')
217               if pattern_blanc.match(valeur) : valeur=None
218
219               if pattern_flottant.match(finLigne) :
220                  valeur=re.sub("d","e",valeur)
221                  valeur=re.sub("D","E",valeur)
222
223               if pattern_liste.match(finLigne) or pattern_liste_texte.match(finLigne):
224                  valeur=valeur.split(";")
225
226
227               finLigne=m.group('reste')
228               self.dictSimp[simpCas]=valeur
229
230               if ligne in dicoComment.keys():
231                  dicoCommentSimp[simpCas]=dicoComment[ligne]
232
233       if 'TITLE' not in self.dictSimp :
234           import os
235           #self.dictSimp['TITLE']=os.path.basename(self.filename)
236
237
238       dicoParMC={}
239       for simp in self.dictSimp:
240           if simp in TELEMACParser.__dict__ : TELEMACParser.__dict__[simp](self,)
241
242       for simp in self.dictSimp:
243           if simp not in self.dicoInverse :
244              #print ( "************")
245              print  ("pb avec dans dicoInverse", simp,'------')
246              print("dicoInverse",sorted(self.dicoInverse.keys()))
247              #print  ("************")
248              continue
249           listeGenea=self.dicoInverse[simp]
250           listeGeneaReverse=[]
251           for (u,v) in listeGenea :
252               if isinstance(v,A_BLOC.BLOC): continue
253               listeGeneaReverse.append(u)
254           listeGeneaReverse.reverse()
255           dicoTravail=dicoParMC
256           i=0
257           if simp in dicoCommentSimp :
258              MC=listeGeneaReverse[0]
259              if MC in dicoCommentMC : dicoCommentMC[MC]+dicoCommentSimp[simp]
260              else                   : dicoCommentMC[MC]=dicoCommentSimp[simp]
261           while i < len(listeGeneaReverse[0:-1]) :
262             mot=listeGeneaReverse[i]
263             i=i+1
264             if mot not in dicoTravail: dicoTravail[mot]={}
265             dicoTravail=dicoTravail[mot]
266           dicoTravail[simp]=self.dictSimp[simp]
267
268       self.textePy=""
269       listeMC=self.tri(list(dicoParMC.keys()))
270       for k in listeMC :
271           if k in dicoCommentMC :
272                 commentaire="COMMENTAIRE("+repr(dicoCommentMC[k])+")\n"
273                 self.textePy+=commentaire
274           self.textePy += str(k )+ "("
275           self.traiteMC(dicoParMC[k])
276           self.textePy += ");\n"
277
278
279       appli.listeTelemac=self.dictSimp
280       if 'debut' in dicoComment :
281           commentaire="COMMENTAIRE("+repr(dicoComment['debut'])+")\n"
282           self.textePy=commentaire+self.textePy
283       if 'fin' in dicoComment :
284           commentaire="COMMENTAIRE("+repr(dicoComment['fin'])+")\n"
285           self.textePy=self.textePy+commentaire
286
287       #print (self.textePy)
288       return self.textePy
289
290
291    #----------------------------------------
292    def traiteIdent(self,ident):
293    # enleve les espaces de part et autre
294    # traduit du langage Telemac vers le langage Catalogue
295    #----------------------------------------
296           while ident[-1] == " " or ident[-1] == '\t' : ident=ident[0:-1]
297           while ident[0]  == " " or ident[0]  == '\t' : ident=ident[1:]
298           try : identCata=self.dicoCasToCata[ident]
299           except :
300             print ( "---> ", "pb mot clef  pour", ident)
301             identCata=None
302           return identCata
303
304
305    def traiteMC(self,dico) :
306        from Accas import A_BLOC, A_FACT, A_SIMP
307        for k in dico :
308            valeur= dico[k]
309            if k not in self.dicoMC : kA=self.dicoFrancaisAnglais[k]
310            else : kA=k
311            obj=self.dicoMC[kA]
312            if isinstance(obj,A_FACT.FACT):   self.convertFACT(obj,kA,valeur)
313            elif isinstance(obj,A_BLOC.BLOC): self.convertBLOC(obj,kA,valeur)
314            elif isinstance(obj,A_SIMP.SIMP): self.convertSIMP(obj,kA,valeur)
315            else : print ("%%%%%%%%%%%\n", "pb conversion type pour", k, obj, "\n%%%%%%%%%%%")
316
317
318    def convertFACT(self,obj,nom,valeur):
319        # traitement LIQUID_BOUNDARIES
320        if nom in TELEMACParser.__dict__ :
321           TELEMACParser.__dict__[nom](self,)
322           return
323        self.textePy +=  nom + "=_F( "
324        self.traiteMC(valeur)
325        self.textePy += '),\n'
326
327
328    def convertBLOC(self,obj,nom,valeur):
329        print ("ANOMALIE _________ BLOC ")
330        print (nom)
331
332    def convertSIMP(self,obj,nom,valeur):
333        #print ('in convertSIMP', nom,valeur)
334        #if nom in ("PRESCRIBED_FLOWRATES", "PRESCRIBED_VELOCITIES", "PRESCRIBED_ELEVATIONS" ): return
335        if obj.max==1 :
336           if hasattr(obj.type[0],'ntuple') :
337              lval=[]
338              for v in valeur :
339                try :    v=eval(v,{})
340                except : pass
341                lval.append(v)
342              self.textePy += nom + "=" + str(lval) +","
343              return
344           if 'TXM' in obj.type :
345
346               if pattern_ContientDouble.match(str(valeur)):
347                  valeur=re.sub("''","\'\'",str(valeur))
348                  self.textePy += nom + "=" + str(valeur) +","
349                  return
350               valeur=str(valeur)
351
352               # ceinture et bretelle si les re sont correctes -)
353               while valeur[-1] == " " or valeur[-1] == '\t' : valeur=valeur[0:-1]
354               while valeur[0]  == " " or valeur[0]  == '\t' : valeur=valeur[1:]
355
356
357
358           # Pour les enum
359           try    : valeur=eval(valeur,{})
360           except : pass
361
362           if nom in TelemacdicoEn:
363              try    :
364                valeur=TelemacdicoEn[nom][valeur]
365                self.textePy += nom + "= '" + str(valeur) +"',"
366                return
367              except : pass
368
369
370           if obj.into != [] and obj.into != None and not('R' in obj.type) and not('I' in obj.type):
371              for possible in obj.into :
372                 try :
373                   if possible.upper() == valeur.upper():
374                      valeur=possible
375                      break
376                   v=valeur[0].upper()+valeur[1:].lower()
377                   v2=tr(v)
378                   if possible.upper() == v2.upper():
379                      valeur=possible
380                      break
381                 except:
382                    if valeur != None :
383                       print ("pb avec le type de ", obj.nom, obj.type, 'et la valeur ', valeur)
384
385           if 'Fichier' in obj.type or 'TXM' in obj.type or 'Repertoire' in obj.type or 'FichierOuRepertoire' in obj.type :
386               valeur=str(valeur)
387               if valeur == "" or valeur == " " :
388                  self.textePy += nom + "= '" + str(valeur) +"' ,"
389                  return
390               while valeur[-1] == " " : valeur=valeur[0:-1]
391               while valeur[0]  == " " : valeur=valeur[1:]
392               self.textePy += nom + "= '" + str(valeur) +"' ,"
393               return
394
395           if bool in obj.type :
396             if   valeur == True  :  self.textePy += nom + "= True,"
397             elif valeur == False :  self.textePy += nom + "= False,"
398             elif pattern_oui.match(valeur) : self.textePy += nom + "= True,"
399             elif pattern_non.match(valeur) : self.textePy += nom + "= False,"
400             else :  self.textePy += nom + "= None,"
401             return
402           self.textePy += nom + "=" + str(valeur) +","
403
404        else :
405           if valeur == () or valeur ==[] or pattern_listeVide.match(str(valeur)) :
406              self.textePy += nom + "= None,"
407              return
408
409           # les 4 lignes suivantes sont probablement inutiles
410           while valeur[-1] == " " or  valeur[-1]=="'" : valeur=valeur[0:-1]
411           while valeur[0]  == " " or  valeur[-0]=="'" : valeur=valeur[1:]
412           oldValeur=valeur
413           if isinstance(valeur, basestring) :
414              if   ";" in valeur : valeur=valeur.split(';')
415              else  : valeur=valeur.split(',')
416
417           if len(valeur)< 2 and pattern_flottant.match(oldValeur):
418           # Attention : on attend une liste mais on a une seule valeur!
419              try :    oldValeur=eval(oldValeur,{})
420              except : pass
421              if nom in TelemacdicoEn :
422                 v=TelemacdicoEn[nom][oldValeur]
423                 self.textePy += nom + "= ('" + str(v) +"',),"
424              else :
425                 self.textePy += nom + "= (" + str(oldValeur) +",),"
426              return
427
428
429           if valeur == None : return
430           newVal=[]
431           for v in valeur :
432             try :    v=eval(v,{})
433             except : pass
434             if nom in TelemacdicoEn:
435                try    : v=TelemacdicoEn[nom][v]
436                except : pass
437             newVal.append(v)
438           self.textePy += nom + "=" + str(newVal) +","
439
440
441
442    def tri(self, listeIn):
443       if len(listeIn) == 1 : return listeIn
444       if self.Ordre_Des_Commandes == None : return listeIn
445       listeOut=[listeIn[0],]
446       for k in listeIn[1:]:
447           #k=str(self.dicoFrancaisAnglais[kF])
448           ordreK=self.Ordre_Des_Commandes.index(k)
449           i=0
450           while i < len(listeOut):
451              #ordreI=self.Ordre_Des_Commandes.index(self.dicoFrancaisAnglais[listeOut[i]])
452              ordreI=self.Ordre_Des_Commandes.index(listeOut[i])
453              if ordreK < ordreI : break
454              i=i+1
455           #listeOut.insert(i,kF)
456           listeOut.insert(i,k)
457       return listeOut
458
459 #   def BOUNDARY_CONDITIONS(self):
460 #       texte_Boundaries="BOUNDARY_CONDITIONS=_F(LIQUID_BOUNDARIES=( "
461 #       if 'PRESCRIBED_ELEVATIONS' in self.dictSimp:
462 #              valeursPE=self.dictSimp["PRESCRIBED_ELEVATIONS"]
463 #              if not type(valeursPE)==list : valeursPE = (valeursPE,)
464 #              longueur=len(self.dictSimp["PRESCRIBED_ELEVATIONS"])
465 #       else : valeursPE=None
466 #       if 'PRESCRIBED_FLOWRATES' in self.dictSimp:
467 #              valeursPF=self.dictSimp["PRESCRIBED_FLOWRATES"]
468 #              if not type(valeursPF)==list : valeursPF = (valeursPF,)
469 #              longueur=len(self.dictSimp["PRESCRIBED_FLOWRATES"])
470 #       else : valeursPF=None
471 #       if 'PRESCRIBED_VELOCITIES' in self.dictSimp:
472 #              valeursPV=self.dictSimp["PRESCRIBED_VELOCITIES"]
473 #              if not type(valeursPV)==list : valeursPV = (valeursPV,)
474 #              longueur=len(self.dictSimp["PRESCRIBED_VELOCITIES"])
475 #       else : valeursPV=None
476 #
477 #       if valeursPE == None and valeursPF == None and valeursPV == None :
478 #             texte_Boundaries +="),\n"
479 #             return
480 #
481 #       if valeursPE == None or valeursPF == None or valeursPV == None :
482 #          listNulle=[]
483 #          for i in range(longueur) : listNulle.append('0')
484 #
485 #
486 #       if valeursPE == None : valeursPE = listNulle
487 #       if valeursPF == None : valeursPF = listNulle
488 #       if valeursPV == None : valeursPV = listNulle
489 #
490 #
491 #       for e in range(len(valeursPE)):
492 #          if valeursPE[e] != "" or valeursPE[e] != "\n" :
493 #            if eval(valeursPE[e],{}) != 0 :
494 #               texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Elevations',\n"
495 #               texte_Boundaries += "PRESCRIBED_ELEVATIONS = " + str(valeursPE[e]) + "),\n"
496 #               continue
497 #
498 #          if valeursPF[e] != "" or valeursPF[e] != "\n" :
499 #            if eval(valeursPF[e],{}) != 0 :
500 #               texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Flowrates',\n"
501 #               texte_Boundaries += "PRESCRIBED_FLOWRATES = " + str(valeursPF[e]) + "),\n"
502 #               continue
503 #
504 #          if valeursPV[e] != "" or valeursPV[e] != "\n" :
505 #             if eval(valeursPV[e],{})!=0 :
506 #                texte_Boundaries += "_F( BOUNDARY_TYPE= 'Prescribed Velocity',\n"
507 #                texte_Boundaries += "PRESCRIBED_VELOCITIES = " + str(valeursPV[e]) + "),\n"
508 #                continue
509 #          print ("pb texte_Boundaries avec la valeur numero ", e)
510 #
511 #       texte_Boundaries +="),),"
512 #       self.textePy += texte_Boundaries
513 #