
#undef PHCON
#undef PHSEG
#undef PHVIA
#undef PHREF
#undef HEIGHT
#undef WIDTH
#undef LOINS
#undef LOTRS
#undef LOCON
#undef BUS
#undef NAME


static NET_ins();
static NET_via();
static NET_seg();
static NET_conn();
static NET_ref();

/*
 *     NETLIST()
 *
 *     This function extract logical netlist from actual WORK_PHFIG. We define a logical figure with the same physical name.
 *   The extraction is composed of 5 functions. Each one visit one list of the figure structure. Instance list, via list,
 *   segment list, father connectors list and the reference list to treat the virtual connectors. The algorithm is based on
 *   the instance connectors connection.
 */


#define  NETPHINS  1111                 /* Definitions for ptype structure */
#define  NETPHCON  2222
#define  NETLOSIG  3333
#define  NETPHSEG  4444
#define  NETPHVIA  5555
#define  NETPHREF  6666


#define  SameLayer(PhConLayer,ViaType)                                                               \
     (                                                                                               \
         (  ViaType == CONT_POLY  &&  ( PhConLayer == POLY   ||  PhConLayer == ALU1  )  )            \
      ||                                                                                             \
         (  ViaType == CONT_VIA   &&  ( PhConLayer == ALU1  ||  PhConLayer == ALU2 )  )              \
     )


 int  autosig = 0 ;                  /*  Signal counter  */
 int  autocon = 0 ;                  /*  Connector counter */


/*******************************************************************************
* rsa_checkname : check for busses                                                 *
*******************************************************************************/
static char *rsa_checkname(name)
char *name;
{
char *t, *s;

   s = t = name;
   while (*t) {
      if (*t == '[')
         *t = ' ';
      else if (*t == ']')
         if (*(++t) == '\0') /* ok, it's finished */
            break ;
         else if (*t == '[') /* multiple array */
            continue;
      *s++ = *t++;
   }

   *s = '\0';
   return name;
}


static int  concmp( locon1, locon2 )                        /*  Thanks to Fred Petrot  */
locon_list **locon1, **locon2 ;
{
char *s, *t;
char *spt, sp[200], *tpt ,tp[200], *st, *tt ;
int u, ls, lt;


   st = s = (*locon1)->NAME ;
   tt = t = (*locon2)->NAME ;

   spt = sp, tpt = tp;
   
   while ((!isdigit(*st)) && *st)
      *spt++ = *st++;
   *spt = '\0';
 
   while ((!isdigit(*tt)) && *tt)
      *tpt++ = *tt++;
   *tpt = '\0';
 
   if ((u = strcmp(sp, tp)) != 0)
      return u;
 
   if ((ls = strlen(s)) == (lt = strlen(t)))
      return strcmp(s,t);
 
   return ls - lt;
}

static char *layers[] = {
            "NWELL",
            "PWELL",
            "NTIE",
            "PTIE",
            "NDIF",
            "PDIF",
            "NTRANS",
            "PTRANS",
            "POLY",
            "ALU1",
            "ALU2",
            "ALU3",
            "TPOLY",
            "TALU1",
            "TALU2",
            "TALU3",
            "LAST_LAYER"
           };

extern phfig_list *WORK_PHFIG ;
extern lofig_list *WORK_LOFIG ;

static void  NETLIST()
{
 locon_list **tabcon ;
 locon_list  *locon ;

 int i ;


   DEF_LOFIG( WORK_PHFIG->NAME ) ;

   NET_ins()  ;
   NET_via()  ;
   NET_seg()  ;
   NET_conn() ;
   NET_ref()  ;

   tabcon = (locon_list **)mbkalloc( sizeof( struct locon ) * autocon ) ;

   locon = WORK_LOFIG->LOCON ;
   for( i = 0 ; i < autocon ; i++ )   {

      tabcon[ i ] = locon ;
      locon = locon->NEXT ;
     }

   qsort( tabcon, autocon, sizeof( locon_list * ), concmp ) ;

   locon = WORK_LOFIG->LOCON = tabcon[ 0 ] ;

   for( i = 1 ; i < autocon ; i++ )   locon = locon->NEXT = tabcon[ i ] ;

   locon->NEXT = NULL ;

   WORK_LOFIG->LOCON = (locon_list *)reverse( (chain_list *)WORK_LOFIG->LOCON ) ;

   SAVE_LOFIG() ;
}


/*
 *     NET_ins()
 *                                                            2
 *   We have a list, we have to do an extraction, so it's an n /2 algorithm.
 *      It will be possible to do not check ALLOW connectors.
 */

