Salome HOME
a968549868e33822ef99f8bb01b9971537918b1f
[tools/eficas.git] / Extensions / parametre_eval.py
1 """
2 Ce module contient la classe PARAMETRE_EVAL qui sert à définir
3 des objets paramètres qui sont compréhensibles et donc affichables
4 par EFICAS.
5 Ces objets sont créés à partir de la modification du fichier de commandes
6 de l'utilisateur par le parseur de fichiers Python
7 """
8 # import de modules Python
9 import string,types,re
10 import traceback
11
12 # import modules Eficas
13 import Accas
14 import interpreteur_formule
15 from Noyau.N_CR import CR
16 import parametre
17
18 pattern_eval       = re.compile(r'^(EVAL)([ \t\r\f\v]*)\(([\w\W]*)')
19
20 class PARAMETRE_EVAL(parametre.PARAMETRE) :
21   """
22   Cette classe permet de créer des objets de type PARAMETRE_EVAL
23   cad des affectations directes évaluées dans le jeu de commandes
24               (ex: a=EVAL('''10.*SQRT(25)'''))
25   qui sont interprétées par le parseur de fichiers Python.
26   Les objets ainsi créés constituent des paramètres évalués pour le jdc
27   """
28   nature = 'PARAMETRE_EVAL'
29   idracine='param_eval'
30
31   def __init__(self,nom,valeur=None):
32     # parent ne peut être qu'un objet de type JDC
33     self.valeur = self.interprete_valeur(valeur)
34     self.val    = valeur
35     self.nom = nom
36     self.jdc = self.parent = CONTEXT.get_current_step()
37     self.definition=self
38     self.niveau = self.parent.niveau
39     # Ceci est-il indispensable ???
40     #self.appel = N_utils.callee_where(niveau=2)
41     self.register()
42
43   def __repr__(self):
44     """
45         Donne un echo de self sous la forme nom = valeur
46     """
47     return self.nom+' = '+ repr(self.valeur) + '\n'
48
49   def __str__(self):
50     """
51         Retourne le nom du paramètre évalué comme représentation de self
52     """
53     return self.nom
54
55   def interprete_valeur(self,val):
56     """
57     Essaie d'interpréter val (chaîne de caractères ou None) comme :
58     une instance de Accas.EVAL
59     Retourne la valeur interprétée
60     """
61     if not val : return None
62     d={}
63     val = string.strip(val)
64     if val[-1] == ';' : val = val[0:-1]
65     d['EVAL'] = Accas.EVAL
66     try:
67         valeur = eval(val,{},d)
68         return valeur
69     except:
70         traceback.print_exc()
71         print "Le texte %s n'est pas celui d'un paramètre évalué" %val
72         return None
73
74   def set_valeur(self,new_valeur):
75     """
76     Remplace la valeur de self par new_valeur interprétée.
77     """
78     self.valeur = self.interprete_valeur(new_valeur)
79     self.val = new_valeur
80     self.init_modif()
81
82   def get_nom(self) :
83     """
84     Retourne le nom du paramètre
85     """
86     return self.nom
87
88   def get_valeur(self):
89     """
90     Retourne la valeur de self, cad le texte de l'objet class_eval.EVAL
91     """
92     if self.valeur :
93         return self.valeur.valeur
94     else:
95         return ''
96
97   def verif_eval(self,exp_eval=None,cr='non'):
98     """
99     Cette méthode a pour but de vérifier si l'expression EVAL
100     est syntaxiquement correcte.
101     Retourne :
102         - un booléen, qui vaut 1 si licite, 0 sinon
103         - un message d'erreurs ('' si illicite)
104     """
105     if not exp_eval:
106         if self.valeur :
107             exp_eval = self.valeur.valeur[3:-3] # on enlève les triples guillemets
108         else:
109             exp_eval = None
110     if exp_eval :
111         # on construit un interpréteur de formule
112         formule=(self.nom,'',None,exp_eval)
113         # on récupère la liste des constantes et des autres fonctions prédéfinies
114         # et qui peuvent être utilisées dans le corps de la formule courante
115         l_ctes,l_form = self.jdc.get_parametres_fonctions_avant_etape(self)
116         # on crée un objet vérificateur
117         verificateur = interpreteur_formule.Interpreteur_Formule(formule=formule,
118                                                                  constantes = l_ctes,
119                                                                  fonctions = l_form)
120         if cr == 'oui' :
121           if not verificateur.cr.estvide():
122             self.cr.fatal(verificateur.cr.get_mess_fatal())
123         return verificateur.isvalid(),string.join(verificateur.cr.crfatal)
124     else:
125         # pas d'expression EVAL --> self non valide
126         if cr == 'oui' : 
127            self.cr.fatal("Le paramètre EVAL %s ne peut valoir None" % self.nom)
128         return 0,"Le paramètre EVAL ne peut valoir None"
129
130   def verif_nom(self,nom=None,cr='non'):
131     """
132     Vérifie si le nom passé en argument (si aucun prend le nom courant)
133     est un nom valide pour un paramètre EVAL
134     Retourne :
135         - un booléen, qui vaut 1 si nom licite, 0 sinon
136         - un message d'erreurs ('' si illicite)
137     """
138     if not nom :
139         nom = self.nom
140     if nom == "" :
141         if cr == 'oui' : self.cr.fatal("Pas de nom donné au paramètre EVAL")
142         return 0,"Pas de nom donné au paramètre EVAL"
143     if len(nom) > 8 :
144         if cr == 'oui' : self.cr.fatal("Un nom de paramètre ne peut dépasser 8 caractères")
145         return 0,"Un nom de paramètre ne peut dépasser 8 caractères"
146     sd = self.parent.get_sd_autour_etape(nom,self)
147     if sd :
148         if cr == 'oui' : self.cr.fatal("Un concept de nom %s existe déjà !" %nom)
149         return 0,"Un concept de nom %s existe déjà !" %nom
150     return 1,''
151
152   def verif_parametre_eval(self,param=None,cr='non'):
153     """
154     Vérifie la validité du paramètre EVAL passé en argument.
155     Ce nouveau paramètre est passé sous la forme d'un tuple :
156                 (nom,valeur)
157     Si aucun tuple passé, prend les valeurs courantes de l'objet
158     Retourne :
159             - un booléen, qui vaut 1 si EVAL licite, 0 sinon
160             - un message d'erreurs ('' si illicite)
161     """
162     if not param :
163         if self.valeur :
164             param = (self.nom,self.valeur.valeur)
165         else:
166             param = (self.nom,None)
167     test_nom,erreur_nom   = self.verif_nom(param[0],cr=cr)
168     test_eval,erreur_eval = self.verif_eval(param[1],cr=cr)
169     # test global = produit des tests partiels
170     test = test_nom*test_eval
171     # message d'erreurs global = concaténation des messages partiels
172     erreur = ''
173     if not test :
174         for mess in (erreur_nom,erreur_eval):
175             erreur = erreur+(len(mess) > 0)*'\n'+mess
176     return test,erreur
177
178   def update(self,param):
179     """
180     Méthode externe.
181     Met à jour les champs nom, valeur de self
182     par les nouvelles valeurs passées dans le tuple formule.
183     On stocke les valeurs SANS vérifications.
184     """
185     self.init_modif()
186     self.set_nom(param[0])
187     self.set_valeur('EVAL("""'+param[1]+'""")')
188
189   def isvalid(self,cr='non'):
190     """
191     Retourne 1 si self est valide, 0 sinon
192     Un paramètre évalué est considéré comme valide si :
193     - il a un nom
194     - il a une valeur qui est interprétable par l'interpréteur de FORMULEs
195     """
196     resu,erreur= self.verif_parametre_eval(cr=cr)
197     return resu
198
199   def report(self):
200     """
201         Génère l'objet rapport (classe CR)
202     """
203     self.cr = CR()
204     self.isvalid(cr='oui')
205     return self.cr
206
207   def set_nom(self,new_nom):
208     """
209     Remplace le nom de self par new_nom
210     """
211     self.nom = new_nom
212
213