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