static NET_ins()
{
 phins_list  *headphins    ;         /*  Physical instances list head                      */

 phins_list  *newphins     ;         /*  Used to visit physical instances                  */
 phfig_list  *newphfig     ;         /*  Physical figure model of new instance             */
 chain_list  *newphlo      ;         /*  Indicate the newphins  phfig and locon            */
 num_list    *newphinsxy   ;         /*  Indicate the newphins coordinates                 */

 phcon_list  *headphcon    ;         /*  Physical new instance connectors list head        */
 phcon_list  *newphcon     ;         /*  Used to visit the newphins physical connectors    */

 long  x1, y1, x2, y2      ;         /*  New instance coordinates                          */

 phins_list  *oldphins     ;         /*  Used to visit the list of yet seen instance       */

 lofig_list  *newlofig     ;         /*  We need the newphins logical model figure         */
 locon_list  *newloconfig  ;         /*  Used to visit the logical list connectors figure  */
 locon_list  *newlocon     ;         /*  Visit new instance logical connectors             */

 chain_list  *sigchain     ;         /*  New instance logical signal list                  */


   headphins = WORK_PHFIG->PHINS ;

   for( newphins = headphins ; newphins != NULL ; newphins = newphins->NEXT )   {

      newphfig  = getphfig( newphins->FIGNAME ) ;

      newphlo = addchain( NULL, (char  *)newphfig ) ;                      /*  We do only one getphfig()  */

      newphins->USER = addptype( newphins->USER, NETPHINS, newphlo ) ;    /*  We put in memory the phfig, and later lofig  */

      newphinsxy = (num_list  *)( getptype( newphins->USER, PLACEABOX )->DATA ) ;           /*  Initialized by PLACE*  */

      headphcon = newphfig->PHCON ;

      for( newphcon = headphcon ; newphcon != NULL ; newphcon = newphcon->NEXT )   {   /*  One signal per connector  */

         ptype_list  *ptype ;

         if( (ptype = getptype( newphcon->USER, NETPHCON ))  == NULL )          /*  First step, ptype structure not yet  */
                                                                                 /*  in memory  */
            newphcon->USER = addptype( newphcon->USER, NETPHCON, NULL ) ;       /*  No signal to start  */

         else   ptype->DATA = NULL ;                                             /*  No signal to start  */
        }

      x1 = newphins->XINS ;                   /*  New instance coordinates  */
      x2 = newphinsxy->DATA ;
      y1 = newphins->YINS ;
      y2 = newphinsxy->NEXT->DATA  ;


      for( oldphins = headphins ; oldphins != newphins ; oldphins = oldphins->NEXT )   {

         num_list    *oldphinsxy ;   /*  Indicates the old instance coordinates  */
         chain_list  *oldphlo  ;     /*  Chain which contain phfig  and  locon   */
         phfig_list  *oldphfig ;     /*  Physical old instance figure model      */


         oldphinsxy = (num_list  *)( getptype( oldphins->USER, PLACEABOX )->DATA ) ;

         if(                                                                    /*  Test if matching possible  */
              ( x1  >  oldphinsxy->DATA  )
            ||
              ( x2  <  oldphins->XINS )
            ||
              ( y2  <  oldphins->YINS )
            ||
              ( y1  >  oldphinsxy->NEXT->DATA  )
           )

              continue ;              /*  No matching connectors possible  */


         oldphlo = (chain_list  *)( getptype( oldphins->USER, NETPHINS )->DATA ) ;

         oldphfig = (phfig_list  *)( oldphlo->DATA ) ;                               /*  pointer figure recuperation  */

         for( newphcon = headphcon ; newphcon != NULL ; newphcon = newphcon->NEXT )   {

            long  newxphcon ;             /*  New instance connectors coordinates  */
            long  newyphcon ;

            phcon_list  *oldphcon ;


            xyflat( &newxphcon, &newyphcon, newphcon->XCON, newphcon->YCON, x1, y1,
                    newphfig->XAB1, newphfig->YAB1, newphfig->XAB2, newphfig->YAB2, newphins->TRANSF ) ;

            for( oldphcon = oldphfig->PHCON ; oldphcon != NULL ; oldphcon = oldphcon->NEXT )   {

               char        *oldphconname  ;         /*  Old instance physical connector name  */
               locon_list  *oldlocon      ;         /*  Use to visit the old logical connectors list  */
               losig_list  *oldlosig      ;         /*  Old logical signal of the matching connector  */
               losig_list  *newphconlosig ;         /*  Actual logical signal  */

               long  oldxphcon ;                    /*  Old instance coordinates  */
               long  oldyphcon ;

               xyflat( &oldxphcon, &oldyphcon, oldphcon->XCON, oldphcon->YCON, oldphins->XINS, oldphins->YINS,
                      oldphfig->XAB1, oldphfig->YAB1, oldphfig->XAB2, oldphfig->YAB2, oldphins->TRANSF ) ;

               if(
                    ( oldphcon->LAYER  !=  newphcon->LAYER )        /*  Matching connectors  */
                 ||
                    ( oldxphcon  !=  newxphcon )
                 ||
                    ( oldyphcon  !=  newyphcon )
                )

                  continue ;      /*  NO match connectors */

/*  We have to know now the oldloconsig, to find it, we use the name of oldphcon : oldphconname */


               oldphconname = oldphcon->NAME ;            /*  With the name we found the equivalent logical connector*/

               for( oldlocon = (locon_list  *)( oldphlo->NEXT ) ; oldlocon != NULL ; oldlocon = oldlocon->NEXT )

                  if( oldlocon->NAME == oldphconname )   break ;

               if( oldlocon == NULL )   {

                  fprintf( stderr, "\nFigure %s doesn't have the same logical & physical view\n", oldphfig->NAME ) ;
                  fprintf( stderr, "Physical connector %s doesn't have a logical connector\n", oldphconname ) ;
                  exit( 11 ) ;
                 }


               oldlosig = oldlocon->SIG ;                          /*  Now we have the logical signal of the oldlocon  */

               newphconlosig = (losig_list  *)( getptype( newphcon->USER, NETPHCON )->DATA ) ;

               if( newphconlosig  ==  NULL )   {                   /*  Physical connector do not already have a signal  */

                  phcon_list  *con ;                            /*  All the physical connectors with the same name, have to */
                  char        *name = newphcon->NAME ;          /*  be connected to the samr signal  */

                  for( con = headphcon ; con != NULL ; con = con->NEXT )

                     if( con->NAME == name )

                        getptype( con->USER, NETPHCON )->DATA = (void  *)oldlosig ;
                 }

               else

               if( newphconlosig != oldlosig )   {           /*  Conflict : same net at different signal  */
                                                             /*  The oldlosig dual list become the newphconlosig dual list  */
                  chain_list  *oldchain ;
                  chain_list  *tmpchain ;

                  ptype_list  *newlosigptype = getptype( newphconlosig->USER, NETLOSIG ) ;

                  oldchain = (chain_list  *)( getptype( oldlosig->USER, NETLOSIG )->DATA ) ;

                  for( ; oldchain != NULL ; oldchain = tmpchain )   {                  /*  dual list transfer  */

                     tmpchain = oldchain->NEXT ;

                     oldchain->NEXT = (chain_list  *)( newlosigptype->DATA ) ;
                     newlosigptype->DATA = (void  *)oldchain ;

                     ((locon_list *)(oldchain->DATA))->SIG = newphconlosig ;
                    }

                  delptype( oldlosig->USER, NETLOSIG ) ;
                  dellosig( WORK_LOFIG, oldlosig->INDEX ) ;  /*  Not very performante because we yet know the signal address*/
                 }
              }
           }
        }


      for( newphcon = headphcon ; newphcon != NULL ; newphcon = newphcon->NEXT )   {   /*  Add a new losig for not yet  */
                                                                                       /*  connected connectors  */
         ptype_list  *ptype ;

         if( (ptype = getptype( newphcon->USER, NETPHCON ))->DATA == NULL )   {

            phcon_list  *con ;
            char  *name = newphcon->NAME ;

            ptype->DATA = (void  *)addlosig( WORK_LOFIG, autosig++, NULL, 'I', NULL ) ;

            for( con = newphcon->NEXT ; con != NULL ; con = con->NEXT )

               if( con->NAME == name )   getptype( con->USER, NETPHCON )->DATA = ptype->DATA ;
           }
        }

      newlofig = getlofig( newphfig->NAME, 'P' ) ;

      sigchain = NULL ;          /*  We have to make the connectors signal list for addloins()  */

      for( newloconfig = newlofig->LOCON ; newloconfig != NULL ; newloconfig = newloconfig->NEXT )   {

         char  *name = newloconfig->NAME ;

         for( newphcon = headphcon ; newphcon != NULL ; newphcon = newphcon->NEXT )

            if( newphcon->NAME == name )   {

               sigchain = addchain( sigchain, (char  *)( getptype( newphcon->USER, NETPHCON )->DATA ) ) ;
               break ;
              }


         if( newphcon == NULL )   {         /*  May be a virtual connector  */
                                            /*  Getphref( 'P' )   gives the reference list  */
            phref_list  *newphref ;

            for( newphref = newphfig->PHREF ; newphref != NULL ; newphref = newphref->NEXT )   {

               if( VirtualConnector( newphref->FIGNAME ) )   {

                  char  tmpname[ 100 ], *c1 ;

                  if( (c1 = strchr( strcpy( tmpname, newphref->NAME), '[' ))  ==  NULL  )

                     if( (c1 = strrchr( tmpname, '_' ))  ==  NULL  )

                      {
                        printf( "Figure %s contains a bad name virtual connector : %s\n", newphfig->NAME, newphref->NAME ) ;
                        continue ;
                      }

                  *c1 = '\0' ;

                  if( strcmp( name, tmpname )  ==  0 )   {

                     sigchain = addchain( sigchain, (char  *)addlosig( WORK_LOFIG, autosig++, NULL, 'I', NULL ) ) ;
                     break ;
                    }
                 }         /*  if( newphcon == NULL  */
              }            /*  for( newphref ... )   */

            if( newphref == NULL )   {

               fprintf( stderr, "\nFigure %s doesn't have the same logical & physical view\n", newphfig->NAME ) ;
               fprintf( stderr, "No physical or virtual connector for logical connector %s\n", name ) ;
               exit(12) ;
              }

           }        /*  if( newphcon == NULL    */

        }           /*  for( newloconfig ... )  */


      sigchain = reverse( sigchain ) ;        /*  Good order for addloins()  */

      newlocon = (locon_list  *)(newphlo->NEXT =
                 ((chain_list  *)( addloins( WORK_LOFIG, newphins->INSNAME, getlofig( newphins->FIGNAME, 'P' ), sigchain, NULL )->LOCON ) ) ) ;


      for( ; newlocon != NULL ; newlocon = newlocon->NEXT )   {          /*  Append DUAL netlist  */

         ptype_list  *ptype ;

         if( (ptype = getptype( newlocon->SIG->USER, NETLOSIG )) == NULL )

            ptype = newlocon->SIG->USER = addptype( newlocon->SIG->USER, NETLOSIG, NULL ) ;

         ptype->DATA = (void  *)addchain( (chain_list  *)(ptype->DATA), (char  *)newlocon ) ;
        }

     }

}



