Salome HOME
PN
[tools/eficas.git] / Ihm / I_MACRO_ETAPE.py
index c79ae36b93ff930f36b3d4cca0275d979db41b64..0ca98ea425baa380cbce7d1ce3db81d3232b598d 100644 (file)
@@ -26,6 +26,7 @@ import traceback,types,string
 
 # Modules Eficas
 import I_ETAPE
+import Noyau
 from Noyau.N_ASSD import ASSD
 
 # import rajoutés suite à l'ajout de Build_sd --> à résorber
@@ -64,13 +65,16 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
          ou leve une exception
          --> utilisée par ops.POURSUITE et INCLUDE
     """
-    #print "get_contexte_jdc"
+    #print "get_contexte_jdc",self,self.nom
+    # On recupere l'etape courante
+    step=CONTEXT.get_current_step()
     try:
        # on essaie de créer un objet JDC auxiliaire avec un contexte initial
        # Attention get_contexte_avant retourne un dictionnaire qui contient
        # le contexte courant. Ce dictionnaire est reactualise regulierement.
        # Si on veut garder l'etat du contexte fige, il faut en faire une copie.
        context_ini = self.parent.get_contexte_avant(self).copy()
+       #print "get_contexte_jdc",context_ini.keys()
 
        # Indispensable avant de creer un nouveau JDC
        CONTEXT.unset_current_step()
@@ -85,9 +89,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
        # En principe si la memorisation est faite au bon moment il n'est pas necessaire
        # de prendre cette precaution mais ce n'est pas vrai partout.
        old_recorded_units=self.recorded_units.copy()
-       #print "get_contexte_jdc",id(self.recorded_units)
-       #self.recorded_units.clear()
 
+       if fichier is None:fichier="SansNom"
        j=self.JdC_aux( procedure=text, nom=fichier,
                                 appli=self.jdc.appli,
                                 cata=self.jdc.cata,
@@ -102,44 +105,39 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
        # On récupère les étapes internes (pour validation)
        self.etapes=j.etapes
        self.jdc_aux=j
-       #print "get_contexte_jdc",id(self.etapes)
     except:
-       traceback.print_exc()
-       # On force le contexte (etape courante) à self
+       # On retablit l'etape courante step
        CONTEXT.unset_current_step()
-       CONTEXT.set_current_step(self)
+       CONTEXT.set_current_step(step)
        return None
 
     if not j.cr.estvide():
        # Erreurs dans l'INCLUDE. On garde la memoire du fichier 
        # mais on n'insere pas les concepts
-       # On force le contexte (etape courante) à self
+       # On retablit l'etape courante step
        CONTEXT.unset_current_step()
-       CONTEXT.set_current_step(self)
+       CONTEXT.set_current_step(step)
        raise Exception("Impossible de relire le fichier\n"+str(j.cr))
 
     if not j.isvalid():
        # L'INCLUDE n'est pas valide.
        # on produit un rapport d'erreurs
-       # On force le contexte (etape courante) à self
        cr=j.report()
+       # On retablit l'etape courante step
        CONTEXT.unset_current_step()
-       CONTEXT.set_current_step(self)
+       CONTEXT.set_current_step(step)
        raise Exception("Le fichier include contient des erreurs\n"+str(cr))
 
     # Si aucune erreur rencontrée
     # On recupere le contexte de l'include verifie
-    #print "context_ini",j.context_ini
-    #print "g_context",j.g_context
     try:
        j_context=j.get_verif_contexte()
     except:
+       # On retablit l'etape courante step
        CONTEXT.unset_current_step()
-       CONTEXT.set_current_step(self)
+       CONTEXT.set_current_step(step)
        raise
 
-    #print "context_ini",j.context_ini
-
     # On remplit le dictionnaire des concepts produits inclus
     # en retirant les concepts présents dans le  contexte initial
     # On ajoute egalement le concept produit dans le sds_dict du parent
@@ -157,11 +155,9 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.index_etape_courante=j.index_etape_courante
     self.jdc_aux=j
 
-    # XXX j.supprime() ???
-    # On rétablit le contexte (etape courante) à self
+    # On retablit l'etape courante step
     CONTEXT.unset_current_step()
-    CONTEXT.set_current_step(self)
-    #print "context_ini",self.jdc_aux.context_ini
+    CONTEXT.set_current_step(step)
 
     return j_context
 
@@ -204,17 +200,13 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       
   def control_sdprods(self,d):
       """
