X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Noyau%2FN_MACRO_ETAPE.py;h=87c14e47e98dde6455c1ea1878f2669caf22ad98;hb=a7d5f18fe322c770026b50343adc09ed0472c192;hp=1139b691220ed8e45e40695ad62f01003b61e4bd;hpb=e48d543f878c604958b5f1e6ac6d92a8392356e4;p=tools%2Feficas.git diff --git a/Noyau/N_MACRO_ETAPE.py b/Noyau/N_MACRO_ETAPE.py index 1139b691..87c14e47 100644 --- a/Noyau/N_MACRO_ETAPE.py +++ b/Noyau/N_MACRO_ETAPE.py @@ -1,4 +1,5 @@ -#@ MODIF N_MACRO_ETAPE Noyau DATE 09/10/2002 AUTEUR DURAND C.DURAND +#@ MODIF N_MACRO_ETAPE Noyau DATE 31/05/2005 AUTEUR DURAND C.DURAND +# -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG @@ -18,6 +19,8 @@ # # # ====================================================================== + + """ Ce module contient la classe MACRO_ETAPE qui sert à vérifier et à exécuter une commande @@ -33,12 +36,14 @@ import N_ETAPE from N_Exception import AsException import N_utils from N_utils import AsType +from N_CO import CO class MACRO_ETAPE(N_ETAPE.ETAPE): """ """ nature = "COMMANDE" + typeCO=CO def __init__(self,oper=None,reuse=None,args={}): """ Attributs : @@ -79,6 +84,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): self.actif=1 self.sdprods=[] self.make_register() + self.UserError="UserError" def make_register(self): """ @@ -89,10 +95,12 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): self.jdc = self.parent.get_jdc_root() self.id=self.parent.register(self) self.niveau=None + self.UserError=self.jdc.UserError else: self.jdc = self.parent =None self.id=None self.niveau=None + self.UserError="UserError" def Build_sd(self,nom): """ @@ -124,15 +132,13 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # d un concept sd.nom=nom self.reset_current_step() - if self.jdc and self.jdc.par_lot == "NON" : - self.Execute() - return sd except AsException,e: self.reset_current_step() raise AsException("Etape ",self.nom,'ligne : ',self.appel[0], 'fichier : ',self.appel[1],e) - except EOFError: - #self.reset_current_step() + except (EOFError,self.UserError): + # Le retablissement du step courant n'est pas strictement necessaire. On le fait pour des raisons de coherence + self.reset_current_step() raise except : self.reset_current_step() @@ -141,6 +147,20 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): 'fichier : ',self.appel[1]+'\n', string.join(l)) + self.Execute() + return sd + + def mark_CO(self): + """ + Marquage des concepts CO d'une macro-commande + """ + # On marque les concepts CO pour verification ulterieure de leur bonne utilisation + l=self.get_all_co() + for c in l: + #if not hasattr(c,"_etape") or c._etape is not c.etape: + c._etape=self + return l + def get_sd_prod(self): """ Retourne le concept résultat d'une macro étape @@ -159,6 +179,9 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): """ sd_prod=self.definition.sd_prod self.typret=None + # On marque les concepts CO pour verification ulterieure de leur bonne utilisation + self.mark_CO() + if type(self.definition.sd_prod) == types.FunctionType: d=self.cree_dict_valeurs(self.mc_liste) try: @@ -167,7 +190,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # les concepts produits dans self.sdprods, il faut le mettre à zéro avant de l'appeler self.sdprods=[] sd_prod= apply(sd_prod,(self,),d) - except EOFError: + except (EOFError,self.UserError): raise except: if CONTEXT.debug: traceback.print_exc() @@ -175,10 +198,9 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): raise AsException("impossible d affecter un type au resultat\n",string.join(l[2:])) # on teste maintenant si la SD est réutilisée ou s'il faut la créer - if self.reuse: - # Il est preferable de traiter cette erreur ultérieurement : ce n'est pas une erreur fatale - #if AsType(self.reuse) != sd_prod: - # raise AsException("type de concept reutilise incompatible avec type produit") + if self.definition.reentrant != 'n' and self.reuse: + # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale. + # Elle sera traitee ulterieurement. self.sd=self.reuse else: if sd_prod == None: @@ -186,12 +208,18 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): else: self.sd= sd_prod(etape=self) self.typret=sd_prod - # Si reuse n'a pas ete donné, c'est une erreur. Ne pas corriger afin de la detecter ensuite - #if self.definition.reentrant == 'o': - # self.reuse = self.sd + # Si la commande est obligatoirement reentrante et reuse n'a pas ete specifie, c'est une erreur. + # On ne fait rien ici. L'erreur sera traitee par la suite. return self.sd def get_type_produit(self,force=0): + try: + return self.get_type_produit_brut(force) + except: + #traceback.print_exc() + return None + + def get_type_produit_brut(self,force=0): """ Retourne le type du concept résultat de l'étape et eventuellement type les concepts produits "à droite" du signe égal (en entrée) @@ -204,16 +232,15 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): et on retourne son résultat """ if not force and hasattr(self,'typret'): return self.typret + # On marque les concepts CO pour verification ulterieure de leur bonne utilisation + self.mark_CO() + if type(self.definition.sd_prod) == types.FunctionType: d=self.cree_dict_valeurs(self.mc_liste) - try: - # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute - # les concepts produits dans self.sdprods, il faut le mettre à zéro - self.sdprods=[] - sd_prod= apply(self.definition.sd_prod,(self,),d) - except: - #traceback.print_exc() - return None + # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute + # les concepts produits dans self.sdprods, il faut le mettre à zéro + self.sdprods=[] + sd_prod= apply(self.definition.sd_prod,(self,),d) else: sd_prod=self.definition.sd_prod return sd_prod @@ -276,32 +303,87 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): if not hasattr(co,'etape'): # Le concept vaut None probablement. On ignore l'appel return - + # + # On cherche a discriminer les differents cas de typage d'un concept + # produit par une macro qui est specifie dans un mot cle simple. + # On peut passer plusieurs fois par type_sdprod ce qui explique + # le nombre important de cas. + # + # Cas 1 : Le concept est libre. Il vient d'etre cree par CO(nom) + # Cas 2 : Le concept est produit par la macro. On est deja passe par type_sdprod. + # Cas semblable a Cas 1. + # Cas 3 : Le concept est produit par la macro englobante (parent). On transfere + # la propriete du concept de la macro parent a la macro courante (self) + # en verifiant que le type est valide + # Cas 4 : La concept est la propriete d'une etape fille. Ceci veut dire qu'on est + # deja passe par type_sdprod et que la propriete a ete transfere a une + # etape fille. Cas semblable a Cas 3. + # Cas 5 : Le concept est produit par une etape externe a la macro. + # if co.etape == None: - # le concept est libre + # Cas 1 : le concept est libre + # On l'attache a la macro et on change son type dans le type demande + # Recherche du mot cle simple associe au concept + mcs=self.get_mcs_with_co(co) + if len(mcs) != 1: + raise AsException("""Erreur interne. +Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co) + mcs=mcs[0] + if not self.typeCO in mcs.definition.type: + raise AsException("""Erreur interne. +Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type)) co.etape=self co.__class__ = t self.sdprods.append(co) + elif co.etape== self: - # le concept est produit par self - co.__class__ = t + # Cas 2 : le concept est produit par la macro (self) + # On est deja passe par type_sdprod (Cas 1 ou 3). + # Il suffit de le mettre dans la liste des concepts produits (self.sdprods) + # Le type du concept doit etre coherent avec le type demande (seulement derive) + if not isinstance(co,t): + raise AsException("""Erreur interne. +Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__)) self.sdprods.append(co) + elif co.etape== self.parent: - # le concept est produit par la macro superieure - # on transfere la propriete - # On verifie que le type du concept existant co.__class__ est un sur type de celui attendu + # Cas 3 : le concept est produit par la macro parente (self.parent) + # on transfere la propriete du concept a la macro fille + # et on change le type du concept comme demande + # Au prealable, on verifie que le concept existant (co) est une instance + # possible du type demande (t) # Cette règle est normalement cohérente avec les règles de vérification des mots-clés - if not issubclass(t,co.__class__): - raise AsException("Le type du concept produit %s devrait etre une sur classe de %s" %(co.__class__,t)) + if not isinstance(co,t): + raise AsException(""" +Impossible de changer le type du concept produit (%s) en (%s). +Le type actuel (%s) devrait etre une classe derivee du nouveau type (%s)""" % (co,t,co.__class__,t)) + mcs=self.get_mcs_with_co(co) + if len(mcs) != 1: + raise AsException("""Erreur interne. +Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co) + mcs=mcs[0] + if not self.typeCO in mcs.definition.type: + raise AsException("""Erreur interne. +Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type)) co.etape=self - co.__class__ = t + # On ne change pas le type car il respecte la condition isinstance(co,t) + #co.__class__ = t self.sdprods.append(co) + elif self.issubstep(co.etape): - # Le concept est propriété d'une sous etape de self. Il doit etre considere - # comme produit par la macro => ajout dans self.sdprods + # Cas 4 : Le concept est propriété d'une sous etape de la macro (self). + # On est deja passe par type_sdprod (Cas 3 ou 1). + # Il suffit de le mettre dans la liste des concepts produits (self.sdprods) + # Le type du concept et t doivent etre derives. + # Il n'y a aucune raison pour que la condition ne soit pas verifiee. + if not isinstance(co,t): + raise AsException("""Erreur interne. +Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__)) self.sdprods.append(co) + else: - # le concept est produit par une autre étape + # Cas 5 : le concept est produit par une autre étape + # On ne fait rien return def issubstep(self,etape): @@ -351,7 +433,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # Il s'agit d'un concept de sortie de la macro. Il ne faut pas le créer # Il faut quand meme appeler la fonction sd_prod si elle existe. # get_type_produit le fait et donne le type attendu par la commande pour verification ultérieure. - sdprod=etape.get_type_produit() + sdprod=etape.get_type_produit_brut() sd=self.Outputs[nomsd] # On verifie que le type du concept existant sd.__class__ est un sur type de celui attendu # Cette règle est normalement cohérente avec les règles de vérification des mots-clés @@ -368,7 +450,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # On force également le nom stocké dans l'attribut sdnom : on lui donne le nom # du concept associé à nomsd etape.sdnom=sd.nom - elif etape.reuse != None: + elif etape.definition.reentrant != 'n' and etape.reuse != None: # On est dans le cas d'une commande avec reutilisation d'un concept existant # get_sd_prod fait le necessaire : verifications, associations, etc. mais ne cree # pas un nouveau concept. Il retourne le concept reutilise @@ -380,7 +462,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # En effet une commande avec reutilisation d'un concept verifie que le nom de # la variable a gauche du signe = est le meme que celui du concept reutilise. # Lorsqu'une telle commande apparait dans une macro, on supprime cette verification. - if etape.sdnom[0] == '_': + if (etape.sdnom == '' or etape.sdnom[0] == '_'): etape.sdnom=sd.nom else: # On est dans le cas de la creation d'un nouveau concept @@ -409,6 +491,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # les macros devrait peut etre etre déplacée dans Build ??? if CONTEXT.debug : print "MACRO.NommerSdprod: ",sd,sdnom + if hasattr(self,'prefix'): # Dans le cas de l'include_materiau on ajoute un prefixe au nom du concept if sdnom != self.prefix:sdnom=self.prefix+sdnom @@ -416,7 +499,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): if self.Outputs.has_key(sdnom): # Il s'agit d'un concept de sortie de la macro produit par une sous commande sdnom=self.Outputs[sdnom].nom - elif sdnom[0] == '_': + elif sdnom != '' and sdnom[0] == '_': # Si le nom du concept commence par le caractere _ on lui attribue # un identificateur JEVEUX construit par gcncon et respectant # la regle gcncon legerement adaptee ici @@ -492,7 +575,10 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): """ Inclut un fichier poursuite """ - f,text=self.get_file(fic_origine=self.parent.nom) + try: + f,text=self.get_file(fic_origine=self.parent.nom) + except: + raise AsException("Impossible d'ouvrir la base pour une poursuite") self.fichier_init=f if f == None:return self.make_contexte(f,text) @@ -526,6 +612,37 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): d.update(self.g_context) return d + def copy(self): + """ Méthode qui retourne une copie de self non enregistrée auprès du JDC + et sans sd + On surcharge la methode de ETAPE pour exprimer que les concepts crees + par la MACRO d'origine ne sont pas crees par la copie mais eventuellement + seulement utilises + """ + etape=N_ETAPE.ETAPE.copy(self) + etape.sdprods=[] + return etape + + def copy_intern(self,etape): + """ Cette méthode effectue la recopie des etapes internes d'une macro + passée en argument (etape) + """ + self.etapes=[] + for etp in etape.etapes: + new_etp=etp.copy() + new_etp.copy_reuse(etp) + new_etp.copy_sdnom(etp) + new_etp.reparent(self) + if etp.sd: + new_sd = etp.sd.__class__(etape=new_etp) + new_etp.sd = new_sd + if etp.reuse: + new_sd.nom = etp.sd.nom + else: + self.NommerSdprod(new_sd,etp.sd.nom) + new_etp.copy_intern(etp) + self.etapes.append(new_etp) +