static NET_via()
{

 phvia_list  *figphvia  ;


   for( figphvia = WORK_PHFIG->PHVIA ; figphvia != NULL ; figphvia = figphvia->NEXT )   {

      phins_list  *ins ;
      ptype_list  *viaptype     ;


      viaptype = figphvia->USER = addptype( figphvia->USER, NETPHVIA, NULL ) ;   /*  No signal on via, first  */

      for( ins = WORK_PHFIG->PHINS ; ins != NULL ; ins = ins->NEXT )   {

         phfig_list  *insphfig ;
         phcon_list  *insphcon ;
         num_list    *insphxy  ;
         chain_list  *insphlo  ;


         if(                                            /*  Matching via and instance  */
              (  figphvia->XVIA  <  ins->XINS  )
            ||
              (  figphvia->YVIA  <  ins->YINS )
            ||
              (  figphvia->XVIA  >  (insphxy = ((num_list  *)( getptype( ins->USER, PLACEABOX )->DATA )))->DATA  )
            ||
              (  figphvia->YVIA  >  insphxy->NEXT->DATA )
           )

             continue ;           /*  Next  instance  */


         insphlo = ((chain_list  *)( getptype( ins->USER, NETPHINS )->DATA )) ;

         insphfig = (phfig_list  *)( insphlo->DATA ) ;

         for( insphcon = insphfig->PHCON ; insphcon != NULL ; insphcon = insphcon->NEXT )   {

            long  insphconx, insphcony ;

            char        *insphconname   ;
            locon_list  *inslocon       ;
            losig_list  *phviasig       ;
            losig_list  *oldlosig       ;
             char       lay             ;
             int        typ             ;


            xyflat( &insphconx, &insphcony, insphcon->XCON, insphcon->YCON, ins->XINS, ins->YINS,
                    insphfig->XAB1, insphfig->YAB1, insphfig->XAB2, insphfig->YAB2, ins->TRANSF ) ;

            if(
                 (  insphconx  !=  figphvia->XVIA  )                /*  Matching via and instance connectors  */
               ||
                 (  insphcony  !=  figphvia->YVIA  )
               ||
                 (  ! ( lay = insphcon->LAYER, typ = figphvia->TYPE, SameLayer( lay , typ ) )  )
              )

                continue ;


            insphconname = insphcon->NAME ;

            for( inslocon = (locon_list  *)( insphlo->NEXT ) ; inslocon != NULL ; inslocon = inslocon->NEXT )

               if( inslocon->NAME == insphconname )   break ;

            if( inslocon == NULL )   {

               fprintf( stderr, "\nFigure %s doesn't have the same logical and physical view\n", insphfig->NAME ) ;
               fprintf( stderr, "Physical connector %s doesn't have a logical connector\n", insphconname ) ;
               exit( 13 ) ;
              }


            phviasig = (losig_list  *)( viaptype->DATA ) ;

            if( phviasig  ==  NULL )   {

               viaptype->DATA = (void  *)inslocon->SIG ;
               break ;
              }

            else

            if( phviasig  !=  (oldlosig = inslocon->SIG) )   {       /*  Same algorithme than NET_ins()  */

               chain_list  *oldchain ;
               chain_list  *tmpchain ;

               ptype_list  *newlosigptype = getptype( phviasig->USER, NETLOSIG ) ;

               oldchain = (chain_list  *)( getptype( oldlosig->USER, NETLOSIG )->DATA ) ;

               for( ; oldchain != NULL ; oldchain = tmpchain )   {

                  tmpchain = oldchain->NEXT ;

                  oldchain->NEXT = (chain_list  *)( newlosigptype->DATA ) ;
                  newlosigptype->DATA = (void  *)oldchain ;

                  ((locon_list *)(oldchain->DATA))->SIG = phviasig ;
                 }

               delptype( oldlosig->USER, NETLOSIG ) ;
               dellosig( WORK_LOFIG, oldlosig->INDEX ) ;
              }
           }
        }

      if( getptype( figphvia->USER, NETPHVIA )->DATA  ==  NULL  )

         printf( "Physical via have no logical signal\n xvia : %ld, yvia : %ld\n", figphvia->XVIA, figphvia->YVIA ) ;

     }
}



