Salome HOME
Updates for Telemac
[tools/eficas.git] / convert / convert_TELEMAC.py
1 # Copyright (C) 2007-2017   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 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>C_VSM_PRINTOUT_SELECTION|COUPLAGE AVEC|COUPLING WITH|VARIABLES FOR GRAPHIC PRINTOUTS|VARIABLES POUR LES SORTIES GRAPHIQUES|VARIABLES TO BE PRINTED|VARIABLES A IMPRIMER|VARIABLES FOR 3D GRAPHIC PRINTOUTS|VARIABLES POUR LES SORTIES GRAPHIQUES 3D|VARIABLES POUR LES SORTIES GRAPHIQUES 2D|VARIABLES FOR 2D GRAPHIC PRINTOUTS)\s*[:=]\s*(?P<quote>[']?)(?P<valeur>[A-Za-z]+(\d*|\*)([,;][A-Za-z]+(\d*|\*))*)\s*(?P=quote)(?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 self.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
94
95    def convert(self, outformat, appliEficas=None):
96
97
98       from Accas import A_BLOC, A_FACT, A_SIMP
99       try :
100         self.dicoCasToCata = appliEficas.readercata.dicoCasToCata
101       except :
102         self.dicoCasToCata = {}
103         print ('pas de dicoCasToCata')
104       self.dicoInverse              = appliEficas.readercata.dicoInverse
105       self.dicoMC                   = appliEficas.readercata.dicoMC
106       self.Ordre_Des_Commandes      = appliEficas.readercata.Ordre_Des_Commandes
107       try :
108         self.TelemacdicoEn            = appliEficas.readercata.TelemacdicoEn
109       except :
110         self.TelemacdicoEn = {}
111         print('pas de TelemacdicoEn')
112       try :
113         self.DicoEnumCasFrToEnumCasEn = appliEficas.readercata.DicoEnumCasFrToEnumCasEn
114       except :
115         self.DicoEnumCasFrToEnumCasEn = {}
116         print ('pas de DicoEnumCasFrToEnumCasEn')
117
118
119       if appliEficas.langue=='fr' :
120           #from enum_Telemac2d_auto       import DicoEnumCasFrToEnumCasEn
121           for k in self.DicoEnumCasFrToEnumCasEn :
122               self.TelemacdicoEn[k]=self.DicoEnumCasFrToEnumCasEn[k]
123
124       text=""
125       self.dictSimp={}
126
127       l_lignes_texte_all = self.text.split('\n')
128       l_lignes_texte = []
129       listeComment = []
130       dicoComment={}
131       dicoCommentSimp={}
132       dicoCommentMC={}
133       texteComment=""
134       debut=True
135       trouveComment = 0
136       for l  in l_lignes_texte_all :
137         if pattern_eta.match(l) : continue
138         if pattern_fin.match(l) : continue
139         if pattern_blanc.match(l) : continue
140
141         if not(pattern_comment_slash.match(l)):
142               l_lignes_texte.append(l)
143               if trouveComment :
144                  if debut:  dicoComment['debut']=texteComment
145                  else : dicoComment[l]=texteComment
146                  trouveComment = 0
147                  texteComment=""
148               if debut : debut = False
149
150         if pattern_comment_slash.match(l):
151              #if pattern_comment_slash_vide.match(l) : continue
152              if pattern_comment_tiret.match(l) : continue
153              texteComment+=l.replace ('/','',1)
154              texteComment+='\n'
155              trouveComment=1
156
157       if texteComment != "" : dicoComment['fin']= texteComment
158
159
160       l_lignes=[]
161       i=0
162       while (i < len(l_lignes_texte)) :
163           ligne=l_lignes_texte[i]
164           i=i+1
165           if not(pattern_finit_par_virgule_ou_affect.match(ligne)):
166              l_lignes.append(ligne)
167              continue
168           nouvelle_ligne=ligne
169           while (i < len(l_lignes_texte)):
170              ligne_traitee=l_lignes_texte[i]
171              i=i+1
172              nouvelle_ligne += ligne_traitee
173              if not(pattern_finit_par_virgule_ou_affect.match(ligne_traitee)):
174                 l_lignes.append(nouvelle_ligne)
175                 break
176
177
178       for ligne in l_lignes :
179           if pattern_comment_slash.match(ligne) : continue
180           #PN : deja teste
181           #if pattern_eta.match(ligne) : continue
182           #if pattern_fin.match(ligne) : continue
183           #if pattern_blanc.match(ligne) : continue
184
185
186           finLigne=ligne
187           while finLigne != "" :
188               if pattern_comment_slash.match(finLigne) : finLigne=""; continue
189               valeur=""
190               if pattern_variables.match(finLigne) :
191                  m=pattern_variables.match(finLigne)
192                  simpCas=self.traiteIdent(m.group('ident'))
193                  if simpCas in ["COUPLING WITH", "COUPLAGE AVEC"]:
194                      if "," in m.group('valeur'):
195                          valeur=m.group('valeur').split(",")
196                      else:
197                          valeur=m.group('valeur').split(";")
198                  else:
199                      valeur=m.group('valeur')
200                  finLigne=m.group('reste')
201                  self.dictSimp[simpCas]=valeur
202                  continue
203
204
205               m=pattern_ligne.match(finLigne)
206               if m == None :
207                  #print( "________________________________________________")
208                  print ('pb avec ****', finLigne , '**** dans ', ligne)
209                  #print( "________________________________________________")
210                  break
211
212               simpCas=self.traiteIdent(m.group('ident'))
213               if not simpCas :
214                  finLigne=m.group('reste')
215                  continue
216
217               finLigne=m.group('reste')
218               # attention, l ordre des if est important
219               if pattern_liste.match(finLigne) :
220                  m=pattern_liste.match(finLigne)
221               elif pattern_liste_texte.match(finLigne) :
222                  m=pattern_liste_texte.match(finLigne)
223               elif pattern_texteQuote.match(finLigne) :
224                  m=pattern_texteQuote.match(finLigne)
225               elif pattern_flottant.match(finLigne) :
226                  m=pattern_flottant.match(finLigne)
227               elif pattern_texteVide.match(finLigne):
228                  m=pattern_texteVide.match(finLigne)
229               elif pattern_texteSimple.match(finLigne):
230                  m=pattern_texteSimple.match(finLigne)
231               else :
232                  #print ("________________________________________________")
233                  print ('pb avec ****', finLigne , '**** dans ', ligne)
234                  print ("non match")
235                  #print ("________________________________________________")
236                  break
237
238
239               valeur=m.group('valeur')
240               if pattern_blanc.match(valeur) : valeur=None
241
242               if pattern_flottant.match(finLigne) :
243                  valeur=re.sub("d","e",valeur)
244                  valeur=re.sub("D","E",valeur)
245
246               if pattern_liste.match(finLigne) or \
247                  pattern_liste_texte.match(finLigne):
248                  valeur=valeur.split(";")
249
250
251               finLigne=m.group('reste')
252               self.dictSimp[simpCas]=valeur
253
254               if ligne in dicoComment.keys():
255                  dicoCommentSimp[simpCas]=dicoComment[ligne]
256
257       if 'TITLE' not in self.dictSimp :
258           import os
259           #self.dictSimp['TITLE']=os.path.basename(self.filename)
260
261
262       dicoParMC={}
263       for simp in self.dictSimp:
264           if simp in TELEMACparser.__dict__ : TELEMACparser.__dict__[simp](self,)
265
266       for simp in self.dictSimp:
267           if simp not in self.dicoInverse :
268              #print ( "************")
269              print  ("pb avec dans dicoInverse", simp,'------')
270              print("dicoInverse",sorted(self.dicoInverse.keys()))
271              #print  ("************")
272              continue
273           listeGenea=self.dicoInverse[simp]
274           listeGeneaReverse=[]
275           for (u,v) in listeGenea :
276               if isinstance(v,A_BLOC.BLOC): continue
277               listeGeneaReverse.append(u)
278           listeGeneaReverse.reverse()
279           dicoTravail=dicoParMC
280           i=0
281           if simp in dicoCommentSimp :
282              MC=listeGeneaReverse[0]
283              if MC in dicoCommentMC : dicoCommentMC[MC]+dicoCommentSimp[simp]
284              else                   : dicoCommentMC[MC]=dicoCommentSimp[simp]
285           while i < len(listeGeneaReverse[0:-1]) :
286             mot=listeGeneaReverse[i]
287             i=i+1
288             if mot not in dicoTravail: dicoTravail[mot]={}
289             dicoTravail=dicoTravail[mot]
290           dicoTravail[simp]=self.dictSimp[simp]
291
292       self.textePy=""
293       listeMC=self.tri(list(dicoParMC.keys()))
294       for k in listeMC :
295           if k in dicoCommentMC :
296                 commentaire="COMMENTAIRE("+repr(dicoCommentMC[k])+")\n"
297                 self.textePy+=commentaire
298           self.textePy += str(k )+ "("
299           self.traiteMC(dicoParMC[k])
300           self.textePy += ");\n"
301
302
303       # ne sert plus
304       #appliEficas.listeTelemac=self.dictSimp
305       appliEficas.listeTelemac={}
306       if 'debut' in dicoComment :
307           commentaire="COMMENTAIRE("+repr(dicoComment['debut'])+")\n"
308           self.textePy=commentaire+self.textePy
309       if 'fin' in dicoComment :
310           commentaire="COMMENTAIRE("+repr(dicoComment['fin'])+")\n"
311           self.textePy=self.textePy+commentaire
312
313       #print (self.textePy)
314       return self.textePy
315
316
317    #----------------------------------------
318    def traiteIdent(self,ident):
319    # enleve les espaces de part et autre
320    # traduit du langage Telemac vers le langage Catalogue
321    #----------------------------------------
322           while ident[-1] == " " or ident[-1] == '\t' : ident=ident[0:-1]
323           while ident[0]  == " " or ident[0]  == '\t' : ident=ident[1:]
324           try : identCata=self.dicoCasToCata[ident]
325           except :
326             print ( "---> ", "pb mot clef  pour", ident)
327             identCata=None
328           return identCata
329
330
331    def traiteMC(self,dico) :
332        from Accas import A_BLOC, A_FACT, A_SIMP
333        for k in dico :
334            valeur= dico[k]
335            if k not in self.dicoMC : kA=self.dicoFrancaisAnglais[k]
336            else : kA=k
337            obj=self.dicoMC[kA]
338            if isinstance(obj,A_FACT.FACT):   self.convertFACT(obj,kA,valeur)
339            elif isinstance(obj,A_BLOC.BLOC): self.convertBLOC(obj,kA,valeur)
340            elif isinstance(obj,A_SIMP.SIMP): self.convertSIMP(obj,kA,valeur)
341            else : print ("%%%%%%%%%%%\n", "pb conversion type pour", k, obj, "\n%%%%%%%%%%%")
342
343
344    def convertFACT(self,obj,nom,valeur):
345        # traitement LIQUID_BOUNDARIES
346        if nom in TELEMACparser.__dict__ :
347           TELEMACparser.__dict__[nom](self,)
348           return
349        self.textePy +=  nom + "=_F( "
350        self.traiteMC(valeur)
351        self.textePy += '),\n'
352
353
354    def convertBLOC(self,obj,nom,valeur):
355        print ("ANOMALIE _________ BLOC ")
356        print (nom)
357
358    def convertSIMP(self,obj,nom,valeur):
359        #print ('in convertSIMP', nom,valeur)
360        #if nom in ("PRESCRIBED_FLOWRATES", "PRESCRIBED_VELOCITIES", "PRESCRIBED_ELEVATIONS" ): return
361        if obj.max==1 :
362           if hasattr(obj.type[0],'ntuple') :
363              lval=[]
364              for v in valeur :
365                try :    v=eval(v,{})
366                except : pass
367                lval.append(v)
368              self.textePy += nom + "=" + str(lval) +","
369              return
370           if 'TXM' in obj.type :
371
372               if pattern_ContientDouble.match(str(valeur)):
373                  valeur=re.sub("''","\'\'",str(valeur))
374                  self.textePy += nom + "=" + str(valeur) +","
375                  return
376               valeur=str(valeur)
377
378               # ceinture et bretelle si les re sont correctes -)
379               while valeur[-1] == " " or valeur[-1] == '\t' : valeur=valeur[0:-1]
380               while valeur[0]  == " " or valeur[0]  == '\t' : valeur=valeur[1:]
381
382
383
384           # Pour les enum
385           try    : valeur=eval(valeur,{})
386           except : pass
387
388           if nom in self.TelemacdicoEn:
389              try    :
390                valeur=self.TelemacdicoEn[nom][valeur]
391                self.textePy += nom + "= '" + str(valeur) +"',"
392                return
393              except : pass
394
395
396           if obj.into != [] and obj.into != None and not('R' in obj.type) and not('I' in obj.type):
397              for possible in obj.into :
398                 try :
399                   if possible.upper() == valeur.upper():
400                      valeur=possible
401                      break
402                   v=valeur[0].upper()+valeur[1:].lower()
403                   v2=tr(v)
404                   if possible.upper() == v2.upper():
405                      valeur=possible
406                      break
407                 except:
408                    if valeur != None :
409                       print ("pb avec le type de ", obj.nom, obj.type, 'et la valeur ', valeur)
410
411           if 'Fichier' in obj.type or 'TXM' in obj.type or 'Repertoire' in obj.type or 'FichierOuRepertoire' in obj.type :
412               valeur=str(valeur)
413               if valeur == "" or valeur == " " :
414                  self.textePy += nom + "= '" + str(valeur) +"' ,"
415                  return
416               while valeur[-1] == " " : valeur=valeur[0:-1]
417               while valeur[0]  == " " : valeur=valeur[1:]
418               self.textePy += nom + "= '" + str(valeur) +"' ,"
419               return
420
421           if bool in obj.type :
422             if   valeur == True  :  self.textePy += nom + "= True,"
423             elif valeur == False :  self.textePy += nom + "= False,"
424             elif pattern_oui.match(valeur) : self.textePy += nom + "= True,"
425             elif pattern_non.match(valeur) : self.textePy += nom + "= False,"
426             else :  self.textePy += nom + "= None,"
427             return
428           self.textePy += nom + "=" + str(valeur) +","
429
430        else :
431           if valeur == () or valeur ==[] or pattern_listeVide.match(str(valeur)) :
432              self.textePy += nom + "= None,"
433              return
434
435           # les 4 lignes suivantes sont probablement inutiles
436           while valeur[-1] == " " or  valeur[-1]=="'" : valeur=valeur[0:-1]
437           while valeur[0]  == " " or  valeur[-0]=="'" : valeur=valeur[1:]
438           oldValeur=valeur
439           if isinstance(valeur, basestring) :
440              if   ";" in valeur : valeur=valeur.split(';')
441              else  : valeur=valeur.split(',')
442
443           if len(valeur)< 2 and pattern_flottant.match(oldValeur):
444           # Attention : on attend une liste mais on a une seule valeur!
445              try :    oldValeur=eval(oldValeur,{})
446              except : pass
447              if nom in self.TelemacdicoEn :
448                 v=self.TelemacdicoEn[nom][oldValeur]
449                 self.textePy += nom + "= ('" + str(v) +"',),"
450              else :
451                 self.textePy += nom + "= (" + str(oldValeur) +",),"
452              return
453
454           # Cas des liste de boolĂ©en
455           if bool in obj.type:
456             values = []
457             for val in valeur:
458               if val == True or pattern_oui.match(val) or val == 'True':
459                 values.append('True')
460               elif val == False or pattern_non.match(val) or val == 'False':
461                 values.append('False')
462               else:
463                 values.append('None')
464             self.textePy += nom + "= [" + ','.join(values) + '],'
465             return
466
467
468           if valeur == None : return
469           newVal=[]
470           for v in valeur :
471             try :    v=eval(v,{})
472             except : pass
473             if nom in self.TelemacdicoEn:
474                try    : v=self.TelemacdicoEn[nom][v]
475                except : pass
476             newVal.append(v)
477           self.textePy += nom + "=" + str(newVal) +","
478
479
480
481    def tri(self, listeIn):
482       if len(listeIn) == 1 : return listeIn
483       if self.Ordre_Des_Commandes == None : return listeIn
484       listeOut=[listeIn[0],]
485       for k in listeIn[1:]:
486           #k=str(self.dicoFrancaisAnglais[kF])
487           ordreK=self.Ordre_Des_Commandes.index(k)
488           i=0
489           while i < len(listeOut):
490              #ordreI=self.Ordre_Des_Commandes.index(self.dicoFrancaisAnglais[listeOut[i]])
491              ordreI=self.Ordre_Des_Commandes.index(listeOut[i])
492              if ordreK < ordreI : break
493              i=i+1
494           #listeOut.insert(i,kF)
495           listeOut.insert(i,k)
496       return listeOut