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.
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.
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.
20 # ======================================================================
23 import string,traceback
25 from Accas import MACRO_ETAPE,MACRO
26 from Extensions import interpreteur_formule
29 class FORM_ETAPE(MACRO_ETAPE):
31 interpreteur = interpreteur_formule.Interpreteur_Formule
34 self.mc_liste=self.build_mc()
35 # on crée la liste des types autorisés (liste des noms de mots-clés
36 # simples dans le catalogue de FORMULE)
37 self.l_types_autorises = self.definition.entites.keys()
38 # en plus de la construction traditionnelle des fils de self
39 # il faut pour les FORMULE décortiquer l'expression ...
40 self.type_retourne,self.arguments,self.corps = self.analyse_formule()
42 def analyse_formule(self):
44 Cette méthode décortique l'expression de la FORMULE.
45 Elle retourne 3 valeurs:
46 - le type retourné par la FORMULE
47 - les arguments de la FORMULE
48 - le corps de la FORMULE, cad son expression
50 if len(self.mc_liste) == 0:
51 # pas de fils pour self --> la FORMULE est incomplète
53 child = self.mc_liste[0] # child est un MCSIMP
54 type_retourne = child.definition.nom
55 valeur = child.getval()
56 # c'est dans valeur que se trouvent la liste des arguments et le corps de la fonction
58 l_args,corps = string.split(valeur,'=',1)
60 # pas de signe = --> la formule est fausse
61 return type_retourne,None,None
62 l_args = string.strip(l_args)
63 corps = string.strip(corps)
64 return type_retourne,l_args,corps
68 Retourne le nom de la FORMULE, cad le nom de la SD si elle existe,
72 return self.sd.get_name()
76 def get_formule(self):
78 Retourne un tuple décrivant la formule :
79 (nom,type_retourne,arguments,corps)
81 t,a,c = self.analyse_formule()
85 def verif_arguments(self,arguments = None):
87 Vérifie si les arguments passés en argument (si aucun prend les arguments courants)
88 sont des arguments valide pour une FORMULE.
90 - un booléen, qui vaut 1 si arguments licites, 0 sinon
91 - un message d'erreurs ('' si illicites)
94 arguments = self.arguments
96 return 0,"Une formule doit avoir au minimum un argument"
97 # il faut au préalable enlever les parenthèses ouvrantes et fermantes
98 # encadrant les arguments
99 arguments = string.strip(arguments)
100 if arguments[0] != '(':
101 return 0,"La liste des arguments d'une formule doit être entre parenthèses : parenthèse ouvrante manquante"
102 if arguments[-1] != ')':
103 return 0,"La liste des arguments d'une formule doit être entre parenthèses : parenthèse fermante manquante"
104 # on peut tester la syntaxe de chaque argument maintenant
107 arguments = arguments[1:-1] # on enlève les parenthèses ouvrante et fermante
108 l_arguments = string.split(arguments,',')
109 for argument in l_arguments:
110 argument = string.strip(argument)
112 typ,nom = string.split(argument,':')
113 # pas de vérification sur le nom de l'argument
114 # vérification du type de l'argument
115 typ = string.strip(typ)
116 if typ not in self.l_types_autorises :
118 erreur = erreur + "Le type "+typ+" n'est pas un type permis pour "+nom+'\n'
120 # l'argument ne respecte pas la syntaxe : typ_arg : nom_arg
122 erreur = erreur+"Syntaxe argument non valide : "+argument+'\n'
125 def verif_corps(self,corps=None,arguments=None):
127 Cette méthode a pour but de vérifier si le corps de la FORMULE
128 est syntaxiquement correct.
130 - un booléen, qui vaut 1 si corps de FORMULE licite, 0 sinon
131 - un message d'erreurs ('' si illicite)
136 arguments = self.arguments
137 formule=(self.get_nom(),self.type_retourne,arguments,corps)
138 # on récupère la liste des constantes et des autres fonctions prédéfinies
139 # et qui peuvent être utilisées dans le corps de la formule courante
140 l_ctes,l_form = self.jdc.get_parametres_fonctions_avant_etape(self)
141 # on crée un objet vérificateur
143 verificateur = self.interpreteur(formule=formule,
147 traceback.print_exc()
148 return 0,"Impossible de réaliser la vérification de la formule"
149 return verificateur.isvalid(),verificateur.report()
151 def verif_nom(self,nom=None):
153 Vérifie si le nom passé en argument (si aucun prend le nom courant)
154 est un nom valide pour une FORMULE.
156 - un booléen, qui vaut 1 si nom licite, 0 sinon
157 - un message d'erreurs ('' si illicite)
162 return 0,"Pas de nom donné à la FORMULE"
164 return 0,"Un nom de FORMULE ne peut dépasser 8 caractères"
165 sd = self.parent.get_sd_autour_etape(nom,self)
167 return 0,"Un concept de nom %s existe déjà !" %nom
170 def verif_type(self,type=None):
172 Vérifie si le type passé en argument (si aucun prend le type courant)
173 est un type valide pour une FORMULE.
175 - un booléen, qui vaut 1 si type licite, 0 sinon
176 - un message d'erreurs ('' si illicite)
179 type = self.type_retourne
181 return 0,"Le type de la valeur retournée n'est pas spécifié"
182 if type not in self.l_types_autorises:
183 return 0,"Une formule ne peut retourner une valeur de type : %s" %type
186 def verif_formule(self,formule=None):
188 Vérifie la validité de la formule passée en argument.
189 Cette nouvelle formule est passée sous la forme d'un tuple : (nom,type_retourne,arguments,corps)
190 Si aucune formule passée, prend les valeurs courantes de la formule
192 - un booléen, qui vaut 1 si formule licite, 0 sinon
193 - un message d'erreurs ('' si illicite)
196 formule = (None,None,None,None)
197 test_nom,erreur_nom = self.verif_nom(formule[0])
198 test_type,erreur_type = self.verif_type(formule[1])
200 args = '('+formule[2]+')'
203 test_arguments,erreur_arguments = self.verif_arguments(args)
204 test_corps,erreur_corps = self.verif_corps(corps = formule[3], arguments = args)
205 # test global = produit des tests partiels
206 test = test_nom*test_type*test_arguments*test_corps
207 # message d'erreurs global = concaténation des messages partiels
210 for mess in (erreur_nom,erreur_type,erreur_arguments,erreur_corps):
211 erreur = erreur+(len(mess) > 0)*'\n'+mess
214 def update(self,formule):
217 Met à jour les champs nom, type_retourne,arguments et corps de la FORMULE
218 par les nouvelles valeurs passées dans le tuple formule.
219 On stocke les valeurs SANS vérifications.
222 self.type_retourne = formule[1]
223 self.arguments = '('+formule[2]+')'
224 self.corps = formule[3]
225 # il faut ajouter le mot-clé simple correspondant dans mc_liste
226 # pour cela on utilise la méthode générale build_mc
227 # du coup on est obligé de modifier le dictionnaire valeur de self ...
229 self.valeur[self.type_retourne] = self.arguments+' = ' + self.corps
231 sd = self.get_sd_prod()
237 Rend l'etape courante active.
238 Il faut ajouter la formule au contexte global du JDC
242 if nom == '' : return
244 self.jdc.append_fonction(self.sd)
250 Rend l'etape courante inactive
251 Il faut supprimer la formule du contexte global du JDC
254 if not self.sd : return
255 self.jdc.del_fonction(self.sd)
257 def delete_concept(self,sd):
262 Mettre a jour les mots cles de l etape et eventuellement le concept produit si reuse
263 suite à la disparition du concept sd
264 Seuls les mots cles simples MCSIMP font un traitement autre que de transmettre aux fils,
265 sauf les objets FORM_ETAPE qui doivent vérifier que le concept détruit n'est pas
266 utilisé dans le corps de la fonction
270 def replace_concept(self,old_sd,sd):
273 - old_sd=concept remplace
274 - sd = nouveau concept
276 Les objets FORM_ETAPE devraient vérifier que le concept remplacé n'est pas
277 utilisé dans le corps de la fonction
282 class_instance=FORM_ETAPE