static NET_seg()
{

 phseg_list  *figphseg  ;


   for( figphseg = WORK_PHFIG->PHSEG ; figphseg != NULL ; figphseg = figphseg->NEXT )   {

      phins_list  *ins ;


      if( figphseg->LAYER == TALU2  ||  figphseg->LAYER == TALU1 )   continue ;


      figphseg->USER = addptype( figphseg->USER, NETPHSEG, NULL ) ;

      for( ins = WORK_PHFIG->PHINS ; ins != NULL ; ins = ins->NEXT )   {

         phfig_list  *insphfig ;
         phcon_list  *insphcon ;
         num_list    *insphxy  ;
         chain_list  *insphlo  ;


         if(                                           /*  Segment is like and instance  see  NET_ins()  */
              (  figphseg->X2  <  ins->XINS  )
            ||
              (  figphseg->Y2  <  ins->YINS )
            ||
              (  figphseg->X1  >  (insphxy = ((num_list  *)( getptype( ins->USER, PLACEABOX )->DATA )))->DATA  )
            ||
              (  figphseg->Y1  >  insphxy->NEXT->DATA )
           )

             continue ;           /*  Next  instance  */


         insphlo = ((chain_list  *)( getptype( ins->USER, NETPHINS )->DATA )) ;

         insphfig = (phfig_list  *)( insphlo->DATA ) ;

         for( insphcon = insphfig->PHCON ; insphcon != NULL ; insphcon = insphcon->NEXT )   {

            long  insphconx, insphcony ;

            char        *insphconname   ;
            locon_list  *inslocon       ;
            ptype_list  *phsegptype     ;
            losig_list  *phsegsig       ;
            losig_list  *oldlosig       ;


            xyflat( &insphconx, &insphcony, insphcon->XCON, insphcon->YCON, ins->XINS, ins->YINS,
                    insphfig->XAB1, insphfig->YAB1, insphfig->XAB2, insphfig->YAB2, ins->TRANSF ) ;

            if(
                  (  figphseg->LAYER  !=  insphcon->LAYER  )
               ||
                  (
                      ! (
                             (figphseg->TYPE==LEFT||figphseg->TYPE==RIGHT)  &&  figphseg->Y1  ==  insphcony
                          &&
                             insphconx >= figphseg->X1  &&  insphconx <= figphseg->X2
                        )
                    &&
                      ! (
                             (figphseg->TYPE==UP||figphseg->TYPE==DOWN) &&  figphseg->X1  ==  insphconx
                          &&
                             insphcony >= figphseg->Y1  &&  insphcony <= figphseg->Y2
                        )
                  )
              )
                continue ;           /*  Next connector  */


            insphconname = insphcon->NAME ;

            for( inslocon = (locon_list  *)( insphlo->NEXT ) ; inslocon != NULL ; inslocon = inslocon->NEXT )

               if( inslocon->NAME == insphconname )   break ;

            if( inslocon == NULL )   {

               fprintf( stderr, "\nFigure %s doesn't have the same logical and physical view\n", insphfig->NAME ) ;
               fprintf( stderr, "Physical connector %s doesn't have a logical connector\n", insphconname ) ;
               exit( 14 ) ;
              }

            phsegptype = getptype( figphseg->USER, NETPHSEG ) ;

            phsegsig = (losig_list  *)( phsegptype->DATA ) ;

            if( phsegsig  ==  NULL )

               phsegptype->DATA = (void  *)inslocon->SIG ;

            else

            if( phsegsig  !=  (oldlosig = inslocon->SIG) )   {

               chain_list  *oldchain ;
               chain_list  *tmpchain ;

               phseg_list  *seg ;
               ptype_list  *segptype ;

               ptype_list  *newlosigptype = getptype( phsegsig->USER, NETLOSIG ) ;


               oldchain = (chain_list  *)( getptype( oldlosig->USER, NETLOSIG )->DATA ) ;

               for( ; oldchain != NULL ; oldchain = tmpchain )   {

                  tmpchain = oldchain->NEXT ;

                  oldchain->NEXT = (chain_list  *)( newlosigptype->DATA ) ;
                  newlosigptype->DATA = (void  *)oldchain ;

                  ((locon_list *)(oldchain->DATA))->SIG = phsegsig ;
                 }

               for( seg = WORK_PHFIG->PHSEG ; seg != figphseg ; seg = seg->NEXT )

                  if(  (segptype = getptype( seg->USER, NETPHSEG ))->DATA  ==  (void *)oldlosig  )

                       segptype->DATA = (void  *)phsegsig ;


               delptype( oldlosig->USER, NETLOSIG ) ;
               dellosig( WORK_LOFIG, oldlosig->INDEX ) ;
              }
           }
        }

      if( getptype( figphseg->USER, NETPHSEG )->DATA  ==  NULL  )   {

         printf( "Physical seg have no logical signal\n x1 : %ld, y1 : %ld\n", figphseg->X1, figphseg->Y1 ) ;
         printf( "X2 : %ld, Y2 : %ld, LAYER : %s\n", figphseg->X2, figphseg->Y2, layers[figphseg->LAYER] ) ;
        }

     }
}



