/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : DESB  v2.n                                                  */
/*    Fichier : contrainte.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"

chain_list * HEAD_VARCON=NULL;    /* Liste des contraintes externes        */
extern chain_list * mux2fcf();    /* Recuperation des contraintes sur      */
                                  /* l'interface du bloc                   */

/****************************************************************************
 *                         fonction GetABL();                               *
 ****************************************************************************/
      /*------------------------------------------+
      |   Scan HEAD_VARCON retourne le pointeur   |
      |   "cellule chain_list" dont DATA pointe   |
      |    sur la liste entierement tagee         | 
      +------------------------------------------*/
chain_list *GetABL(pointeur)
chain_list *pointeur;
{
chain_list *pt;
list_list  *list;

   for (pt=pointeur; pt; pt=pt->NEXT) 
   {
      for (list=(list_list*)pt->DATA; list; list=list->NEXT) 
      {
         if ((list->TYPE & TAG) == TAG) continue;
         else break;
      }
      if (list == NULL) return(pt);
   }
return((chain_list*)NULL);
}

/****************************************************************************
 *                         fonction Tag();                                  *
 ****************************************************************************/
/*-----------------------------------+
|   Tag les instances de `conect`    |
|    dans la structure HEAD_VARCON   |
+-----------------------------------*/
void Tag(conect)
locon_list *conect;
{
chain_list *pt;
list_list  *list;

   for (pt=HEAD_VARCON; pt; pt=pt->NEXT) 
   {
      for (list=(list_list*)pt->DATA; list; list=list->NEXT) 
      {
         if (conect == (locon_list*)list->DATA) 
         { 
         list->TYPE |= TAG;
         }
      }
   }
}

/****************************************************************************
 *                         fonction freetag();                              *
 ****************************************************************************/
/*----------------------------------------+
|  libere les tag `TAG` dans HEAD_VARCON  |
+----------------------------------------*/
void freetag()
{
chain_list *pt;
list_list  *list;
 
   for (pt=HEAD_VARCON; pt; pt=pt->NEXT) 
   {
      for(list=(list_list*)pt->DATA;list;list=list->NEXT) list->TYPE=(long)0;
   }
}
 
/****************************************************************************
 *                         fonction AddPrimType();                          *
 ****************************************************************************/
/*---------------------------------------------+
|   type  PRIM les connecteurs contraints      |
|   de la liste `prim`, en variable primaire   | 
|   et leur associe un index bdd               |
+---------------------------------------------*/
void AddPrimType(prim)
list_list *prim;
{
list_list  *ptr;
locon_list *conect;
ptype_list *user;

   for (ptr=prim; ptr; ptr=ptr->NEXT) 
   {
   conect=(locon_list*)ptr->DATA;
   user=getptype(conect->USER,DSB_CONTRAINT);
   user->DATA = (void*)PRIM;
   conect->USER=addptype(conect->USER,BDD_INDEX,(void*)((long)index_bdd));
   CURRENT_BEFIG->BERIN=dsbAddBerin(CURRENT_BEFIG->BERIN,conect->NAME);
   fcfAddPrimConect(conect);
   index_bdd++;
   }
}

/****************************************************************************
 *                         fonction InitContrainte();                       *
 ****************************************************************************/
     /*---------------------------------------------------------------*
      | Lit le fichier mux exposant les contraintes externes          |
      | Met a jour le USER des connexteurs concernes                  |
      | Cree les listes de variables pour lesquelles des ABL existent |
      *---------------------------------------------------------------*/
short InitContrainte()
{
chain_list * chaine=NULL;
chaine=mux2fcf();
   if(chaine != NULL)
   {
   InitUserConnect(HEAD_DESBFIG,(chain_list*)chaine->DATA);
   HEAD_VARCON=fcfChainNameToLocon(chaine->NEXT);
   return(0);
   }
return(-1);
}

/****************************************************************************
 *                         fonction fcfChainNameToLocon();                  *
 ****************************************************************************/
