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