-          Cette methode doit updater le contexte fournit par
-          l'appelant en argument (d) en fonction de sa definition
-          tout en verifiant que ses concepts produits ne sont pas
-          deja definis dans le contexte
+          Cette methode doit verifier que les concepts produits par la 
+          commande ne sont pas incompatibles avec le contexte fourni (d).
+          Si c'est le cas, le concept produit doit etre supprime
+          Si la macro a elle meme des etapes, elle doit propager
+          le traitement (voir methode control_jdc_context_apres de I_JDC)
       """
-      if hasattr(self,"fichier_unite"):
-         self.update_fichier_init(self.fichier_unite)
-         self.init_modif()
-
-      if type(self.definition.op_init) == types.FunctionType:
-        apply(self.definition.op_init,(self,d))
+      #print "I_MACRO_ETAPE.control_sdprods",d.keys(),self.nom,self.sd and self.sd.nom
       if self.sd:
         if d.has_key(self.sd.nom):
            # Le concept est deja defini
@@ -225,18 +217,49 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
               # Redefinition du concept, on l'annule
               #XXX on pourrait simplement annuler son nom pour conserver les objets
               # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
-              self.sd=self.reuse=self.sdnom=None
               self.init_modif()
-        else:
-           # Le concept n'est pas defini, on peut updater d
-           d[self.sd.nom]=self.sd
+              sd=self.sd
+              self.sd=self.reuse=self.sdnom=None
+              self.parent.delete_concept_after_etape(self,sd)
+              self.fin_modif()
+
       # On verifie les concepts a droite du signe =
-      for co in self.sdprods:
+      self.init_modif()
+      sdprods=self.sdprods[:]
+      self.sdprods=[]
+      for co in sdprods:
         if d.has_key(co.nom) and co is not d[co.nom] :
+           #nettoie les mots cles de l'étape qui ont comme valeur co
            self.delete_concept(co)
+           #supprime les references a co dans les etapes suivantes
+           self.parent.delete_concept_after_etape(self,co)
         else:
-           d[co.nom]=co
+           self.sdprods.append(co)
+      self.fin_modif()
        
+      for e in self.etapes:
+          e.control_sdprods(d)
+          e.update_context(d)
+
+  def supprime_sdprod(self,sd):
+      """
+         Supprime le concept produit sd s'il est produit par l'etape
+      """
+      if sd in self.sdprods:
+         self.init_modif()
+         self.parent.del_sdprod(sd)
+         self.sdprods.remove(sd)
+         self.fin_modif()
+         self.parent.delete_concept(sd)
+         return
+
+      if sd is not self.sd :return
+      if self.sd is not None :
+         self.init_modif()
+         self.parent.del_sdprod(sd)
+         self.sd=None
+         self.fin_modif()
+         self.parent.delete_concept(sd)
 
   def supprime_sdprods(self):
       """
@@ -246,7 +269,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
           Une macro en a en général plus d'un
       """
       #print "supprime_sdprods"
-      if not self.is_reentrant() :
+      if self.reuse is not self.sd :
          # l'étape n'est pas réentrante
          # le concept retourné par l'étape est à supprimer car il était
          # créé par l'étape
@@ -265,6 +288,22 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       # On met g_context à blanc
       self.g_context={}
 
+  def close(self):
+      #print "close",self
+      if hasattr(self,"jdc_aux") and self.jdc_aux:
+         # La macro a un jdc auxiliaire inclus. On demande sa fermeture
+         self.jdc_aux.close()
+
+  def reset_context(self):
+      if hasattr(self,"jdc_aux") and self.jdc_aux:
+         # La macro a un jdc auxiliaire inclus. On demande la reinitialisation du contexte
+         self.jdc_aux.reset_context()
+
+  def update_concept(self,sd):
+      I_ETAPE.ETAPE.update_concept(self,sd)
+      for etape in self.etapes:
+          etape.update_concept(sd)
+
   def delete_concept(self,sd):
       """
           Fonction : Mettre a jour les mots cles de l etape et eventuellement
