Salome HOME
CCAR: ajout des fichiers macros
[tools/eficas.git] / Ihm / I_FORM_ETAPE.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 """
23 import string,traceback
24
25 from I_MACRO_ETAPE import MACRO_ETAPE
26 from Extensions import interpreteur_formule
27 from Editeur import analyse_catalogue
28
29 analyse_catalogue.l_noms_commandes.append('FORM') # déclare le nom FORM à l'analyseur de catalogue
30
31
32 class FORM_ETAPE(MACRO_ETAPE):
33
34     interpreteur = interpreteur_formule.Interpreteur_Formule
35
36     def McBuild(self):
37         self.mc_liste=self.build_mc()
38         # on crée la liste des types autorisés (liste des noms de mots-clés
39         # simples dans le catalogue de FORMULE)
40         self.l_types_autorises = self.definition.entites.keys()
41         # en plus de la construction traditionnelle des fils de self
42         # il faut pour les FORMULE décortiquer l'expression ...
43         self.type_retourne,self.arguments,self.corps = self.analyse_formule()
44
45     def analyse_formule(self):
46         """
47         Cette méthode décortique l'expression de la FORMULE.
48         Elle retourne 3 valeurs:
49             - le type retourné par la FORMULE
50             - les arguments de la FORMULE
51             - le corps de la FORMULE, cad son expression
52         """
53         if len(self.mc_liste) == 0:
54             # pas de fils pour self --> la FORMULE est incomplète
55             return None,None,None
56         child = self.mc_liste[0] # child est un MCSIMP
57         type_retourne = child.definition.nom
58         valeur = child.getval()
59         # c'est dans valeur que se trouvent la liste des arguments et le corps de la fonction
60         try:
61             l_args,corps = string.split(valeur,'=',1)
62         except:
63             # pas de signe = --> la formule est fausse
64             return type_retourne,None,None
65         l_args = string.strip(l_args)
66         corps = string.strip(corps)
67         return type_retourne,l_args,corps
68
69     def get_nom(self):
70         """
71         Retourne le nom de la FORMULE, cad le nom de la SD si elle existe,
72         la string vide sinon
73         """
74         if self.sd :
75             return self.sd.get_name()
76         else:
77             return ''
78
79     def get_formule(self):
80         """
81         Retourne un tuple décrivant la formule :
82         (nom,type_retourne,arguments,corps)
83         """
84         t,a,c = self.analyse_formule()
85         n = self.get_nom()
86         return (n,t,a,c)
87
88     def verif_arguments(self,arguments = None):
89         """
90         Vérifie si les arguments passés en argument (si aucun prend les arguments courants)
91         sont des arguments valide pour une FORMULE.
92         Retourne :
93             - un booléen, qui vaut 1 si arguments licites, 0 sinon
94             - un message d'erreurs ('' si illicites)
95         """
96         if not arguments :
97             arguments = self.arguments
98         if not arguments :
99             return 0,"Une formule doit avoir au minimum un argument"
100         # il faut au préalable enlever les parenthèses ouvrantes et fermantes
101         # encadrant les arguments
102         arguments = string.strip(arguments)
103         if arguments[0] != '(':
104             return 0,"La liste des arguments d'une formule doit être entre parenthèses : parenthèse ouvrante manquante"
105         if arguments[-1] != ')':
106             return 0,"La liste des arguments d'une formule doit être entre parenthèses : parenthèse fermante manquante"
107         # on peut tester la syntaxe de chaque argument maintenant
108         erreur=''
109         test = 1
110         arguments = arguments[1:-1] # on enlève les parenthèses ouvrante et fermante
111         l_arguments = string.split(arguments,',')
112         for argument in l_arguments:
113             argument = string.strip(argument)
114             try:
115                 typ,nom = string.split(argument,':')
116                 # pas de vérification sur le nom de l'argument
117                 # vérification du type de l'argument
118                 typ = string.strip(typ)
119                 if typ not in self.l_types_autorises :
120                     test = 0
121                     erreur = erreur + "Le type "+typ+" n'est pas un type permis pour "+nom+'\n'
122             except:
123                 # l'argument ne respecte pas la syntaxe : typ_arg : nom_arg
124                 test = 0
125                 erreur = erreur+"Syntaxe argument non valide : "+argument+'\n'
126         return test,erreur
127
128     def verif_corps(self,corps=None,arguments=None):
129         """
130         Cette méthode a pour but de vérifier si le corps de la FORMULE
131         est syntaxiquement correct.
132         Retourne :
133             - un booléen, qui vaut 1 si corps de FORMULE licite, 0 sinon
134             - un message d'erreurs ('' si illicite)
135         """
136         if not corps :
137             corps = self.corps
138         if not arguments :
139             arguments = self.arguments
140         formule=(self.get_nom(),self.type_retourne,arguments,corps)
141         # on récupère la liste des constantes et des autres fonctions prédéfinies
142         # et qui peuvent être utilisées dans le corps de la formule courante
143         l_ctes,l_form = self.jdc.get_parametres_fonctions_avant_etape(self)
144         # on crée un objet vérificateur
145         try:
146             verificateur = self.interpreteur(formule=formule,
147                                              constantes = l_ctes,
148                                              fonctions = l_form)
149         except :
150             traceback.print_exc()
151             return 0,"Impossible de réaliser la vérification de la formule"
152         return verificateur.isvalid(),verificateur.report()
153
154     def verif_nom(self,nom=None):
155         """
156         Vérifie si le nom passé en argument (si aucun prend le nom courant)
157         est un nom valide pour une FORMULE.
158         Retourne :
159             - un booléen, qui vaut 1 si nom licite, 0 sinon
160             - un message d'erreurs ('' si illicite)
161         """
162         if not nom :
163             nom = self.get_nom()
164         if nom == "" :
165             return 0,"Pas de nom donné à la FORMULE"
166         if len(nom) > 8 :
167             return 0,"Un nom de FORMULE ne peut dépasser 8 caractères"
168         sd = self.parent.get_sd_autour_etape(nom,self)
169         if sd :
170             return 0,"Un concept de nom %s existe déjà !" %nom
171         return 1,''
172
173     def verif_type(self,type=None):
174         """
175         Vérifie si le type passé en argument (si aucun prend le type courant)
176         est un type valide pour une FORMULE.
177         Retourne :
178             - un booléen, qui vaut 1 si type licite, 0 sinon
179             - un message d'erreurs ('' si illicite)
180         """
181         if not type:
182             type = self.type_retourne
183         if not type :
184             return 0,"Le type de la valeur retournée n'est pas spécifié"
185         if type not in self.l_types_autorises:
186             return 0,"Une formule ne peut retourner une valeur de type : %s" %type
187         return 1,''
188
189     def verif_formule(self,formule=None):
190         """
191         Vérifie la validité de la formule passée en argument.
192         Cette nouvelle formule est passée sous la forme d'un tuple : (nom,type_retourne,arguments,corps)
193         Si aucune formule passée, prend les valeurs courantes de la formule
194         Retourne :
195             - un booléen, qui vaut 1 si formule licite, 0 sinon
196             - un message d'erreurs ('' si illicite)
197         """
198         if not formule :
199             formule = (None,None,None,None)
200         test_nom,erreur_nom = self.verif_nom(formule[0])
201         test_type,erreur_type = self.verif_type(formule[1])
202         if formule[2]:
203             args = '('+formule[2]+')'
204         else:
205             args = None
206         test_arguments,erreur_arguments = self.verif_arguments(args)
207         test_corps,erreur_corps = self.verif_corps(corps = formule[3], arguments = args)
208         # test global = produit des tests partiels
209         test = test_nom*test_type*test_arguments*test_corps
210         # message d'erreurs global = concaténation des messages partiels
211         erreur = ''
212         if not test :
213             for mess in (erreur_nom,erreur_type,erreur_arguments,erreur_corps):
214                 erreur = erreur+(len(mess) > 0)*'\n'+mess
215         return test,erreur
216
217     def update(self,formule):
218         """
219         Méthode externe.
220         Met à jour les champs nom, type_retourne,arguments et corps de la FORMULE
221         par les nouvelles valeurs passées dans le tuple formule.
222         On stocke les valeurs SANS vérifications.
223         """
224         self.init_modif()
225         self.type_retourne = formule[1]
226         self.arguments = '('+formule[2]+')'
227         self.corps = formule[3]
228         # il faut ajouter le mot-clé simple correspondant dans mc_liste
229         # pour cela on utilise la méthode générale build_mc
230         # du coup on est obligé de modifier le dictionnaire valeur de self ...
231         self.valeur = {}
232         self.valeur[self.type_retourne] = self.arguments+' = ' + self.corps
233         self.McBuild()
234         sd = self.get_sd_prod()
235         if sd:
236             sd.nom = formule[0]
237
238     def active(self):
239         """
240         Rend l'etape courante active.
241         Il faut ajouter la formule au contexte global du JDC
242         """
243         self.actif = 1
244         nom = self.get_nom()
245         if nom == '' : return
246         try:
247             self.jdc.append_fonction(self.sd)
248         except:
249             pass
250
251     def inactive(self):
252         """
253         Rend l'etape courante inactive
254         Il faut supprimer la formule du contexte global du JDC
255         """
256         self.actif = 0
257         if not self.sd : return
258         self.jdc.del_fonction(self.sd)
259
260     def delete_concept(self,sd):
261         """ 
262          Inputs :
263            - sd=concept detruit
264          Fonction :
265          Mettre a jour les mots cles de l etape et eventuellement le concept produit si reuse
266          suite à la disparition du concept sd
267          Seuls les mots cles simples MCSIMP font un traitement autre que de transmettre aux fils,
268          sauf les objets FORM_ETAPE qui doivent vérifier que le concept détruit n'est pas 
269          utilisé dans le corps de la fonction
270         """
271         self.init_modif()
272          
273     def replace_concept(self,old_sd,sd):
274         """
275          Inputs :
276            - old_sd=concept remplace
277            - sd = nouveau concept
278          Fonction :
279          Les objets FORM_ETAPE devraient vérifier que le concept remplacé n'est pas
280          utilisé dans le corps de la fonction
281         """
282         self.init_modif()
283