static NET_conn()
{

 phcon_list  *figphcon  ;
 phseg_list  *figphseg  ;

 int  FOUND ;


   for( figphcon = WORK_PHFIG->PHCON ; figphcon != NULL ; figphcon = figphcon->NEXT )   {

      phins_list  *ins ;
      ptype_list  *ptype ;


      if( figphcon->LAYER == TALU2  ||  figphcon->LAYER == TALU1 || figphcon->LAYER == NWELL )   continue ;


      if( (ptype = getptype( figphcon->USER, NETPHCON )) != NULL  )   {
         if( FAST_MODE == 'Y' )   continue ;                              /*  Yet connected  */
        }
      else
         ptype = figphcon->USER = addptype( figphcon->USER, NETPHCON, NULL ) ;

      FOUND = FALSE ;

      for( ins = WORK_PHFIG->PHINS ; ins != NULL ; ins = ins->NEXT )   {

         phfig_list  *insphfig ;
         phcon_list  *insphcon ;

         chain_list  *insphlo  ;

         num_list    *insphxy  ;


         if(                                         /*  Matching connectors and father connectors  */
              (  figphcon->XCON  <  ins->XINS  )
            ||
              (  figphcon->YCON  <  ins->YINS )
            ||
              (  figphcon->XCON  >  (insphxy = ((num_list  *)( getptype( ins->USER, PLACEABOX )->DATA )))->DATA  )
            ||
              (  figphcon->YCON  >  insphxy->NEXT->DATA  )
           )

             continue ;         /*  Next instance  */


         insphlo = (chain_list  *)( getptype( ins->USER, NETPHINS )->DATA ) ;

         insphfig = (phfig_list  *)( insphlo->DATA ) ;

         for( insphcon = insphfig->PHCON ; insphcon != NULL ; insphcon = insphcon->NEXT )   {

            long  insphconx, insphcony ;
            char  *insphconname ;

            locon_list  *inslocon ;


            xyflat( &insphconx, &insphcony, insphcon->XCON, insphcon->YCON, ins->XINS, ins->YINS,
                    insphfig->XAB1, insphfig->YAB1, insphfig->XAB2, insphfig->YAB2, ins->TRANSF ) ;

            if(                                         /*  Matching instance connectors and father connectors  */
                 (  insphcon->LAYER  !=  figphcon->LAYER  )
               ||
                 (  insphconx  !=  figphcon->XCON  )
               ||
                 (  insphcony  !=  figphcon->YCON  )
              )

                continue ;      /*  Next  connector  */


            insphconname = insphcon->NAME ;

            for( inslocon = (locon_list  *)( insphlo->NEXT ) ; inslocon != NULL ; inslocon = inslocon->NEXT )

               if( inslocon->NAME == insphconname )   break ;

            if( inslocon == NULL )   {

               fprintf( stderr, "\nFigure %s doesn't have the same logical and physical view\n", insphfig->NAME ) ;
               fprintf( stderr, "Physical connector %s doesn't have is logical equivalent\n", insphconname ) ;
               exit( 15 ) ;
              }

 
            if( ptype->DATA  !=  NULL )   {

               if( inslocon->SIG  !=  ((losig_list  *)(ptype->DATA)) )   {

                  fprintf( stderr, "\nThe connector %s is connected to different logical signal\n", figphcon->NAME ) ;
                  exit( 16 ) ;
                 }
              }

            else   {

               char        *name = figphcon->NAME ;
               phcon_list  *con ;

               autocon++ ;
               addlocon( WORK_LOFIG, name, inslocon->SIG, 'X' ) ;
               inslocon->SIG->TYPE = 'E' ;
               ptype->DATA = ((void *)( inslocon->SIG )) ;

               for( con = figphcon->NEXT ; con != NULL ; con = con->NEXT )

                   if( con->NAME == name )   con->USER = addptype( con->USER, NETPHCON, inslocon->SIG ) ;

              }


            FOUND = TRUE ;
            break ;
           }

         if( FOUND )   break ;
        }


      if( FOUND )   continue ;           /*  if ! FOUND we must check the segment list  */


      for( figphseg = WORK_PHFIG->PHSEG ; figphseg != NULL ; figphseg = figphseg->NEXT )   {

         losig_list  *phseglosig ;

         if(                                                   /*  Matching between father connector and segment  */
                (  figphseg->LAYER  !=  figphcon->LAYER  )
            ||
                (
                   ! (
                          (figphseg->TYPE==LEFT||figphseg->TYPE==RIGHT) &&  figphseg->Y1  ==  figphcon->YCON
                      &&
                          figphcon->XCON >= figphseg->X1  &&  figphcon->XCON <= figphseg->X2
                     )
                 &&
                   ! (
                          (figphseg->TYPE==UP||figphseg->TYPE==DOWN) &&  figphseg->X1  ==  figphcon->XCON
                      &&
                          figphcon->YCON >= figphseg->Y1  &&  figphcon->YCON <= figphseg->Y2
                     )
                )
           )
             continue ;           /*  Next segment  */



         if( (phseglosig = (losig_list  *)( getptype( figphseg->USER, NETPHSEG )->DATA ))  ==  NULL )

            printf( "Father connector %s on physical segment %s with no logical signal\n", figphcon->NAME, figphseg->NAME ) ;

         else

            if( ptype->DATA  !=  NULL )   {

               if( phseglosig  !=  ((losig_list  *)(ptype->DATA)) )   {

                  fprintf( stderr, "\nThe connector %s is connected to different logical signal\n", figphcon->NAME ) ;
                  exit( 17 ) ;
                 }

               break ;

              }

            else   {

               char        *name = figphcon->NAME ;
               phcon_list  *con ;

               autocon++ ;
               addlocon( WORK_LOFIG, name, phseglosig, 'X' ) ;
               phseglosig->TYPE = 'E' ;
               ptype->DATA = ((void *)( phseglosig )) ;

               for( con = figphcon->NEXT ; con != NULL ; con = con->NEXT )

                   if( con->NAME == name )   con->USER = addptype( con->USER, NETPHCON, phseglosig ) ;

               break ;
              }
        }

      if( figphseg  ==  NULL )   {

         printf( "Father connector %s cannot be connected to a logical signal\n", figphcon->NAME ) ;
         printf( "XCON : %ld, YCON : %ld\n", figphcon->XCON, figphcon->YCON ) ;
        }
     }
}