@@ -285,13 +324,14 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       #print "replace_concept",old_sd,sd
       I_ETAPE.ETAPE.replace_concept(self,old_sd,sd)
       for etape in self.etapes:
-         etape.replace_concept(sd)
+         etape.replace_concept(old_sd,sd)
          
   def change_fichier_init(self,new_fic,text):
     """
        Tente de changer le fichier include. Le precedent include est conservé
        dans old_xxx
     """
+    #print "change_fichier_init",new_fic
     if not hasattr(self,'fichier_ini'):
        self.fichier_ini=None
        self.fichier_text=None
@@ -336,6 +376,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.reevalue_sd_jdc()
 
     self.fin_modif()
+    if self.old_jdc_aux:
+       self.old_jdc_aux.close()
 
   def restore_fichier_init(self):
     """
@@ -351,24 +393,98 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
 
   def force_fichier_init(self):
     """
-       Force le fichier init en erreur
+       Force le remplacement du fichier init meme si le remplacant est en erreur
     """
-    # On conserve la memoire du nouveau fichier
-    # mais on n'utilise pas les concepts crees par ce fichier
-    # on met l'etape en erreur : fichier_err=string.join(l)
-    self.init_modif()
+    # Reinitialisation complete du compte-rendu d'erreurs
+    self.jdc_aux.cr=self.jdc_aux.CR()
+    # On remplit le dictionnaire des concepts produits inclus
+    # en retirant les concepts présents dans le  contexte initial
+    # On ajoute egalement le concept produit dans le sds_dict du parent
+    # sans verification car on est sur (verification integrée) que
+    # le nommage est possible
+    j_context=self.jdc_aux.get_contexte_avant(None)
+    self.g_context.clear()
+    context_ini=self.jdc_aux.context_ini
+    for k,v in j_context.items():
+       if not context_ini.has_key(k) or context_ini[k] != v:
+           self.g_context[k]=v
+           self.parent.sds_dict[k]=v
+    # On recupere le contexte courant
+    self.current_context=self.jdc_aux.current_context
+    self.index_etape_courante=self.jdc_aux.index_etape_courante
+    self.contexte_fichier_init = j_context
+    self.fichier_err = None
+
     # On enregistre la modification de fichier
+    self.init_modif()
+    self.state="undetermined"
     self.record_unite()
-    #self.etapes=[]
-    self.g_context={}
     # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
     self.parent.reset_context()
 
+    # On remplace les anciens concepts par les nouveaux (y compris ajouts 
+    # et suppression) et on propage les modifications aux etapes precedentes et suivantes
+    # reevalue_sd_jdc construit la liste des differences entre les contextes contexte_fichier_init
+    # et old_contexte_fichier_init et effectue les destructions et remplacements de concept
+    # necessaires
     self.old_contexte_fichier_init=self.old_context
-    self.contexte_fichier_init={}
     self.reevalue_sd_jdc()
-
     self.fin_modif()
+    if self.old_jdc_aux:
+       self.old_jdc_aux.close()
+
+    self.jdc_aux.force_contexte(self.g_context)
+
+  def build_include(self,fichier,text):
+    import Extensions.jdc_include
+    self.JdC_aux=Extensions.jdc_include.JdC_include
+    # un include partage la table des unites avec son parent (jdc)
+    self.recorded_units=self.parent.recorded_units
+    self.build_jdcaux(fichier,text)
+
+  def build_poursuite(self,fichier,text):
+    import Extensions.jdc_include
+    self.JdC_aux=Extensions.jdc_include.JdC_poursuite
+    # une poursuite a sa propre table d'unites
+    self.recorded_units={}
+    self.build_jdcaux(fichier,text)
+
+  def build_jdcaux(self,fichier,text):
+    """
+         Cree un jdc auxiliaire initialise avec text. 
+         Initialise le nom du fichier associé avec fichier
+         N'enregistre pas d'association unite <-> fichier
+    """
+    self.fichier_ini = fichier
+    self.fichier_text= text
+    self.fichier_unite=None
+    self.fichier_err = None
+    try:
+       contexte = self.get_contexte_jdc(fichier,text)
+       if contexte is None :
+          # Impossible de construire le jdc auxiliaire (sortie par None)
+          # On simule une sortie par exception
+          raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
+       else:
+          # La construction du jdc auxiliaire est allée au bout
+          self.contexte_fichier_init = contexte
+       self.init_modif()
+       self.fin_modif()
+    except:
+       # Impossible de construire le jdc auxiliaire (sortie par exception)
+       l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
+       if self.jdc.appli:
+          self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
+                                        message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
+                                       )
+       self.g_context={}
+       self.etapes=[]
+       self.jdc_aux=None
+       self.fichier_err = string.join(l)
+       self.contexte_fichier_init={}
+       self.init_modif()
+       self.fin_modif()
+       raise
 
   def make_contexte_include(self,fichier,text):
     """
