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