1 #@ MODIF nommage Noyau DATE 25/10/2011 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 - 2011 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.
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.
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.
22 # ======================================================================
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.
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.
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.
43 from functools import partial
49 #commentaire standard precede d'un nombre quelconque de blancs (pas multiligne)
50 pattern_comment = re.compile(r"^\s*#.*")
52 def _GetNomConceptResultat(ope, level=2):
54 Cette fonction recherche dans la pile des appels, l'appel à la commande
55 qui doit etre situé à 2 niveaux au-dessus (cur_frame(2)).
56 On retrouve d'abord la frame d'exécution f. Puis le numéro de la ligne
57 dans le source f.f_lineno et le nom du fichier source (f.f_code.co_filename).
58 A partir de là, on récupère la ligne de source avec linecache.getline
59 et on vérifie que cette ligne correspond véritablement à l'appel.
61 En effet, lorsque les commandes tiennent sur plusieurs lignes, on retrouve
62 la dernière ligne. Il faut donc remonter dans le source jusqu'à la première
65 Enfin la fonction evalnom forme un nom acceptable lorsque le concept est un
66 élément d'une liste, par exemple.
69 f=N_utils.cur_frame(level)
70 lineno = f.f_lineno # XXX Too bad if -O is used
71 #lineno = f_lineno(f) # Ne marche pas toujours
73 filename = co.co_filename
75 #print "NOMOP,FICHIER, LIGNE ",ope,filename,lineno
76 #pattern pour identifier le debut de la commande
77 pattern_oper=re.compile(regex1 % ope)
81 line = linecache.getline(filename, lineno)
83 if pattern_comment.match(line):continue
86 if pattern_oper.search(line):
87 l=pattern_oper.split(line)
89 #print "COMMANDE ",string.join(list)
91 # On suppose que le concept resultat a bien ete
92 # isole en tete de la ligne de source
93 m=evalnom(string.strip(l[0]),f.f_locals)
95 if m!=[] : return m[-1]
97 #print "appel inconnu"
102 Retourne un nom pour le concept resultat identifie par text
103 Pour obtenir ce nom il y a plusieurs possibilites :
104 1. text est un identificateur python c'est le nom du concept
105 2. text est un element d'une liste on construit le nom en
106 evaluant la partie indice dans le contexte de l'appelant d
108 l=re.split('([\[\]]+)',text)
110 if l[-1] == '' :l=l[:-1]
115 ll=string.split(s,',')
116 ll=re.split('[ ,]+',s)
117 if ll[0] == '' :ll=ll[1:]
123 if i+1<len(l) and l[i+1] == '[': # le nom est suivi d un subscript
125 nom=id0+'_'+str(eval(sub,d))
135 Calcule le numero de ligne courant
136 Devrait marcher meme avec -O
137 Semble ne pas marcher en présence de tuples longs
140 if not hasattr(c, 'co_lnotab'):return f.f_lineno
142 line = c.co_firstlineno
145 for i in range(0, len(tab), 2):
146 addr = addr + ord(tab[i])
149 line = line + ord(tab[i+1])
154 """Cette classe définit un système de nommage dynamique des concepts."""
157 self.native = _GetNomConceptResultat
158 self.use_global_naming()
160 def use_naming_function(self, function):
161 """Utilise une fonction particulière de nommage."""
162 self.naming_func = function
164 def use_global_naming(self):
165 """Utilise la fonction native de nommage."""
166 self.naming_func = partial(self.native, level=3)
168 def __call__(self, *args):
169 """Appel à la fonction de nommage."""
170 return self.naming_func(*args)
172 GetNomConceptResultat = NamingSystem()