chain_list *fcfChainNameToLocon(listchaine)
chain_list *listchaine;
{
list_list * varList = NULL ;
chain_list *chaine = NULL ;

   for(chaine=listchaine;chaine!=NULL;chaine=chaine->NEXT)
   {
   list_list * list ;
   varList=(list_list*)chaine->DATA;
      for(list=varList;list!=NULL;list=list->NEXT)
      {
      char * varName ;
      locon_list * conct;
      varName=(char*)list->DATA;
      conct=GetLocon(HEAD_DESBFIG,(char*)varName);
      list->DATA=(char*)conct;
      }
   }
return(listchaine);
}

/****************************************************************************
 *                         fonction InitUserConnect();                      *
 ****************************************************************************/
  /*-----------------------------------------------------*
   | Ajoute un user de type DSB_CONTRAINT aux connecteurs    |
   | concernes par des contraintes externes              |
   *-----------------------------------------------------*/
void InitUserConnect( fig , ptchain)
desafig_list *fig ;
chain_list *ptchain ;
{
chain_list * chain;
locon_list * connect;
ptype_list * user;
int nb_user = 0;
int nb_berin = 0;
chain_list * conxNotFind=NULL;

   for(chain=ptchain;chain != NULL;chain=chain->NEXT)
   {
      for (connect=fig->LOCON;connect!=NULL;connect=connect->NEXT)
      {
         if(connect->NAME==(char*)chain->DATA)
         {
         connect->USER=addptype(connect->USER,DSB_CONTRAINT,(void*)0);
         nb_user++;
         break ;
         }
      }

      if(connect==NULL) conxNotFind=addchain(conxNotFind,(void*)chain->DATA);
   }

   for (chain=ptchain;chain != NULL; chain=chain->NEXT) nb_berin++;

   if (nb_berin != nb_user)
   {
   chain_list * chain ;

      if(FCF_LANG=='E')
      fprintf(stderr,"[FATAL ERR] executing 'InitUserConect' :%d connector(s) do not exist\n",(nb_berin-nb_user));
      else if (FCF_LANG=='F')
      fprintf(stderr,"[FATAL ERR] Fonction 'InitUserConect' :%d connecteurs n'exist pas\n",(nb_berin-nb_user));
      
      for(chain=conxNotFind;chain!=NULL;chain=chain->NEXT)
      {
      printf("connector : %s\n",(char*)chain->DATA);
      }
   fflush(stdout);
   exit(-1);
   }
}

/****************************************************************************
 *                         fonction affichlist();                           *
 ****************************************************************************/
void affichlist(plist)
list_list *plist ;
{
list_list * list;

   for(list=plist; list;list=list->NEXT)
   {
   printf("var: %s Tag=%d\n",(char*)(((locon_list*)list->DATA)->NAME),list->TYPE );
   }
}
/****************************************************************************
 *                         fonction affichvar();                            *
 ****************************************************************************/
void affichvar(pchain)
chain_list * pchain ;
{
chain_list * chain = NULL;
int cmpt = 1;

   for(chain=pchain;chain;chain=chain->NEXT)
   {
   printf("Liste %d \n",cmpt++);
   affichlist((list_list*)chain->DATA);
   }
}
     
/****************************************************************************
 *                         fonction GetLocon();                             *
 ****************************************************************************/
   /*-------------------------------------------------------------*
    | Retourne le pointeur de connecteur externe a partir de son  |
    | nom.                                                        |
    | Entree : un char * (le nom du connecteur)                   |
    | Sortie : Le pointeur de connecteur                          |
    *-------------------------------------------------------------*/
locon_list * GetLocon(fig,name)
desafig_list * fig;
char * name;
{
locon_list * connect = NULL ;

   for(connect=fig->LOCON  ; connect != NULL ; connect=connect->NEXT)
   {
      if (strcmp(connect->NAME,name)==0)  return (connect) ;
   }

   if (connect == NULL)
   {
   fcfFatalError(2,"GetLocon",name,NULL,0);
   }
}

