Salome HOME
PN : pour prendre en compte le nouveau panneau : UNIQUE_ASSD_Panel_Reel
[tools/eficas.git] / Minicode / ops.py
1 # -*- coding: utf-8 -*-
2 #@ MODIF ops Cata  DATE 06/09/2003   AUTEUR D6BHHJP J.P.LEFEBVRE 
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2001  EDF R&D                  WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR   
9 # (AT YOUR OPTION) ANY LATER VERSION.                                 
10 #
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT 
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF          
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU    
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.                            
15 #
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE   
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,       
18 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.      
19 # ======================================================================
20
21 # Modules Python
22 import types
23 import string,linecache,os,traceback,re
24
25 # Modules Eficas
26 import Accas
27 from Accas import ASSD
28 from Noyau.N_FONCTION import formule
29
30 try:
31    import aster
32    # Si le module aster est présent, on le connecte
33    # au JDC
34    import Build.B_CODE
35    Build.B_CODE.CODE.codex=aster
36 except:
37    pass
38
39 def DEBUT(self,PAR_LOT,CODE,**args):
40    """
41        Fonction sdprod de la macro DEBUT
42    """
43    # La commande DEBUT ne peut exister qu'au niveau jdc
44    if self.jdc is not self.parent :
45       raise Accas.AsException("La commande DEBUT ne peut exister qu'au niveau jdc")
46
47    self.jdc.set_par_lot(PAR_LOT)
48    if CODE!=None :
49       self.jdc.fico=CODE['NOM']
50    else:
51       self.jdc.fico=None
52
53 def build_debut(self,**args):
54    """
55    Fonction ops pour la macro DEBUT
56    """
57    self.jdc.UserError=self.codex.error
58
59    if self.jdc.par_lot == 'NON' :
60       self.jdc._Build()
61    # On execute la fonction debut pour initialiser les bases
62    # Cette execution est indispensable avant toute autre action sur ASTER
63    # op doit etre un entier car la fonction debut appelle GCECDU qui demande
64    # le numero de l'operateur associé (getoper)
65    self.definition.op=0
66    self.set_icmd(1)
67    lot,ier=self.codex.debut(self,1)
68    # On remet op a None juste apres pour eviter que la commande DEBUT
69    # ne soit executée dans la phase d'execution
70    self.definition.op=None
71    return ier
72
73 def POURSUITE(self,PAR_LOT,CODE,HDF,**args):
74    """
75        Fonction sdprod de la macro POURSUITE
76    """
77    # La commande POURSUITE ne peut exister qu'au niveau jdc
78    if self.jdc is not self.parent :
79       raise Accas.AsException("La commande POURSUITE ne peut exister qu'au niveau jdc")
80
81    self.jdc.set_par_lot(PAR_LOT)
82    if CODE!=None :
83       self.jdc.fico=CODE['NOM']
84    else:
85       self.jdc.fico=None
86    if (self.codex and os.path.isfile("glob.1")) or HDF!=None:
87      # Le module d'execution est accessible et glob.1 est present
88      # Pour eviter de rappeler plusieurs fois la sequence d'initialisation
89      # on memorise avec l'attribut fichier_init que l'initialisation
90      # est réalisée
91      if hasattr(self,'fichier_init'):return
92      self.fichier_init='glob.1'
93      self.jdc.initexec()
94      # le sous programme fortran appelé par self.codex.poursu demande le numero
95      # de l'operateur (GCECDU->getoper), on lui donne la valeur 0
96      self.definition.op=0
97      lot,ier,lonuti,concepts=self.codex.poursu(self,1)
98      # Par la suite pour ne pas executer la commande pendant la phase
99      # d'execution on le remet à None
100      self.definition.op=None
101      # On demande la numerotation de la commande POURSUITE avec l'incrément
102      # lonuti pour qu'elle soit numérotée à la suite des commandes existantes.
103      self.set_icmd(lonuti)
104      pos=0
105      d={}
106      while pos+80 < len(concepts)+1:
107        nomres=concepts[pos:pos+8]
108        concep=concepts[pos+8:pos+24]
109        nomcmd=concepts[pos+24:pos+40]
110        statut=concepts[pos+40:pos+48]
111        print nomres,concep,nomcmd,statut
112        if nomres[0] not in (' ','.','&') and statut != '&DETRUIT':
113           exec nomres+'='+string.lower(concep)+'()' in self.parent.g_context,d
114        pos=pos+80
115      for k,v in d.items():
116        self.parent.NommerSdprod(v,k)
117      self.g_context=d
118      return
119    else:
120      # Si le module d'execution n est pas accessible ou glob.1 absent on 
121      # demande un fichier (EFICAS)
122      # Il faut éviter de réinterpréter le fichier à chaque appel de
123      # POURSUITE
124      if hasattr(self,'fichier_init'):
125         return
126      self.make_poursuite()
127
128 def POURSUITE_context(self,d):
129    """
130        Fonction op_init de la macro POURSUITE
131    """
132    # self représente la macro POURSUITE ...
133    d.update(self.g_context)
134    # Une commande POURSUITE n'est possible qu'au niveau le plus haut
135    # On ajoute directement les concepts dans le contexte du jdc
136    # XXX est ce que les concepts ne sont pas ajoutés plusieurs fois ??
137    for v in self.g_context.values():
138       if isinstance(v,ASSD) : self.jdc.sds.append(v)
139
140 def build_poursuite(self,**args):
141    """
142    Fonction ops pour la macro POURSUITE
143    """
144    # Pour POURSUITE on ne modifie pas la valeur initialisee dans ops.POURSUITE
145    # Il n y a pas besoin d executer self.codex.poursu (c'est deja fait dans
146    # la fonction sdprod de la commande (ops.POURSUITE))
147    self.jdc.UserError=self.codex.error
148    return 0
149
150 def INCLUDE(self,UNITE,**args):
151    """ 
152        Fonction sd_prod pour la macro INCLUDE
153    """
154    if not UNITE : return
155    if hasattr(self,'unite'):return
156    self.unite=UNITE
157
158    if self.jdc and self.jdc.par_lot == 'NON':
159       # On est en mode commande par commande, on appelle la methode speciale
160       self.Execute_alone()
161
162    self.make_include(unite=UNITE)
163
164 def INCLUDE_context(self,d):
165    """ 
166        Fonction op_init pour macro INCLUDE
167    """
168    for k,v in self.g_context.items():
169       d[k]=v
170
171 def build_include(self,**args):
172    """
173    Fonction ops de la macro INCLUDE appelée lors de la phase de Build
174    """
175    # Pour presque toutes les commandes (sauf FORMULE et POURSUITE)
176    # le numero de la commande n est pas utile en phase de construction
177    # La macro INCLUDE ne sera pas numérotée (incrément=None)
178    ier=0
179    self.set_icmd(None)
180    icmd=0
181    # On n'execute pas l'ops d'include en phase BUILD car il ne sert a rien.
182    #ier=self.codex.opsexe(self,icmd,-1,1)
183    return ier
184
185 def detruire(self,d):
186    """
187        Cette fonction est la fonction op_init de la PROC DETRUIRE
188    """
189    if self["CONCEPT"]!=None:
190      sd=[]
191      for mc in self["CONCEPT"]:
192        mcs=mc["NOM"]
193        if type(mcs) == types.ListType or type(mcs) == types.TupleType:
194          for e in mcs:
195            if isinstance(e,ASSD):
196              sd.append(e)
197              e=e.nom
198            if d.has_key(e):del d[e]
199            if self.jdc.sds_dict.has_key(e):del self.jdc.sds_dict[e]
200        else:
201 #CCAR: ajout de ce test pour ne pas détruire une formule. Faut-il le reintegrer 
202 #      dans le catalogue d'Aster ? Est-il spécial EFICAS ?
203          if isinstance(mcs,formule):
204            cr=self.parent.report()
205            cr.fatal("la destruction d'une FORMULE est impossible" )
206 #CCAR: fin ajout
207          if isinstance(mcs,ASSD):
208            sd.append(mcs)
209            mcs=mcs.nom
210          if d.has_key(mcs):del d[mcs]
211          if self.jdc.sds_dict.has_key(mcs):del self.jdc.sds_dict[mcs]
212      for s in sd:
213        # On signale au parent que le concept s n'existe plus apres l'étape self
214        self.parent.delete_concept_after_etape(self,s)
215
216 def subst_materiau(text,NOM_MATER,EXTRACTION,UNITE_LONGUEUR):
217    """
218        Cette fonction retourne un texte obtenu à partir du texte passé en argument (text)
219        en substituant le nom du materiau par NOM_MATER 
220        et en réalisant les extractions spéciifées dans EXTRACTION
221    """
222    lines=string.split(text,'\n')
223
224 ##### traitement de UNIT : facteur multiplicatif puissance de 10
225    regmcsu=re.compile(r" *(.*) *= *([^ ,]*) *## +([^ ]*) *([^ ]*)")
226    ll_u=[]
227    for l in lines:
228        m=regmcsu.match(l)
229        if m:
230           if m.group(3) == "UNIT":
231              if   UNITE_LONGUEUR=='M'  : coef = '0'
232              elif UNITE_LONGUEUR=='MM' : coef = m.group(4)
233              print ' UNITE_LONGUEUR = BINGO'
234              print ' UNITE_LONGUEUR = ',m.group(4),type(m.group(4))
235              ll_u.append('   '+m.group(1)+" = "+m.group(2)+coef)
236           else : ll_u.append(l)
237        else : ll_u.append(l)
238
239 ##### traitement de EXTRACTION
240    if EXTRACTION:
241      regmcf=re.compile(r" *(.*) *= *_F\( *## +(.*) +(.*)")
242      regmcs=re.compile(r" *(.*) *= *([^ ,]*) *, *## +([^ ]*) *([^ ]*)")
243      regfin=re.compile(r" *\) *")
244      ll=[]
245      temps={};lmcf=[]
246      for e in EXTRACTION:
247        mcf=e['COMPOR']
248        lmcf.append(mcf)
249        temps[mcf]=e['TEMP_EVAL']
250      FLAG=0
251      for l in ll_u:
252        m=regmcf.match(l)
253        if m: # On a trouve un mot cle facteur "commentarise"
254          if m.group(2) == "SUBST": # il est de plus substituable
255            if temps.has_key(m.group(3)): # Il est a substituer
256              ll.append(" "+m.group(3)+"=_F(")
257              mcf=m.group(3)
258              TEMP=temps[mcf]
259              FLAG=1 # Indique que l'on est en cours de substitution
260            else: # Il n est pas a substituer car il n est pas dans la liste demandee
261              ll.append(l)
262          else: # Mot cle facteur commentarise non substituable
263            ll.append(l)
264        else:  # La ligne ne contient pas un mot cle facteur commentarise
265          if FLAG == 0: # On n est pas en cours de substitution
266            ll.append(l)
267          else: # On est en cours de substitution. On cherche les mots cles simples commentarises
268            m=regmcs.match(l)
269            if m: # On a trouve un mot cle simple commentarise
270              if m.group(3) == "EVAL":
271                ll.append("  "+m.group(1)+' = EVAL("'+m.group(4)+"("+str(TEMP)+')"),')
272              elif m.group(3) == "SUPPR":
273                pass
274              else:
275                ll.append(l)
276            else: # On cherche la fin du mot cle facteur en cours de substitution
277              m=regfin.match(l)
278              if m: # On l a trouve. On le supprime de la liste
279                FLAG=0
280                del temps[mcf]
281              ll.append(l)
282    else:
283      ll=ll_u
284
285    for l in ll:
286      print l
287    lines=ll
288    ll=[]
289    for l in lines:
290      l=re.sub(" *MAT *= *",NOM_MATER+" = ",l,1)
291      ll.append(l)
292    text=string.join(ll,'\n')
293    return text
294
295 def post_INCLUDE(self):
296   """
297       Cette fonction est executée apres toutes les commandes d'un INCLUDE (RETOUR)
298       Elle sert principalement pour les INCLUDE_MATERIAU : remise a blanc du prefixe Fortran
299   """
300   self.codex.opsexe(self,0,-1,2)
301
302 def INCLUDE_MATERIAU(self,NOM_AFNOR,TYPE_MODELE,VARIANTE,TYPE_VALE,NOM_MATER,
303                     EXTRACTION,UNITE_LONGUEUR,INFO,**args):
304   """ 
305       Fonction sd_prod pour la macro INCLUDE_MATERIAU
306   """
307   mat=string.join((NOM_AFNOR,'_',TYPE_MODELE,'_',VARIANTE,'.',TYPE_VALE),'')
308   if not hasattr(self,'mat') or self.mat != mat or self.nom_mater != NOM_MATER :
309     # On récupère le répertoire des matériaux dans les arguments 
310     # supplémentaires du JDC
311     rep_mat=self.jdc.args.get("rep_mat","NOrep_mat")
312     f=os.path.join(rep_mat,mat)
313     self.mat=mat
314     self.nom_mater=NOM_MATER
315     if not os.path.isfile(f):
316        del self.mat
317        self.make_contexte(f,"#Texte sans effet pour reinitialiser le contexte a vide\n")
318        raise "Erreur sur le fichier materiau: "+f
319     # Les materiaux sont uniquement disponibles en syntaxe Python
320     # On lit le fichier et on supprime les éventuels \r
321     text=string.replace(open(f).read(),'\r\n','\n')
322     # On effectue les substitutions necessaires
323     self.prefix=NOM_MATER
324     self.text= subst_materiau(text,NOM_MATER,EXTRACTION,UNITE_LONGUEUR)
325     if INFO == 2:
326       print "INCLUDE_MATERIAU: ", self.mat,' ',NOM_MATER,'\n'
327       print self.text
328     # on execute le texte fourni dans le contexte forme par
329     # le contexte de l etape pere (global au sens Python)
330     # et le contexte de l etape (local au sens Python)
331     # Il faut auparavant l'enregistrer aupres du module linecache (utile pour nommage.py)
332     linecache.cache[f]=0,0,string.split(self.text,'\n'),f
333
334     self.postexec=post_INCLUDE
335
336     if self.jdc.par_lot == 'NON':
337       # On est en mode commande par commande, on appelle la methode speciale
338       self.Execute_alone()
339
340     self.make_contexte(f,self.text)
341
342 def build_formule(self,**args):
343   """
344   Fonction ops de la macro FORMULE appelée lors de la phase de Build
345   """
346   from Build import B_utils
347   for mc in self.mc_liste:
348 ###    if mc.nom in ('REEL','ENTIER','COMPLEXE'):
349     if mc.nom in ('REEL','COMPLEXE'):
350       texte= self.sd.get_name()+ string.strip(mc.valeur)
351       mc.valeur=B_utils.ReorganisationDe(texte,80)
352   # ATTENTION : FORMULE est une des rares commandes qui a besoin de
353   # connaitre son numero d execution avant d etre construite
354   self.set_icmd(1)
355   # La macro formule doit etre executee. Seules les macros qui ont
356   # un numero d'op sont executees lors des phases suivantes
357   self.definition.op = -5
358   ier=self.codex.opsexe(self,self.icmd,-1,-self.definition.op)
359   return ier
360
361 def build_procedure(self,**args):
362     """
363     Fonction ops de la macro PROCEDURE appelée lors de la phase de Build
364     """
365     ier=0
366     # Pour presque toutes les commandes (sauf FORMULE et POURSUITE)
367     # le numero de la commande n est pas utile en phase de construction
368     # On ne numérote pas une macro PROCEDURE (incrément=None)
369     self.set_icmd(None)
370     icmd=0
371     #ier=self.codex.opsexe(self,icmd,-1,3)
372     return ier
373
374 def build_retour(self,**args):
375     """
376     Fonction ops de la macro RETOUR appelée lors de la phase de Build
377     """
378     ier=0
379     # Pour presque toutes les commandes (sauf FORMULE et POURSUITE)
380     # le numero de la commande n est pas utile en phase de construction
381     # On ne numérote pas une macro RETOUR (incrément=None)
382     self.set_icmd(None)
383     icmd=0
384     #ier=self.codex.opsexe(self,icmd,-1,2)
385     return ier
386