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