@@ -399,9 +515,9 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       except:
          l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
          self.fichier_err = string.join(l)
-         #self.etapes=[]
          self.g_context={}
-
+         self.etapes=[]
+         self.jdc_aux=None
          self.old_contexte_fichier_init=old_context
          self.contexte_fichier_init={}
          self.reevalue_sd_jdc()
@@ -411,59 +527,60 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       self.fichier_err = None
       self.old_contexte_fichier_init=old_context
       self.reevalue_sd_jdc()
-      #print "reevalue_fichier_init",self.jdc_aux.context_ini
 
   def update_fichier_init(self,unite):
       """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur 
          les noms des fichiers
          Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
+         L'include a été initialisé précédemment. Le jdc auxiliaire existe.
       """
-      #print "update_fichier_init",unite
-      self.fichier_err=None
+      #print "update_fichier_init",unite,self.fichier_unite 
       self.old_contexte_fichier_init=self.contexte_fichier_init
       old_fichier_ini=self.fichier_ini
+      if not hasattr(self,"jdc_aux"):self.jdc_aux=None
+      old_jdc_aux=self.jdc_aux
 
       #print "update_fichier_init",self,self.parent,self.parent.recorded_units
 
-      #if unite != self.fichier_unite or not self.parent.recorded_units.has_key(unite):
-      if not self.parent.recorded_units.has_key(unite):
-         # Nouvelle unite
-         f,text=self.get_file(unite=unite,fic_origine=self.parent.nom)
-         units={}
-         if f is not None:
+      if self.fichier_unite is None:
+         # L'unité n'était pas définie précédemment. On ne change que l'unite
+         #print "update_fichier_init","pas de changement dans include"
+         self.fichier_unite=unite
+         return
+      elif unite == self.fichier_unite :
+         # L'unité n'a pas changé
+         #print "update_fichier_init","pas de changement dans include 3"
+         return
+      elif unite != self.fichier_unite :
+         # L'unité était définie précédemment. On remplace l'include 
+         #
+         f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
+         if f is None:
+            # Le fichier associé n'a pas pu etre defini
+            # on change l'unite associée mais pas l'include
+            #print "update_fichier_init","pas de changement dans include 2"
+            self.fichier_unite=unite
+            return
+         else:
             self.fichier_ini = f
             self.fichier_text=text
-         self.recorded_units=units
-         if self.fichier_ini is None and self.jdc.appli:
-            self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
-                     message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
-      else:
-         # Unite existante
-         f,text,units=self.parent.recorded_units[unite]
-         self.fichier_ini = f
-         self.fichier_text=text
-         self.recorded_units=units
+            self.fichier_unite=unite
+         #print "update_fichier_init",self.recorded_units
 
