/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : DESB  v2.n                                                  */
/*    Fichier : marqoutput.c                                                */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : Marc LAURENTIN                        le : 06/09/1991     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include "head.h" 

short PROF_MAX ;

/**********************************************/
/*   Marque la sortie du cone dest_cone       */
/*   pointant sur source_cone                 */
/**********************************************/
void MarqOutput(source_cone, dest_cone)
cone_list *source_cone, *dest_cone;
{
list_list *out;

out=dest_cone->OUTCONE;
while (((cone_list*)out->DATA) != source_cone ) out=out->NEXT;

      if ((getptype(out->USER,OUTPUT_MARK)) == NULL)
   	 out->USER=addptype(out->USER,OUTPUT_MARK,(void*)NULL);
}


/****************************************************************************
 *                         fonction PropStepMarqOutput();                   *
 ****************************************************************************/
short PropStepMarqOutput(cone)
cone_list *cone;
{
list_list    *input;
locon_list   *userconx;
ptype_list   *user;
short        i;
chain_list * chain ;

   /* traitement des rebouclages */
   for(chain=FCF_CONE_LIST;chain!=NULL;chain=chain->NEXT)
   {
      if((cone_list*)chain->DATA == cone ) break ;
   }
   if(chain != NULL )
   {
   profondeur-- ;
   return(0);
   }
   else FCF_CONE_LIST=addchain(FCF_CONE_LIST,(void*)cone) ;

   if (((profondeur < PROF_MAX) 
        && ((cone->TYPE & LATCH) != LATCH) 
        && ((cone->TYPE & HZ) != HZ) 
        && ((cone->TYPE & CONFLICT) != CONFLICT)) ||
        (profondeur==0)) 
   { 
      if ((user=getptype(cone->USER,PROF)) != NULL)
      {
         if ((short)((long)user->DATA) <= profondeur)
         {
         profondeur--;
         FCF_CONE_LIST = FCF_CONE_LIST->NEXT ;
         return(1);
         }
         else user->DATA=(void*)((long)profondeur);
      }
      else cone->USER=addptype(cone->USER,PROF,(void*)((long)profondeur));
 
      for (input=(list_list*)cone->INCONE; input; input=input->NEXT) 
      { 
         if ((input->TYPE & LOOP) == LOOP) continue;
         
         if ((input->TYPE & EXT) != EXT) 
         {
         profondeur++;
         i=PropStepMarqOutput((cone_list*)input->DATA);
            if (i==1) 
            {
            MarqOutput(cone,(cone_list*)input->DATA);	
            continue;
            }
            else 
            {
            cone->TYPE |= FCF_LOOP ;
            }
         }

         else 
         {
         userconx=(locon_list*)input->DATA;
            if ((user=getptype(userconx->USER,OUTPUT_MARK)) == NULL)
            userconx->USER=addptype(userconx->USER,OUTPUT_MARK,(void*)cone);
            else 
            {
            /* on regarde si le cone qui a ce conx en entree est le meme */
            /* Si NON, on met NULL <=> plusieurs output mark */
               if((cone_list*)user->DATA!=cone) user->DATA=(void *)NULL ;
            }

            if((getptype(userconx->USER,DSB_CONTRAINT))!=NULL) Tag(userconx);
         }
      }
   profondeur--;
   FCF_CONE_LIST = FCF_CONE_LIST->NEXT ;
   return(1);
   }	

   else 
   {
   profondeur--;
   FCF_CONE_LIST = FCF_CONE_LIST->NEXT ;
   return(1);
   }
}


/****************************************************************************
 *                         fonction MyAddChain();                           *
 ****************************************************************************/

chain_list * MyAddChain(chaine, data)
chain_list * chaine ;
char * data ;
{
chain_list * courant;

   for (courant = chaine; courant != NULL ; courant = courant->NEXT)
   {
      if ((char*)courant->DATA == data) break;
   }

   if (courant == NULL) chaine=addchain(chaine,(void*)data);

return(chaine);
}
