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