Salome HOME
*** empty log message ***
[tools/eficas.git] / Noyau / nommage.py
1 # -*- coding: utf-8 -*-
2 #@ MODIF nommage Noyau  DATE 18/03/2003   AUTEUR VABHHTS J.PELLET 
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2002  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 # ======================================================================
22 """
23    Ce module sert à nommer les concepts produits par les commandes.
24    Le nom du concept est obtenu en appelant la fonction GetNomConceptResultat
25    du module avec le nom de la commande en argument.
26    
27    Cette fonction parcourt le source dans lequel la commande se trouve, parse le
28    fichier et retrouve le nom du concept qui se trouve à gauche du signe = précédant
29    le nom de la commande.
30
31    Cette fonction utilise la fonction cur_frame du module N_utils qui retourne la frame
32    d'exécution Python située 2 niveaux au-dessus. C'est à partir de cette frame que
33    l'on retrouve le fichier source et le numéro de ligne où se trouve l'appel à la commande.
34
35 """
36
37 # Modules Python
38 import re,string
39 import linecache
40
41 # Modules EFICAS
42 import N_utils
43
44 regex1='=?\s*%s\s*\('
45
46 def GetNomConceptResultat(ope):
47   """
48      Cette fonction recherche dans la pile des appels, l'appel à la commande
49      qui doit etre situé à 2 niveaux au-dessus (cur_frame(2)).
50      On retrouve d'abord la frame d'exécution f. Puis le numéro de la ligne
51      dans le source f.f_lineno et le nom du fichier source (f.f_code.co_filename).
52      A partir de là, on récupère la ligne de source avec linecache.getline
53      et on vérifie que cette ligne correspond véritablement à l'appel.
54
55      En effet, lorsque les commandes tiennent sur plusieurs lignes, on retrouve
56      la dernière ligne. Il faut donc remonter dans le source jusqu'à la première 
57      ligne.
58
59      Enfin la fonction evalnom forme un nom acceptable lorsque le concept est un
60      élément d'une liste, par exemple.
61
62   """
63   f=N_utils.cur_frame(2)
64   lineno = f.f_lineno     # XXX Too bad if -O is used
65   #lineno = f_lineno(f)  # Ne marche pas toujours
66   co = f.f_code
67   filename = co.co_filename
68   name = co.co_name
69   #print "NOMOP,FICHIER, LIGNE ",ope,filename,lineno
70   line = linecache.getline(filename, lineno)
71   if not line: line = None
72
73   list=[]
74   list.append(line)
75   while lineno > 0:
76     #print "LIGNE ",line
77     if re.search(regex1 % ope,line):
78       l=re.split(regex1 % ope,line)
79       list.reverse()
80       #print "COMMANDE ",string.join(list)
81       #print "SPLIT ",l
82       # On suppose que le concept resultat a bien ete
83       # isole en tete de la ligne de source
84       m=evalnom(string.strip(l[0]),f.f_locals)
85       #print "NOMS ",m
86       if m!=[] :  return m[-1]
87       else : return ''
88     lineno=lineno-1
89     line = linecache.getline(filename, lineno)
90     list.append(line)
91   #print "appel inconnu"
92   return ""
93
94 def evalnom(text,d):
95   """
96    Retourne un nom pour le concept resultat identifie par text
97    Pour obtenir ce nom il y a plusieurs possibilites :
98     1-text est un identificateur python c est le nom du concept
99     2-text est un element d une liste on construit le nom en
100       evaluant la partie indice dans le contexte de l appelant d
101   """
102   l=re.split('([\[\]]+)',text)
103   #print l
104   if l[-1] == '' :l=l[:-1]
105   lll=[]
106   i=0
107   while i<len(l):
108     s=l[i]
109     ll=string.split(s,',')
110     ll=re.split('[ ,]+',s)
111     if ll[0] == '' :ll=ll[1:]
112     if len(ll) == 1:
113       id0=ll[0]
114     else:
115       lll=lll+ll[0:-1]
116       id0=ll[-1]
117     if i+1<len(l) and l[i+1] == '[': # le nom est suivi d un subscript
118       sub=l[i+2]
119       nom=id0+'_'+str(eval(sub,d))
120       i=i+4
121     else:
122       nom=id0
123       i=i+1
124     lll.append(nom)
125   return lll
126
127 def f_lineno(f):
128    """
129       Calcule le numero de ligne courant
130       Devrait marcher meme avec -O
131       Semble ne pas marcher en présence de tuples longs
132    """
133    c=f.f_code
134    if not hasattr(c, 'co_lnotab'):return f.f_lineno
135    tab=c.co_lnotab
136    line = c.co_firstlineno
137    stopat = f.f_lasti
138    addr = 0
139    for i in range(0, len(tab), 2):
140        addr = addr + ord(tab[i])
141        if addr > stopat:
142            break
143        line = line + ord(tab[i+1])
144    return line
145