"""
"""
# Modules Python
+import sys
import string,types
from copy import copy
def get_sdname(self):
if CONTEXT.debug : print "SDNAME ",self.reuse,self.sd,self.sd.get_name()
+ sdname=''
if self.reuse != None:
sdname= self.reuse.get_name()
else:
- sdname=self.sd.get_name()
+ if self.sd:sdname=self.sd.get_name()
if string.find(sdname,'sansnom') != -1 or string.find(sdname,'SD_') != -1:
# dans le cas où la SD est 'sansnom' ou 'SD_' on retourne la chaîne vide
return ''
"""
Met l'état de l'étape à : modifié
Propage la modification au parent
- Si la fonction op_init existe, l'active
"""
# Une action
# doit etre realisée apres init_modif et la validite reevaluée
ex : INCLUDE et POURSUITE
"""
if self.isvalid() :
- if type(self.definition.op_init) == types.FunctionType :
- # XXX Normalement en mode editeur g_context ne peut pas etre utilisé
- apply(self.definition.op_init,(self,self.parent.g_context))
- self.state = 'modified'
-
+ d=self.parent.get_contexte_apres(self)
+ if self.parent:
+ self.parent.fin_modif()
+
def nomme_sd(self,nom) :
"""
Cette méthode a pour fonction de donner un nom (nom) au concept
Il faut ajouter la sd si elle existe au contexte global du JDC
et à la liste des sd
"""
+ if self.actif:return
self.actif = 1
if not self.sd : return
- # XXX Pourquoi faut-il faire ce qui suit ??? par defaut les etapes sont actives
try:
self.jdc.append_sdprod(self.sd)
except:
self.jdc.del_sdprod(self.sd)
self.jdc.delete_concept_after_etape(self,self.sd)
+ 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
+ """
+ if type(self.definition.op_init) == types.FunctionType:
+ apply(self.definition.op_init,(self,d))
+ if self.sd:
+ if d.has_key(self.sd.nom):
+ # Le concept est deja defini
+ if self.reuse and self.reuse is d[self.sd.nom]:
+ # Le concept est reutilise : situation normale
+ pass
+ else:
+ # 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
+
def supprime_sdprods(self):
"""
Fonction:
Une procedure n'en a aucun
Une macro en a en général plus d'un
"""
- # XXX pour les macros il faudrait peut etre aussi
- # supprimer les concepts a droite du = ???
if not self.is_reentrant() :
# l'étape n'est pas réentrante
# le concept retourné par l'étape est à supprimer car il était
for child in self.mc_liste :
child.delete_concept(sd)
+ def replace_concept(self,old_sd,sd):
+ """
+ Inputs :
+ old_sd=concept remplace
+ sd = nouveau concept
+ Fonction :
+ Mettre a jour les mots cles de l etape et eventuellement
+ le concept produit si reuse
+ suite au remplacement du concept old_sd
+ """
+ if self.reuse and self.reuse == old_sd:
+ self.sd=self.reuse=sd
+ self.init_modif()
+ for child in self.mc_liste :
+ child.replace_concept(old_sd,sd)
+
def make_register(self):
"""
Initialise les attributs jdc, id, niveau et réalise les
# En plus il faut rendre coherents sdnom et sd.nom
self.sd=None
self.sdnom=None
+ self.state="unchanged"
self.valid=0
return self.sd
+
#raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
# 'fichier : ',self.appel[1],e)
except EOFError:
Inputs :
sd=concept detruit
Fonction :
- Mettre a jour les mos cles de l etape et eventuellement le concept produit si reuse
+ Mettre a jour les mots cles de l etape et eventuellement le concept produit si reuse
suite à la disparition du concept sd
Seuls les mots cles simples MCSIMP font un traitement autre que de transmettre aux fils,
sauf les objets FORM_ETAPE qui doivent vérifier que le concept détruit n'est pas
"""
self.init_modif()
+ def replace_concept(self,old_sd,sd):
+ """
+ Inputs :
+ old_sd=concept remplace
+ sd = nouveau concept
+ Fonction :
+ Les objets FORM_ETAPE devraient vérifier que le concept remplacé n'est pas
+ utilisé dans le corps de la fonction
+ """
+ self.init_modif()
+
if sd:return sd
return self.get_sd_apres_etape(nom_sd,etape,avec)
+ def get_contexte_avant(self,etape):
+ """
+ Retourne le dictionnaire des concepts connus avant etape
+ On tient compte des commandes qui modifient le contexte
+ comme DETRUIRE ou les macros
+ Si etape == None, on retourne le contexte en fin de JDC
+ """
+ # L'étape courante pour laquelle le contexte a été calculé est
+ # mémorisée dans self.index_etape_courante
+ # XXX on pourrait faire mieux dans le cas PAR_LOT="NON" : en
+ # mémorisant l'étape
+ # courante pendant le processus de construction des étapes.
+ # Si on insère des commandes (par ex, dans EFICAS), il faut préalablement
+ # remettre ce pointeur à 0
+ if etape:
+ index_etape=self.etapes.index(etape)
+ else:
+ index_etape=len(self.etapes)
+ if index_etape >= self.index_etape_courante:
+ # On calcule le contexte en partant du contexte existant
+ d=self.current_context
+ if self.index_etape_courante==0 and self.context_ini:
+ d.update(self.context_ini)
+ liste_etapes=self.etapes[self.index_etape_courante:index_etape]
+ else:
+ d=self.current_context={}
+ if self.context_ini:d.update(self.context_ini)
+ liste_etapes=self.etapes
+
+ for e in liste_etapes:
+ if e is etape:
+ break
+ if e.isactif():
+ e.update_context(d)
+ self.index_etape_courante=index_etape
+ return d
+
+ def get_contexte_apres(self,etape):
+ """
+ Retourne le dictionnaire des concepts connus apres etape
+ On tient compte des commandes qui modifient le contexte
+ comme DETRUIRE ou les macros
+ Si etape == None, on retourne le contexte en fin de JDC
+ """
+ if not etape: return self.get_contexte_avant(etape)
+
+ d=self.get_contexte_avant(etape)
+ if etape.isactif():etape.update_context(d)
+ self.index_etape_courante=self.index_etape_courante+1
+ return d
+
def active_etapes(self):
"""
Cette méthode a pour fonction de désactiver les étapes qui doivent
un jeu de commandes
"""
self.init_modif()
+ # On memorise le contexte avant l'etape a supprimer
+ d=self.get_contexte_avant(etape)
+ index_etape=self.etapes.index(etape)
+
self.etapes.remove(etape)
if etape.niveau is not self:
# Dans ce cas l'étape est enregistrée dans un niveau
etape.supprime_sdprods()
self.active_etapes()
- def del_sdprod(self,sd):
- """
- Supprime la SD sd de la liste des sd et des dictionnaires de contexte
- """
- if sd in self.sds : self.sds.remove(sd)
- if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
-
- def delete_concept(self,sd):
- """
- Inputs :
- sd=concept detruit
- Fonction :
- Mettre a jour les etapes du JDC suite à la disparition du
- concept sd
- Seuls les mots cles simples MCSIMP font un traitement autre
- que de transmettre aux fils
- """
- for etape in self.etapes :
- etape.delete_concept(sd)
+ # Apres suppression de l'etape il faut controler que les etapes
+ # suivantes ne produisent pas des concepts DETRUITS dans op_init de etape
+ for e in self.etapes[index_etape:]:
+ e.control_sdprods(d)
+
+ self.reset_context()
+ self.fin_modif()
def analyse(self):
self.compile()
if self.appli:
self.appli.send_message(message)
-#XXX ne semble pas servir pour JDC
-# def reevalue_sd_jdc(self):
- #"""
- #Avec la liste des SD qui ont été supprimées, propage la disparition de ces
- #SD dans toutes les étapes et descendants
- #"""
- #l_sd = self.diff_contextes()
- #if len(l_sd) == 0 : return
- #for sd in l_sd:
- #self.jdc.delete_concept(sd)
-
def init_modif(self):
"""
Méthode appelée au moment où une modification va être faite afin de
self.state = 'modified'
def fin_modif(self):
+ self.isvalid()
pass
def get_liste_mc_inconnus(self):
fproc=open(file,'r')
text=fproc.read()
fproc.close()
+ if file == None : return None,None
text=string.replace(text,'\r\n','\n')
linecache.cache[file]=0,0,string.split(text,'\n'),file
return file,text
"""
return []
- def NommerSdprod(self,sd,sdnom):
+ def NommerSdprod(self,sd,sdnom,restrict='non'):
"""
- Nomme la SD apres avoir verifie que le nommage est possible : nom
- non utilise
+ Nomme la SD apres avoir verifie que le nommage est possible :
+ nom non utilise
Si le nom est deja utilise, leve une exception
Met le concept créé dans le concept global g_context
"""
# XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
# Le dictionnaire g_context ne représente pas le contexte
# effectif avant une étape.
- # Il faut utiliser get_contexte_avant avec une indication de l'étape
- # traitée. Pour le moment, il n'y a pas de moyen de le faire : ajouter
- # un attribut dans le JDC ???
+ # Il faut utiliser get_contexte_avant avec indication de l'étape
+ # traitée.
+ # Cette etape est indiquee par l'attribut _etape_context qui a ete
+ # positionné préalablement par un appel à set_etape_context
+
if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
+
if self._etape_context:
o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
else:
- o=self.g_context.get(sdnom,None)
+ o=self.sds_dict.get(sdnom,None)
+
if isinstance(o,ASSD):
raise AsException("Nom de concept deja defini : %s" % sdnom)
# ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
# Ajoute a la creation (appel de reg_sd).
- self.g_context[sdnom]=sd
+ self.sds_dict[sdnom]=sd
sd.nom=sdnom
def set_etape_context(self,etape):
self.current_context={}
self.index_etape_courante=0
+ def del_sdprod(self,sd):
+ """
+ Supprime la SD sd de la liste des sd et des dictionnaires de contexte
+ """
+ if sd in self.sds : self.sds.remove(sd)
+ if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
+ if self.sds_dict.has_key(sd.nom) : del self.sds_dict[sd.nom]
+
def del_param(self,param):
"""
Supprime le paramètre param de la liste des paramètres
if fonction in self.fonctions : self.fonctions.remove(fonction)
if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]
+ def append_sdprod(self,sd):
+ """
+ Ajoute la SD sd à la liste des sd en vérifiant au préalable qu'une SD de
+ même nom n'existe pas déjà
+ """
+ if sd == None or sd.nom == None:return
+
+ o=self.sds_dict.get(sd.nom,None)
+ if isinstance(o,ASSD):
+ raise AsException("Nom de concept deja defini : %s" % sd.nom)
+ self.sds_dict[sd.nom]=sd
+ self.g_context[sd.nom] = sd
+ if sd not in self.sds : self.sds.append(sd)
+
+ def append_param(self,param):
+ """
+ Ajoute le paramètre param à la liste des params
+ et au contexte global
+ """
+ # il faudrait vérifier qu'un paramètre de même nom n'existe pas déjà !!!
+ if param not in self.params : self.params.append(param)
+ self.g_context[param.nom]=param
+
+ def append_fonction(self,fonction):
+ """
+ Ajoute la fonction fonction à la liste des fonctions
+ et au contexte global
+ """
+ # il faudrait vérifier qu'une fonction de même nom n'existe pas déjà !!!
+ if fonction not in self.fonctions : self.fonctions.append(fonction)
+ self.g_context[fonction.nom]=fonction
+
+ def delete_concept_after_etape(self,etape,sd):
+ """
+ Met à jour les étapes du JDC qui sont après etape en fonction
+ de la disparition du concept sd
+ """
+ index = self.etapes.index(etape)+1
+ if index == len(self.etapes) :
+ return # etape est la dernière étape du jdc ...on ne fait rien !
+ for child in self.etapes[index:]:
+ child.delete_concept(sd)
+
+ def delete_concept(self,sd):
+ """
+ Inputs :
+ sd=concept detruit
+ Fonction :
+ Mettre a jour les etapes du JDC suite à la disparition du
+ concept sd
+ Seuls les mots cles simples MCSIMP font un traitement autre
+ que de transmettre aux fils
+ """
+ for etape in self.etapes :
+ etape.delete_concept(sd)
+
+ def replace_concept_after_etape(self,etape,old_sd,sd):
+ """
+ Met à jour les étapes du JDC qui sont après etape en fonction
+ du remplacement du concept sd
+ """
+ index = self.etapes.index(etape)+1
+ if index == len(self.etapes) :
+ return # etape est la dernière étape du jdc ...on ne fait rien !
+ for child in self.etapes[index:]:
+ child.replace_concept(old_sd,sd)
+
+ def dump_state(self):
+ print "dump_state"
+ print "JDC.state: ",self.state
+ for etape in self.etapes :
+ print etape.nom+".state: ",etape.state
+
+#ATTENTION cette methode surcharge la methode du package Validation : a reintegrer
+ def isvalid(self,cr='non'):
+ """
+ Méthode booléenne qui retourne 0 si le JDC est invalide, 1 sinon
+ """
+ # FR : on prend en compte l'état du JDC ('unchanged','modified','undetermined')
+ # afin d'accélérer le test de validité du JDC
+ if self.state == 'unchanged':
+ return self.valid
+ else:
+ valid = 1
+ texte,test = self.verif_regles()
+ if test == 0:
+ if cr == 'oui': self.cr.fatal(string.strip(texte))
+ valid = 0
+ if valid :
+ for e in self.etapes:
+ if not e.isactif() : continue
+ if not e.isvalid():
+ valid = 0
+ break
+ self.state="unchanged"
+ self.valid = valid
+ return self.valid
+
"""
"""
# Modules Python
+import sys
import traceback,types,string
# Modules Eficas
from Noyau.N_ASSD import ASSD
# import rajoutés suite à l'ajout de Build_sd --> à résorber
-import Noyau
+import Noyau, Validation.V_MACRO_ETAPE
from Noyau import N_Exception
from Noyau.N_Exception import AsException
# fin import à résorber
class MACRO_ETAPE(I_ETAPE.ETAPE):
def __init__(self):
- # XXX CCAR : ne suis pas certain que typret doive etre
- # initialise à None (a verifier)
self.typret=None
def get_sdprods(self,nom_sd):
Fonction : retourne le concept produit par l etape de nom nom_sd
s il existe sinon None
"""
- if self.sd:
- if self.sd.nom == nom_sd:
- return self.sd
+ if self.sd and self.sd.nom == nom_sd :return self.sd
for co in self.sdprods:
- if co.nom==nom_sd:return co
+ if co.nom == nom_sd:return co
+ if type(self.definition.op_init) == types.FunctionType:
+ d={}
+ apply(self.definition.op_init,(self,d))
+ return d.get(nom_sd,None)
return None
- def make_contexte(self,fichier,text):
- """
- Cette méthode sert à créer un contexte en interprétant un texte source
- Python
- """
- # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
- contexte = self.get_contexte_jdc(fichier,text)
- if contexte == None :
- raise Exception("Impossible de relire le fichier")
- else:
- self.g_context = contexte
- if hasattr(self,'contexte_fichier_init'):
- self.old_contexte_fichier_init = self.contexte_fichier_init
- self.contexte_fichier_init = contexte
- # XXX la validité ne doit pas etre forcée à 1. Que faut-il faire exactement ???
- self.init_modif()
- #self.valid = 1
- #self.state = 'unchanged'
-
def get_contexte_jdc(self,fichier,text):
"""
Interprète text comme un texte de jdc et retourne le
contexte final
cad le dictionnaire des sd disponibles à la dernière étape
Si text n'est pas un texte de jdc valide, retourne None
+ ou leve une exception
--> utilisée par ops.POURSUITE et INCLUDE
"""
try:
- # on essaie de créer un objet JDC...
+ # on essaie de créer un objet JDC auxiliaire avec un contexte initial
context_ini = self.parent.get_contexte_avant(self)
+ # Indispensable avant de creer un nouveau JDC
CONTEXT.unset_current_step()
- j=self.jdc.definition(procedure=text,cata=self.jdc.cata,
- nom=fichier,
- context_ini = context_ini,
- appli=self.jdc.appli)
+ args=self.jdc.args
+ prefix_include=None
+ if hasattr(self,'prefix'):
+ prefix_include=self.prefix
+
+ j=self.JdC_aux( procedure=text,cata=self.jdc.cata,
+ nom=fichier,
+ context_ini = context_ini,
+ appli=self.jdc.appli,
+ jdc_pere=self.jdc,etape_include=self,
+ prefix_include=prefix_include,**args)
+
j.analyse()
- # XXX en passant par un jdc auxiliaire, on risque de rendre les etapes inactives
- # on les force dans l'etat actif
- for etape in j.etapes:
- etape.active()
except:
traceback.print_exc()
+ # On force le contexte (etape courante) à self
+ CONTEXT.unset_current_step()
+ CONTEXT.set_current_step(self)
return None
- CONTEXT.set_current_step(self)
+
if not j.cr.estvide():
- raise Exception("Impossible de relire le fichier\n"+str(j.cr))
+ # On force le contexte (etape courante) à self
+ CONTEXT.unset_current_step()
+ CONTEXT.set_current_step(self)
+ # Erreurs dans l'INCLUDE. On garde la memoire du fichier mais on n'insere pas les concepts
+ # et les etapes. Ce traitement doit etre fait par l'appelant qui recoit l'exception
+ raise Exception("Impossible de relire le fichier\n"+str(j.cr))
+
+ cr=j.report()
+ if not cr.estvide():
+ # On force le contexte (etape courante) à self
+ CONTEXT.unset_current_step()
+ CONTEXT.set_current_step(self)
+ raise Exception("Le fichier include contient des erreurs\n"+str(j.cr))
+
+ # Cette verification n'est plus necessaire elle est integree dans le JDC_INCLUDE
+ #self.verif_contexte(j_context)
- #XXX la validité d'un source inclus n'est pas identique à celle d'un JDC complet
- # impossible de la tester en dehors du JDC d'accueil
- #cr=j.report()
- #if not cr.estvide():
- # raise Exception("Le fichier contient des erreurs\n"+str(j.cr))
+ # On recupere le contexte apres la derniere etape
j_context=j.get_contexte_avant(None)
- # XXX j.g_context doit donner le meme résultat
- # On retourne le contexte apres la derniere etape
- # XXX j.supprime() ???
- self.verif_contexte(j_context)
- # Le contexte est acceptable. On récupère les étapes internes (pour validation)
+
+ # On remplit le dictionnaire des concepts produits inclus
+ # en retirant les concepts présents dans le contexte initial
+ self.g_context.clear()
+ for k,v in j_context.items():
+ if not context_ini.has_key(k) or context_ini[k] != v:
+ self.g_context[k]=v
+
+ # On récupère les étapes internes (pour validation)
self.etapes=j.etapes
+
+ # ainsi que le contexte courant
+ self.current_context=j.current_context
+ self.index_etape_courante=j.index_etape_courante
+
+ # XXX j.supprime() ???
+ # On force le contexte (etape courante) à self
+ CONTEXT.unset_current_step()
+ CONTEXT.set_current_step(self)
+
return j_context
def verif_contexte(self,context):
def reevalue_sd_jdc(self):
"""
Avec la liste des SD qui ont été supprimées, propage la
- disparition de ces SD dans totues les étapes et descendants
+ disparition de ces SD dans toutes les étapes et descendants
"""
- l_sd = self.diff_contextes()
- if len(l_sd) == 0 : return
- for sd in l_sd:
- self.jdc.delete_concept(sd)
+ l_sd_supp,l_sd_repl = self.diff_contextes()
+ for sd in l_sd_supp:
+ self.parent.delete_concept_after_etape(self,sd)
+ for old_sd,sd in l_sd_repl:
+ self.parent.replace_concept_after_etape(self,old_sd,sd)
def diff_contextes(self):
"""
Réalise la différence entre les 2 contextes
old_contexte_fichier_init et contexte_fichier_init
- cad retourne la liste des sd qui ont disparu
+ cad retourne la liste des sd qui ont disparu ou ne derivent pas de la meme classe
+ et des sd qui ont ete remplacees
"""
- if not hasattr(self,'old_contexte_fichier_init'):return []
+ if not hasattr(self,'old_contexte_fichier_init'):return [],[]
l_sd_suppressed = []
+ l_sd_replaced = []
for old_key in self.old_contexte_fichier_init.keys():
if not self.contexte_fichier_init.has_key(old_key):
if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
- return l_sd_suppressed
+ else:
+ if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
+ # Un concept de meme nom existe
+ old_class=self.old_contexte_fichier_init[old_key].__class__
+ if not isinstance(self.contexte_fichier_init[old_key],old_class):
+ # S'il n'est pas d'une classe derivee, on le supprime
+ l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
+ else:
+ l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key]))
+ return l_sd_suppressed,l_sd_replaced
+ 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
+ """
+ if type(self.definition.op_init) == types.FunctionType:
+ apply(self.definition.op_init,(self,d))
+ if self.sd:
+ if d.has_key(self.sd.nom):
+ # Le concept est deja defini
+ if self.reuse and self.reuse is d[self.sd.nom]:
+ # Le concept est reutilise : situation normale
+ pass
+ else:
+ # 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
+ # On verifie les concepts a droite du signe =
+ for co in self.sdprods:
+ if d.has_key(co.nom) and co is not d[co.nom] :
+ self.delete_concept(co)
+ else:
+ d[co.nom]=co
+
+
def supprime_sdprods(self):
"""
Fonction:
# Si la macro a des etapes et des concepts inclus, on les detruit
for nom_sd,co in self.g_context.items():
if not isinstance(co,ASSD):continue
- print "Delete: ",self.nom,co.nom
self.parent.del_sdprod(co)
self.parent.delete_concept(co)
# On met g_context à blanc
self.g_context={}
+#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
def Build_sd(self,nom):
"""
Construit le concept produit de l'opérateur. Deux cas
# 1. on annule la sd associée à self
# 2. on la conserve mais il faut qu'elle soit correcte et la retourner
# En plus il faut rendre coherents sdnom et sd.nom
+ # On choisit de retourner None et de mettre l'etape invalide
self.sd=None
self.sdnom=None
+ self.state="unchanged"
self.valid=0
return self.sd
#raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
'fichier : ',self.appel[1]+'\n',
string.join(l))
+
+ def make_contexte_include(self,fichier,text):
+ """
+ Cette méthode sert à créer un contexte en interprétant un texte source
+ Python
+ """
+ # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
+ contexte = self.get_contexte_jdc(fichier,text)
+ if contexte == None :
+ raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
+ else:
+ # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE
+ # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion
+ # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits
+ # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts
+ # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc)
+ # g_context est utilisé pour avoir les concepts produits par la macro
+ # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro
+ self.contexte_fichier_init = contexte
+
+ def reevalue_fichier_init(self):
+ """Recalcule les concepts produits par le fichier enregistre"""
+ old_context=self.contexte_fichier_init
+ try:
+ self.make_contexte_include(self.fichier_ini ,self.fichier_text)
+ except:
+ l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
+ self.fichier_err = string.join(l)
+ self.etapes=[]
+ self.g_context={}
+
+ self.old_contexte_fichier_init=old_context
+ self.contexte_fichier_init={}
+ self.reevalue_sd_jdc()
+ return
+
+ # L'evaluation s'est bien passee
+ self.fichier_err = None
+ self.old_contexte_fichier_init=old_context
+ self.reevalue_sd_jdc()
+
+ def make_poursuite(self):
+ """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
+ """
+ if not hasattr(self,'fichier_ini') :
+ # Si le fichier n'est pas defini on le demande
+ f,text=self.get_file(fic_origine=self.parent.nom)
+ # On memorise le fichier retourne
+ self.fichier_ini = f
+ self.fichier_text = text
+ import Extensions.jdc_include
+ self.JdC_aux=Extensions.jdc_include.JdC_poursuite
+ self.contexte_fichier_init={}
+ if f is None:
+ self.fichier_err="Le fichier POURSUITE n'est pas defini"
+ else:
+ self.fichier_err=None
+
+ if self.fichier_err is not None: raise Exception(self.fichier_err)
+
+ try:
+ self.make_contexte_include(self.fichier_ini,self.fichier_text)
+ except:
+ 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 poursuite",
+ message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
+ )
+ self.g_context={}
+ self.etapes=[]
+ self.fichier_err = string.join(l)
+ self.contexte_fichier_init={}
+ raise
+
+ else:
+ # Si le fichier est deja defini on ne reevalue pas le fichier
+ # et on leve une exception si une erreur a été enregistrée
+ if self.fichier_err is not None: raise Exception(self.fichier_err)
+
+
+#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
+ def make_include(self,unite=None):
+ """
+ Inclut un fichier dont l'unite logique est unite
+ Cette methode est appelee par la fonction sd_prod de la macro INCLUDE
+ Si l'INCLUDE est invalide, la methode doit produire une exception
+ Sinon on retourne None. Les concepts produits par l'INCLUDE sont
+ pris en compte par le JDC parent lors du calcul du contexte (appel de ???)
+ """
+
+ # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE
+ # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
+ del self.unite
+ # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None
+ if not unite : return
+
+ if not hasattr(self,'fichier_ini') :
+ # Si le fichier n'est pas defini on le demande
+ f,text=self.get_file(unite=unite,fic_origine=self.parent.nom)
+ # On memorise le fichier retourne
+ self.fichier_ini = f
+ self.fichier_text = text
+ self.contexte_fichier_init={}
+ if f is None:
+ self.fichier_err="Le fichier INCLUDE n est pas defini"
+ else:
+ self.fichier_err=None
+ import Extensions.jdc_include
+ self.JdC_aux=Extensions.jdc_include.JdC_include
+
+ if self.fichier_err is not None: raise Exception(self.fichier_err)
+
+ try:
+ self.make_contexte_include(self.fichier_ini ,self.fichier_text)
+ except:
+ 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.fichier_err = string.join(l)
+ self.contexte_fichier_init={}
+ raise
+
+ else:
+ # Si le fichier est deja defini on ne reevalue pas le fichier
+ # et on leve une exception si une erreur a été enregistrée
+ #self.reevalue_fichier_init()
+ if self.fichier_err is not None: raise Exception(self.fichier_err)
+
+
+#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
+ def make_contexte(self,fichier,text):
+ """
+ Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
+ en interprétant un texte source Python
+ Elle est appelee par la fonction sd_prd d'INCLUDE_MATERIAU
+ """
+ # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
+ # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
+ if hasattr(self,'mat'):del self.mat
+ self.fichier_ini =fichier
+ self.fichier_text=text
+ self.fichier_err=None
+ self.contexte_fichier_init={}
+ # On specifie la classe a utiliser pour le JDC auxiliaire
+ import Extensions.jdc_include
+ self.JdC_aux=Extensions.jdc_include.JdC_include
+ try:
+ self.make_contexte_include(self.fichier_ini ,self.fichier_text)
+ except:
+ l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
+ self.g_context={}
+ self.etapes=[]
+ self.fichier_err = string.join(l)
+ self.contexte_fichier_init={}
+ raise
+
+#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
+ def update_sdprod(self,cr='non'):
+ # Cette methode peut etre appelee dans EFICAS avec des mots cles de
+ # la commande modifies. Ceci peut conduire a la construction ou
+ # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU
+ # Il faut donc positionner le current_step avant l'appel
+ CONTEXT.unset_current_step()
+ CONTEXT.set_current_step(self)
+ valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr)
+ CONTEXT.unset_current_step()
+ return valid
+
for child in self.mc_liste :
child.delete_concept(sd)
+ def replace_concept(self,old_sd,sd):
+ """
+ Inputs :
+ old_sd=concept remplace
+ sd = nouveau concept
+ Fonction :
+ Mettre a jour les fils de l objet suite au remplacement du
+ concept old_sd
+ """
+ for child in self.mc_liste :
+ child.replace_concept(old_sd,sd)
+
def delete_mc_global(self,mc):
"""
Supprime le mot-clé mc de la liste des mots-clés globaux de l'étape
for child in self.data :
child.delete_concept(sd)
+ def replace_concept(self,old_sd,sd):
+ """
+ Inputs :
+ old_sd=concept remplacé
+ sd=nouveau concept
+ Fonction :
+ Mettre a jour les fils de l objet suite au remplacement
+ du concept old_sd
+ """
+ for child in self.data :
+ child.replace_concept(old_sd,sd)
+
def copy(self):
"""
Réalise la copie d'une MCList
self.val = new_valeur
self.valeur = valeur
self.init_modif()
+ self.fin_modif()
return 1
else:
# On n'a pas trouve de concept ni réussi à évaluer la valeur
except:
traceback.print_exc()
return 0
- self.val=self.valeur
self.init_modif()
+ self.val=self.valeur
+ self.fin_modif()
return 1
elif type(new_valeur)==types.StringType and self.wait_TXM():
+ self.init_modif()
self.val = new_valeur
self.valeur = new_valeur
- self.init_modif()
+ self.fin_modif()
return 1
else:
return 0
else :
# on ne fait aucune vérification ...
+ self.init_modif()
try:
self.valeur = eval(new_valeur)
self.val = eval(new_valeur)
- self.init_modif()
+ self.fin_modif()
return 1
except:
self.valeur = new_valeur
self.val = new_valeur
- self.init_modif()
+ self.fin_modif()
return 1
def eval_valeur(self,new_valeur):
self.val=None
self.init_modif()
+ def replace_concept(self,old_sd,sd):
+ """
+ Inputs :
+ old_sd=concept remplacé
+ sd=nouveau concept
+ Fonction :
+ Met a jour la valeur du mot cle simple suite au remplacement
+ du concept old_sd
+ """
+ if type(self.valeur) == types.TupleType :
+ if old_sd in self.valeur:
+ self.valeur=list(self.valeur)
+ i=self.valeur.index(old_sd)
+ self.valeur[i]=sd
+ self.init_modif()
+ elif type(self.valeur) == types.ListType:
+ if old_sd in self.valeur:
+ i=self.valeur.index(old_sd)
+ self.valeur[i]=sd
+ self.init_modif()
+ else:
+ if self.valeur == old_sd:
+ self.valeur=sd
+ self.val=sd
+ self.init_modif()
+
def copy(self):
""" Retourne une copie de self """
objet = self.makeobjet()
new_objet = CO(nom_co)
CONTEXT.unset_current_step()
CONTEXT.set_current_step(cs)
+ self.init_modif()
self.valeur = new_objet
self.val = new_objet
- self.init_modif()
+ self.fin_modif()
step.reset_context()
# On force l'enregistrement de new_objet en tant que concept produit
# de la macro en appelant get_type_produit avec force=1
else:
l.append(sd)
self.valeur=l
+ # Est ce init_modif ou init_modif_up
+ # Normalement init_modif va avec fin_modif
self.init_modif()
+ self.fin_modif()
else:
if isinstance(self.valeur,ASSD) :
if self.valeur not in l_sd_avant_etape :
self.valeur = None
self.init_modif()
-
+ self.fin_modif()
def get_min_max(self):
"""
"""
return self.definition.type
+#ATTENTION : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
+# Elles doivent etre reintegrees des que possible
+
+ def isvalid(self,cr='non'):
+ """
+ Cette méthode retourne un indicateur de validité de l'objet
+ de type MCSIMP
+
+ - 0 si l'objet est invalide
+
+ - 1 si l'objet est valide
+
+ Le paramètre cr permet de paramétrer le traitement.
+ Si cr == 'oui'
+ la méthode construit également un comte-rendu de validation
+ dans self.cr qui doit avoir été créé préalablement.
+ """
+ if self.state == 'unchanged':
+ return self.valid
+ else:
+ valid = 1
+ if hasattr(self,'valid'):
+ old_valid = self.valid
+ else:
+ old_valid = None
+ v=self.valeur
+ # presence
+ if self.isoblig() and v == None :
+ if cr == 'oui' :
+ self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
+ valid = 0
+ # type,into ...
+ valid = self.verif_type(cr=cr)*self.verif_into(cr=cr)*self.verif_card(cr=cr)
+ self.valid = valid
+ self.state = 'unchanged'
+ # Si la validité du mot clé a changé, on le signale à l'objet parent
+ if not old_valid:
+ self.init_modif_up()
+ elif old_valid != self.valid :
+ self.init_modif_up()
+ return self.valid
+
# import rajoutés suite à l'ajout de Build_sd --> à résorber
-import traceback,types
+import sys
+import traceback,types,string
import Noyau
from Noyau import N_Exception
from Noyau.N_Exception import AsException
for child in self.mc_liste :
child.delete_concept(sd)
+ def replace_concept(self,old_sd,sd):
+ """
+ Inputs :
+ old_sd=concept remplacé
+ sd=nouveau concept
+ Fonction :
+ Mettre a jour les mots cles de l etape
+ suite au remplacement du concept old_sd
+ """
+ for child in self.mc_liste :
+ child.replace_concept(old_sd,sd)
+
def Build_sd(self):
"""
Cette methode applique la fonction op_init au contexte du parent