-      if self.fichier_ini is None:
-         # Le fichier n'est pas défini
-         self.fichier_err="Le fichier associé n'est pas défini"
-         self.parent.change_unit(unite,self,self.fichier_unite)
-         self.g_context={}
-         self.contexte_fichier_init={}
-         self.parent.reset_context()
-         self.reevalue_sd_jdc()
-         return
+      #print "update_fichier_init",self.fichier_ini,self.fichier_text,self.fichier_unite
 
       if old_fichier_ini == self.fichier_ini:
          # Le fichier inclus n'a pas changé. On ne recrée pas le contexte
+         # mais on enregistre le changement d'association unite <-> fichier
          #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini
+         self.parent.record_unit(unite,self)
          return
 
       try:
+        self.fichier_err=None
         self.make_contexte_include(self.fichier_ini,self.fichier_text)
         # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
         # avant d'appeler change_unit
-        self.parent.change_unit(unite,self,self.fichier_unite)
       except:
         # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
         l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
@@ -471,19 +588,24 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
         # mais on n'utilise pas les concepts crees par ce fichier
         # on met l'etape en erreur : fichier_err=string.join(l)
         self.fichier_err=string.join(l)
-        self.parent.change_unit(unite,self,self.fichier_unite)
         self.g_context={}
+        self.etapes=[]
+        self.jdc_aux=None
         self.contexte_fichier_init={}
 
+      if old_jdc_aux:
+         old_jdc_aux.close()
+      self.parent.record_unit(unite,self)
       # Le contexte du parent doit etre reinitialise car les concepts 
       # produits ont changé
       self.parent.reset_context()
       # Si des concepts ont disparu lors du changement de fichier, on 
       # demande leur suppression
       self.reevalue_sd_jdc()
-      #print "update_fichier_init",self.jdc_aux.context_ini
+      #print "update_fichier_init",self.jdc_aux.context_ini.keys()
 
   def record_unite(self):
+      #print "record_unite",self.nom
       if self.nom == "POURSUITE":
          self.parent.record_unit(None,self)
       else:
@@ -495,40 +617,74 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
          Initialise en plus recorded_units
       """
       #print "get_file_memo",unite,fic_origine,self,self.parent
-      #print self.parent.old_recorded_units
       #print self.parent.recorded_units
       if unite is None:
+         # On est dans le cas d'une poursuite. On ne reutilise aucune unite de parent
          units={}
       else:
+         # On est dans le cas d'un include. On reutilise toutes les unites de parent
          units=self.parent.recorded_units
-      if self.parent.old_recorded_units.has_key(unite):
-         f,text,units=self.parent.old_recorded_units[unite]
-         #print id(self.recorded_units)
-         self.recorded_units=units
-         #print id(self.recorded_units)
-         return f,text
+
+      if self.parent.recorded_units.has_key(unite):
+         f,text,units=self.parent.recorded_units[unite]
       elif self.jdc :
          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
       else:
          f,text=None,None
+
       self.recorded_units=units
       if f is None and self.jdc.appli:
          self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
                           message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
       return f,text
 
+  def update_context(self,d):
+      """
+         Met à jour le contexte contenu dans le dictionnaire d
+         Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte
+         Une fonction enregistree dans op_init peut egalement modifier le contexte
+      """
+      #print "update_context",self,self.nom,d.keys()
+      if hasattr(self,"jdc_aux") and self.jdc_aux:
+            #ATTENTION: update_context NE DOIT PAS appeler reset_context
+            # car il appelle directement ou indirectement update_context
+            # equivalent a reset_context. Evite les recursions
+            self.jdc_aux.context_ini=d.copy()
+            self.jdc_aux.current_context={}
+            self.jdc_aux.index_etape_courante=0
+            #ATTENTION: il ne faut pas utiliser self.jdc_aux.get_contexte_avant
+            #car cet appel conduit a des remontées multiples incohérentes dans le
+            # ou les parents. 
+            #get_context_avant appelle update_context qui NE DOIT PAS appeler get_contexte_avant
+            #On n'a besoin que d'un update local connaissant
+            # le contexte amont : d qui sert a reinitialiser self.context_ini
+            for e in self.etapes:
+                e.update_context(d)
+            return
+
+      if type(self.definition.op_init) == types.FunctionType:
+        apply(self.definition.op_init,(self,d))
+      if self.sd != None:d[self.sd.nom]=self.sd
+      for co in self.sdprods:
+        d[co.nom]=co
+      #print "update_context.fin",d.keys()
+
+#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
+  def supprime(self):
+      #print "supprime",self
+      if hasattr(self,"jdc_aux") and self.jdc_aux:
+         self.jdc_aux.supprime_aux()
+         self.jdc_aux=None
+      Noyau.N_MACRO_ETAPE.MACRO_ETAPE.supprime(self)
+
 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
   def get_file(self,unite=None,fic_origine=''):
       """Retourne le nom du fichier et le source correspondant a l'unite unite
