Salome HOME
This commit was generated by cvs2git to track changes on a CVS vendor
[tools/eficas.git] / Noyau / nommage.py
1 #@ MODIF nommage Noyau  DATE 27/03/2002   AUTEUR DURAND C.DURAND 
2 #            CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR   
8 # (AT YOUR OPTION) ANY LATER VERSION.                                 
9 #
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT 
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF          
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU    
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.                            
14 #
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE   
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,       
17 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.      
18 #                                                                       
19 #                                                                       
20 # ======================================================================
21 """
22    Ce module sert à nommer les concepts produits par les commandes.
23    Le nom du concept est obtenu en appelant la fonction GetNomConceptResultat
24    du module avec le nom de la commande en argument.
25    
26    Cette fonction parcourt le source dans lequel la commande se trouve, parse le
27    fichier et retrouve le nom du concept qui se trouve à gauche du signe = précédant
28    le nom de la commande.
29
30    Cette fonction utilise la fonction cur_frame du module N_utils qui retourne la frame
31    d'exécution Python située 2 niveaux au-dessus. C'est à partir de cette frame que
32    l'on retrouve le fichier source et le numéro de ligne où se trouve l'appel à la commande.
33
34 """
35
36 # Modules Python
37 import re,string
38 import linecache
39
40 # Modules EFICAS
41 import N_utils
42
43 regex1='=\s*%s\s*\('
44
45 def GetNomConceptResultat(ope):
46   """
47      Cette fonction recherche dans la pile des appels, l'appel à la commande
48      qui doit etre situé à 2 niveaux au-dessus (cur_frame(2)).
49      On retrouve d'abord la frame d'exécution f. Puis le numéro de la ligne
50      dans le source f.f_lineno et le nom du fichier source (f.f_code.co_filename).
51      A partir de là, on récupère la ligne de source avec linecache.getline
52      et on vérifie que cette ligne correspond véritablement à l'appel.
53
54      En effet, lorsque les commandes tiennent sur plusieurs lignes, on retrouve
55      la dernière ligne. Il faut donc remonter dans le source jusqu'à la première 
56      ligne.
57
58      Enfin la fonction evalnom forme un nom acceptable lorsque le concept est un
59      élément d'une liste, par exemple.
60
61   """
62   f=N_utils.cur_frame(2)
63   lineno = f.f_lineno     # XXX Too bad if -O is used
64   #lineno = f_lineno(f)  # Ne marche pas toujours
65   co = f.f_code
66   filename = co.co_filename
67   name = co.co_name
68   #print "NOMOP,FICHIER, LIGNE ",ope,filename,lineno
69   line = linecache.getline(filename, lineno)
70   if not line: line = None
71
72   list=[]
73   list.append(line)
74   while lineno > 0:
75     #print "LIGNE ",line
76     if re.search(regex1 % ope,line):
77       l=re.split(regex1 % ope,line)
78       list.reverse()
79       #print "COMMANDE ",string.join(list)
80       #print "SPLIT ",l
81       # On suppose que le concept resultat a bien ete
82       # isole en tete de la ligne de source
83       m=evalnom(string.strip(l[0]),f.f_locals)
84       #print "NOMS ",m
85       return m[-1]
86     lineno=lineno-1
87     line = linecache.getline(filename, lineno)
88     list.append(line)
89   #print "appel inconnu"
90   return ""
91
92 def evalnom(text,d):
93   """
94    Retourne un nom pour le concept resultat identifie par text
95    Pour obtenir ce nom il y a plusieurs possibilites :
96     1-text est un identificateur python c est le nom du concept
97     2-text est un element d une liste on construit le nom en
98       evaluant la partie indice dans le contexte de l appelant d
99   """
100   l=re.split('([\[\]]+)',text)
101   #print l
102   if l[-1] == '' :l=l[:-1]
103   lll=[]
104   i=0
105   while i<len(l):
106     s=l[i]
107     ll=string.split(s,',')
108     ll=re.split('[ ,]+',s)
109     if ll[0] == '' :ll=ll[1:]
110     if len(ll) == 1:
111       id0=ll[0]
112     else:
113       lll=lll+ll[0:-1]
114       id0=ll[-1]
115     if i+1<len(l) and l[i+1] == '[': # le nom est suivi d un subscript
116       sub=l[i+2]
117       nom=id0+'_'+str(eval(sub,d))
118       i=i+4
119     else:
120       nom=id0
121       i=i+1
122     lll.append(nom)
123   return lll
124
125 def f_lineno(f):
126    """
127       Calcule le numero de ligne courant
128       Devrait marcher meme avec -O
129       Semble ne pas marcher en présence de tuples longs
130    """
131    c=f.f_code
132    if not hasattr(c, 'co_lnotab'):return f.f_lineno
133    tab=c.co_lnotab
134    line = c.co_firstlineno
135    stopat = f.f_lasti
136    addr = 0
137    for i in range(0, len(tab), 2):
138        addr = addr + ord(tab[i])
139        if addr > stopat:
140            break
141        line = line + ord(tab[i+1])
142    return line
143