Salome HOME
Update version
[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 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