-         Initialise en plus recorded_units
       """
-      #print "get_file",unite
-      units={}
       if self.jdc :
          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
       else:
          f,text=None,None
-      self.recorded_units=units
       return f,text
 
 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
@@ -563,7 +719,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
            raise
          self.JdC_aux=Extensions.jdc_include.JdC_include
 
-         if f is None:
+         #print "make_include",self.fichier_ini,self.fichier_text 
+         if f is None and not text:
              self.fichier_err="Le fichier INCLUDE n est pas defini"
              self.parent.record_unit(unite,self)
              raise Exception(self.fichier_err)
@@ -576,10 +733,12 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
            if self.jdc.appli:
               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
-                                            message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
+                                            message="Le contenu de ce fichier ne sera pas pris en compte\n"+string.join(l)
                                            )
            self.parent.record_unit(unite,self)
            self.g_context={}
+           self.etapes=[]
+           self.jdc_aux=None
            self.fichier_err = string.join(l)
            self.contexte_fichier_init={}
            raise
@@ -616,12 +775,14 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.JdC_aux=Extensions.jdc_include.JdC_include
     try:
        self.make_contexte_include(self.fichier_ini ,self.fichier_text)
-       self.parent.record_unit(self.fichier_unite,self)
+       #self.parent.record_unit(self.fichier_unite,self)
     except:
        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
        self.fichier_err = string.join(l)
-       self.parent.record_unit(self.fichier_unite,self)
+       #self.parent.record_unit(self.fichier_unite,self)
        self.g_context={}
+       self.etapes=[]
+       self.jdc_aux=None
        self.contexte_fichier_init={}
        raise
 
@@ -680,9 +841,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
            raise
          self.JdC_aux=Extensions.jdc_include.JdC_poursuite
          self.contexte_fichier_init={}
+         #print "make_poursuite",self.fichier_ini,self.fichier_text
 
          if f is None:
              self.fichier_err="Le fichier POURSUITE n'est pas defini"
+             self.jdc_aux=None
              self.parent.record_unit(None,self)
              raise Exception(self.fichier_err)
 
@@ -697,6 +860,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
                                            )
            self.parent.record_unit(None,self)
            self.g_context={}
+           self.etapes=[]
+           self.jdc_aux=None
            self.fichier_err = string.join(l)
            self.contexte_fichier_init={}
            raise
@@ -706,104 +871,3 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
          # et on leve une exception si une erreur a été enregistrée
          self.update_fichier_init(None)
          if self.fichier_err is not None: raise Exception(self.fichier_err)
-
-#ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro 
-  def type_sdprod(self,co,t):
-      """
-           Cette methode a pour fonction de typer le concept co avec le type t
-            dans les conditions suivantes
-            1- co est un concept produit de self
-            2- co est un concept libre : on le type et on l attribue à self
-           Elle enregistre egalement les concepts produits (on fait l hypothese
-            que la liste sdprods a été correctement initialisee, vide probablement)
-      """
-      #print "type_sdprod",co,t
-      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:
-         # 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]
-         #
-         # Attention : la seule modif est ici : Accas.CO au lieu de CO
-         #
-         if not Accas.CO 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:
-         # 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:
-         # 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 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 Accas.CO 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
-         # 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):
-         # 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:
-         # Cas 5 : le concept est produit par une autre étape
-         # On ne fait rien
-         return
-