static NET_ref()                         /*  Virtual connectors  */
{

 phref_list  *figphref  ;

 int  FOUND ;


   for( figphref = WORK_PHFIG->PHREF ; figphref != NULL ; figphref = figphref->NEXT )   {

      phins_list  *ins ;


      if( getptype( figphref->USER, NETPHREF ) != NULL  )   continue ;        /* yet connected  */ 

      if( ! VirtualConnector( figphref->FIGNAME ) )          continue ;

      figphref->USER = addptype( figphref->USER, NETPHREF, NULL ) ;

      FOUND = FALSE ;

      for( ins = WORK_PHFIG->PHINS ; ins != NULL ; ins = ins->NEXT )   {

         phfig_list  *insphfig ;
         phref_list  *insphref ;

         chain_list  *insphlo  ;

         num_list    *insphxy  ;


         if(
              (  figphref->XREF  <  ins->XINS  )
            ||
              (  figphref->YREF  <  ins->YINS )
            ||
              (  figphref->XREF  >  (insphxy = ((num_list  *)( getptype( ins->USER, PLACEABOX )->DATA )))->DATA  )
            ||
              (  figphref->YREF  >  insphxy->NEXT->DATA  )
           )

             continue ;         /*  Next instance  */

         insphlo = (chain_list  *)( getptype( ins->USER, NETPHINS )->DATA ) ;

         insphfig = (phfig_list  *)( insphlo->DATA ) ;

         for( insphref = insphfig->PHREF ; insphref != NULL ; insphref = insphref->NEXT )   {

            long  insphrefx, insphrefy ;
            char  insphrefname[ 100 ], *c1 ;
            char  conname[ 100 ] ;
            char  prout[ 100 ] ;
            int   length ;

            phref_list  *ref ;
            locon_list  *inslocon ;


            xyflat( &insphrefx, &insphrefy, insphref->XREF, insphref->YREF, ins->XINS, ins->YINS,
                    insphfig->XAB1, insphfig->YAB1, insphfig->XAB2, insphfig->YAB2, ins->TRANSF ) ;

            if(
                 (  insphrefx  !=  figphref->XREF  )
               ||
                 (  insphrefy  !=  figphref->YREF  )
              )

                continue ;      /*  Next  virtual connector  */


            if(  (c1 = strchr( strcpy( insphrefname, figphref->NAME ), ' ' ))  ==  NULL  ) /* '[' -> ' ' 06/03/92 */

               if(  (c1 = strrchr( insphrefname, '_' ))  ==  NULL  )

                {
                  printf( "Figure %s contains a bad name virtual connector : %s\n", WORK_PHFIG->NAME, figphref->NAME ) ;
                  continue ;
                }


            *c1 = '\0' ;

            for( inslocon = (locon_list  *)( insphlo->NEXT ) ; inslocon != NULL ; inslocon = inslocon->NEXT )

               if( strcmp( inslocon->NAME, insphrefname )  ==  0 )   break ;


            if( inslocon == NULL )   {

               fprintf( stderr, "\nFigure %s doesn't have the same logical and physical view\n", insphfig->NAME ) ;
               fprintf( stderr, "Virtual connector %s doesn't have is logical equivalent\n", insphrefname ) ;
               exit( 18 ) ;
              }


            *strrchr( strcpy( conname, figphref->NAME ), '_' ) = '\0' ;

            strcpy( prout, conname ) ;
            autocon++ ; 
            addlocon( WORK_LOFIG, rsa_checkname(prout), inslocon->SIG, 'X' ) ;
            inslocon->SIG->TYPE = 'E' ;


/*          ptype->DATA = ((char *)( inslocon->SIG )) ;                      Initialize do not used  */


            length = strlen( conname ) ;

            for( ref = figphref->NEXT ; ref != NULL ; ref = ref->NEXT )

                if(      VirtualConnector( ref->FIGNAME )
                   &&  ( strncmp( ref->NAME, conname, length )  == 0 )
                   &&  ( ref->NAME)[ length ] == '_'  )

                   ref->USER = addptype( ref->USER, NETPHREF, NULL  /*inslocon->SIG*/ ) ;


            FOUND = TRUE ;
            break ;
           }

         if( FOUND )   break ;
        }
     }
}



int  VirtualConnector( name )
char  *name ;
{
 static  info = 1 ;

 static  char  *refcon ;

   if( info )   {
      refcon  =  (char  *)namealloc( "ref_con" ) ;
      info = 0 ;
     }

   return name == refcon ;
}
