/*******************************************************************************
* mbk    : acces functions to logical structures                               *
*                                                                              *
* version : 3.03                                                               *
* date   : 30/04/91                                                            *
*******************************************************************************/

#include MUT_H
#include MLO_H
#include "mbk_lo.h"

/*******************************************************************************
* global variable for netlist view                                             *
*******************************************************************************/
lofig_list *HEAD_LOFIG;            /* physical figure list head   */

/*******************************************************************************
* function addlofig()                                                          *
*******************************************************************************/
lofig_list *addlofig(name)
char *name;
{
lofig_list *ptfig;

	name = namealloc(name);
	/* scan figure list */
	ptfig = HEAD_LOFIG;
	while (ptfig != NULL && ptfig->NAME != name)
	   ptfig = ptfig->NEXT;

	if (ptfig != NULL) {   /* figure exists */
	   (void)fflush(stdout);
	   (void)fprintf(stderr, "*** mbk error ***\n");
	   (void)fprintf(stderr, "addlofig impossible : ");
	   (void)fprintf(stderr, "figure %s already exists\n", name);
	   EXIT(1);
	}
	ptfig = (lofig_list *)mbkalloc(sizeof(lofig_list));
	ptfig->MODE   = 'A';
	ptfig->NAME   = name;
	ptfig->MODELCHAIN  = NULL;
	ptfig->LOINS  = NULL;
	ptfig->LOTRS  = NULL;
	ptfig->LOCON  = NULL;
	ptfig->LOSIG  = NULL;
	ptfig->BKSIG  = NULL;
	ptfig->USER   = NULL;
	ptfig->NEXT   = HEAD_LOFIG;
	HEAD_LOFIG = ptfig;

	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- addlofig  : %s\n", name);

	return ptfig;
}

/*******************************************************************************
* function addlomodel()                                                        *
* used by the parsers to construct a temporary model                           *
*******************************************************************************/
lofig_list *addlomodel(model, name)
lofig_list *model;
char *name;
{
lofig_list *fig;

	name = namealloc(name);
	/* check to see if the model has already been loaded */
	for (fig = model; fig && fig->NAME != name; fig = fig->NEXT);

	if (fig) { /* figure exists */
	   (void)fflush(stdout);
	     (void)fprintf(stderr, "*** mbk error ***\n");
	     (void)fprintf(stderr, "addlomodel impossible : ");
	     (void)fprintf(stderr, "model %s already exists \n", name);
	     EXIT(1);
	}
	  fig = (lofig_list *)mbkalloc(sizeof(lofig_list));
	  fig->MODE = 'A';
	  fig->NAME = name;
	  fig->MODELCHAIN = NULL;
	  fig->LOINS = NULL;
	  fig->LOTRS = NULL;
	  fig->LOCON = NULL;
	  fig->LOSIG = NULL;
	  fig->BKSIG = NULL;
	  fig->USER = NULL;
	  fig->NEXT = model;
	  model = fig;

	if (TRACE_MODE == 'Y')
	     (void)fprintf(stdout, "--- mbk --- addlomodel  : %s\n", name);

	return  model;
}
  
/*******************************************************************************
* function addlotrs()                                                          *
*******************************************************************************/
lotrs_list *addlotrs(ptfig, type, x, y, width, length, ps, pd, xs, xd, ptgrid,
	                  ptsource, ptdrain)
lofig_list *ptfig;
losig_list *ptgrid, *ptsource, *ptdrain;
long x, y;
unsigned short width, length, ps, pd, xs, xd;
char type;
{
lotrs_list  *pttrs;
locon_list  *ptcon;

	if (type != TRANSN && type != TRANSP) {
	   (void)fflush(stdout);
	   (void)fprintf(stderr, "*** mbk error ***\n");
	   (void)fprintf(stderr, "  illegal transistor type : %ld\n", (long)type);
	   EXIT(1);
	}
	pttrs = (lotrs_list *)mbkalloc(sizeof(lotrs_list));
	pttrs->X    = x;
	pttrs->Y    = y;
	pttrs->WIDTH   = width;
	pttrs->LENGTH  = length;
	pttrs->PS   = ps;
	pttrs->PD   = pd;
	pttrs->XS   = xs;
	pttrs->XD   = xd;
	pttrs->TYPE   = type;
	pttrs->NEXT   = ptfig->LOTRS;
	ptfig->LOTRS   = pttrs;
	pttrs->USER   = NULL;

	ptcon = (locon_list *)mbkalloc(sizeof(locon_list));
	ptcon->NAME   = namealloc("grid");
	ptcon->SIG    = ptgrid;
	ptcon->ROOT   = (void *)pttrs;
	ptcon->TYPE   = 'T';
	ptcon->DIRECTION = 'I';
	pttrs->GRID   = ptcon;
	
	ptcon = (locon_list *)mbkalloc(sizeof(locon_list));
	ptcon->NAME   = namealloc("drain");
	ptcon->SIG    = ptdrain;
	ptcon->ROOT   = (void *)pttrs;
	ptcon->TYPE   = 'T';
	ptcon->DIRECTION = 'I';
	pttrs->DRAIN    = ptcon;
	
	ptcon = (locon_list *)mbkalloc(sizeof(locon_list));
	ptcon->NAME   = namealloc("source");
	ptcon->SIG    = ptsource;
	ptcon->ROOT   = (void *)pttrs;
	ptcon->TYPE   = 'T';
	ptcon->DIRECTION = 'I';
	pttrs->SOURCE   = ptcon;
	
	if ((TRACE_MODE == 'Y'))
	   (void)fprintf(stdout,
	                  "--- mbk --- addlotrs  : %s  X=%ld, Y=%ld, W=%ld, L=%ld, PS = %ud, PD = %ud, XS = %ud, XD = %ud\n",
	                  type == TRANSN ? "TRANSN" : "TRANSP", x, y, width, length,
	                  ps, pd, xs, xd);

	return pttrs;
}

/*******************************************************************************
* function addloins()                                                          *
*******************************************************************************/
loins_list *addloins(ptfig, insname, ptnewfig, sigchain)
lofig_list *ptfig;
char *insname;
lofig_list *ptnewfig;
chain_list *sigchain;
{
locon_list *ptcon = NULL;
locon_list *ptnewcon = NULL;
loins_list *ptins = NULL;
char *figname;
chain_list *ptchain;

	insname = namealloc(insname);
	figname = ptnewfig->NAME;

	/* check insname  unicity */
	if (strcmp(insname, "*") && FAST_MODE != 'Y') {
	   for (ptins = ptfig->LOINS; ptins; ptins = ptins->NEXT) {
	      if (ptins->INSNAME == insname) {
	         (void)fflush(stdout);
	         (void)fprintf(stderr, "*** mbk error ***\n");
	         (void)fprintf(stderr, "addloins impossible : ");
	         (void)fprintf(stderr, "instance %s already exist in figure %s\n", 
	                        insname, ptfig->NAME);
	         EXIT(1);
	      }
	   }
	}

	if (ptfig->NAME == figname) {
	   (void)fflush(stdout);
	   (void)fprintf(stderr, "*** mbk error ***\n");
	   (void)fprintf(stderr, "addloins impossible :\n");
	   (void)fprintf(stderr, "instance model is the figure %s itself\n", 
	                  figname);
	   EXIT(1);
	}

	ptins = (loins_list *)mbkalloc(sizeof(loins_list));

	ptins->INSNAME  = insname;
	ptins->FIGNAME  = figname;
	ptins->LOCON   = NULL;
	ptins->USER    = NULL;
	ptins->NEXT    = ptfig->LOINS;
	ptfig->LOINS   = ptins;

	/* update model list   */
	for (ptchain = ptfig->MODELCHAIN; ptchain; ptchain = ptchain->NEXT)
	   if (ptchain->DATA == (void *)figname)
	      break;

	if (!ptchain)
	   ptfig->MODELCHAIN = addchain(ptfig->MODELCHAIN, (void *)figname);

	for (ptcon = ptnewfig->LOCON; ptcon; ptcon = ptcon->NEXT) {
	   if (sigchain == NULL) {
	      (void)fflush(stdout);
	      (void)fprintf(stderr, "*** mbk error ***\n");
	      (void)fprintf(stderr, "addloins impossible : connector number ");
	      (void)fprintf(stderr, "discrepancy between figure %s", 
	                     ptnewfig->NAME);
	      (void)fprintf(stderr, " and instance %s in figure %s\n",
	                     insname, ptfig->NAME);
	      EXIT(1);
	   }
	   ptnewcon = (locon_list *)mbkalloc(sizeof(locon_list));
	   ptnewcon->NAME = ptcon->NAME;
	   ptnewcon->DIRECTION = ptcon->DIRECTION;
	   ptnewcon->TYPE = 'I';
	   ptnewcon->SIG  = (losig_list *)sigchain->DATA;
	   ptnewcon->ROOT = (void *)ptins;
	   ptnewcon->USER = NULL;
	   ptnewcon->NEXT = ptins->LOCON;
	   ptins->LOCON  = ptnewcon;
	   sigchain = sigchain->NEXT;
	}
	if (sigchain != NULL) {
	   (void)fflush(stdout);
	   (void)fprintf(stderr, "*** mbk error ***\n");
	   (void)fprintf(stderr, "addloins impossible : ");
	   (void)fprintf(stderr, "connector number discrepancy between figure %s ", 
	                  ptnewfig->NAME);
	   (void)fprintf(stderr, "and instance %s in figure %s\n",
	                  insname, ptfig->NAME);
	   EXIT(1);
	}

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

	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- addloins  : %s of figure %s\n", 
	                  insname, figname);
	return ptins;
}

/*******************************************************************************
* function addlocon()                                                          *
*******************************************************************************/
locon_list *addlocon(ptfig, name, ptsig, dir)
lofig_list *ptfig;
char *name;
losig_list *ptsig;
char dir;
{
locon_list *ptcon;

name = namealloc(name);

	/* check name  unicity */
	if (FAST_MODE != 'Y') {
	   for (ptcon = ptfig->LOCON; ptcon; ptcon = ptcon->NEXT) {
	      if (ptcon->NAME == name) {
	         (void)fflush(stdout);
	         (void)fprintf(stderr, "*** mbk error ***\n");
	         (void)fprintf(stderr, "addlocon impossible :\n");
	         (void)fprintf(stderr, "connector %s already exists in figure %s\n", 
	                        name, ptfig->NAME);
	         EXIT(1);
	      }
	   }
	   if (dir != 'I' && dir != 'O' && dir != 'X' && dir != 'B' 
	         && dir != 'Z' && dir != 'T') {
	      (void)fflush(stdout);
	      (void)fprintf(stderr, "*** mbk error ***\n");
	      (void)fprintf(stderr, "addlocon impossible :\n");
	      (void)fprintf(stderr, "bad direction %c in figure %s\n",
	                     dir, ptfig->NAME);
	      EXIT(1);
	   }
	}

	ptcon = (locon_list *)mbkalloc(sizeof(locon_list));
	ptcon->NAME = name;
	ptcon->TYPE = 'E';
	ptcon->SIG  = ptsig;
	ptcon->ROOT = (void *)ptfig;
	ptcon->DIRECTION=dir;
	ptcon->USER  = NULL;
	ptcon->NEXT = ptfig->LOCON;
	ptfig->LOCON = ptcon;

	if (TRACE_MODE == 'Y')
	   if (ptsig!=NULL)
	      (void)fprintf(stdout, "--- mbk --- addlocon  : %s linked to %ld\n", 
	                     name, ptsig->INDEX);
	   else
	      (void)fprintf(stdout, "--- mbk --- addlocon  : %s  no signal\n", name);

	return ptcon;
}

/*******************************************************************************
* function addlosig()                                                          *
*******************************************************************************/
losig_list *addlosig(ptfig, index, namechain, type, capa)
lofig_list *ptfig;
long index;
chain_list *namechain;
char type;
float capa;
{
losig_list *ptsig = NULL;
losig_list *pthead = NULL;
ptype_list *pt = NULL;
chain_list *ptchain = NULL;
short high;
short low;
int i;

	low = (short)(index % SIGSIZE);
	high = (short)(index / SIGSIZE);
	for (pt = ptfig->BKSIG; pt; pt = pt->NEXT)
	   if (pt->TYPE == high)
	      break;
	if (pt == NULL) {
	   pthead = (losig_list *)mbkalloc(SIGSIZE * sizeof(losig_list));
	   ptsig = pthead;
	   for (i = 0; i < SIGSIZE; i++) {
	      ptsig->INDEX = 0;
	      ptsig++;
	   }
	   ptfig->BKSIG = (ptype_list *)addptype(ptfig->BKSIG,
	                                          (long)high, (void *)pthead);
	   pt = ptfig->BKSIG;
	}
	ptsig = (losig_list *)(pt->DATA) + low;

	/* check index  unicity */
	if (ptsig->INDEX != 0L) {
	   (void)fflush(stdout);
	   (void)fprintf(stderr, "*** mbk error ***\n");
	   (void)fprintf(stderr, "addlosig impossible :\n");
	   (void)fprintf(stderr, "signal %ld already exist in figure %s\n", 
	                  index, ptfig->NAME);
	   EXIT(1);
	}
	for (ptchain = namechain; ptchain; ptchain = ptchain->NEXT)
	   ptchain->DATA = (void *)namealloc((char *)ptchain->DATA);

	ptsig->NAMECHAIN = namechain;
	ptsig->INDEX    = index;
	ptsig->CAPA   = capa;
	ptsig->USER   = NULL;
	ptsig->TYPE   = type;
	ptsig->NEXT   = ptfig->LOSIG;
	ptfig->LOSIG    = ptsig;

	if (TRACE_MODE == 'Y') {
	   (void)fprintf(stdout, "--- mbk --- addlosig : %ld ", index);
	   if (ptsig->NAMECHAIN)
	      if (ptsig->NAMECHAIN->DATA)
	         (void)fprintf(stdout, "name : %s",
	                        (char *)((chain_list *)(ptsig->NAMECHAIN))->DATA);
	   (void)fprintf(stdout, "\n");
	}
	
	return ptsig;
}

/*******************************************************************************
* function dellofig()                                                          *
*******************************************************************************/
int dellofig(name)
char *name;
{
lofig_list *ptfig;
loins_list *ptins;
locon_list *ptcon;
ptype_list *pt;
void *ptold;

	name = namealloc(name);
	for (ptfig = HEAD_LOFIG; ptfig; ptfig = ptfig->NEXT) {
	   if (ptfig->NAME == name)
	      break;
	   ptold = (void *)ptfig;
	}
	if (ptfig == NULL)
	   return 0;
	else if (ptfig == HEAD_LOFIG) 
	   HEAD_LOFIG = ptfig->NEXT;
	else 
	   ((lofig_list *)ptold)->NEXT = ptfig->NEXT;
	for (ptins = ptfig->LOINS; ptins; ptins = (loins_list *)ptold) {
	   ptold = (void *)ptins->NEXT;
	   mbkfree((void *)ptins);
	}
	for (pt = ptfig->BKSIG; pt; pt = pt->NEXT)
	   mbkfree((void *)pt->DATA);
	freeptype(ptfig->BKSIG);
	for (ptcon = ptfig->LOCON; ptcon; ptcon = (locon_list *)ptold) {
	   ptold = (void *)ptcon->NEXT;
	   mbkfree((void *)ptcon);
	}
	mbkfree((void *)ptfig);
	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- dellofig  : %s\n", name);
	return 1;
}

/*******************************************************************************
* function  freelomodel()                                                      *
*******************************************************************************/
void freelomodel(ptmodel)
lofig_list *ptmodel;
{
lofig_list *ptfig;
locon_list *ptcon;
locon_list *ptc;

	if (!ptmodel) /* nothing to be freed */
	   return;

	ptfig = ptmodel->NEXT;
	while (1) { 
	   for (ptcon = ptmodel->LOCON; ptcon; ptcon = ptc) {
	      ptc = ptcon->NEXT;
	      mbkfree((void *)ptcon);
	   }
	   mbkfree((void *)ptmodel);
	   ptmodel = ptfig;
	   if (!ptfig)
	      break;
	   ptfig = ptfig->NEXT;
	}

	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- freelomodel\n");
}

/*******************************************************************************
* function  dellosig()                                                         *
*******************************************************************************/
int dellosig(ptfig, index)
lofig_list *ptfig;
long index;
{
losig_list *ptsav;
losig_list *ptsig;

	for (ptsig = ptfig->LOSIG; ptsig; ptsig = ptsig->NEXT) {
	   if (ptsig->INDEX == index)
	      break;
	   ptsav = ptsig;
	}

	if (ptsig == NULL)
	   return 0;
	else if (ptsig == ptfig->LOSIG)
	   ptfig->LOSIG = ptsig->NEXT;
	else
	   ptsav->NEXT = ptsig->NEXT;
	ptsig->INDEX = 0L;

	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- dellosig  : %ld\n", index);

	return 1;
}

/*******************************************************************************
* function dellotrs()                                                          *
*******************************************************************************/
int dellotrs(ptfig, pttrs)
lofig_list  *ptfig;
lotrs_list  *pttrs;
{
lotrs_list  *pt;
lotrs_list  *ptsav;

	for (pt = ptfig->LOTRS; pt; pt = pt->NEXT) {
	   if (pt == pttrs)
	      break;
	   ptsav = pt;
	}
	if (pt == NULL)
	   return 0;
	else if (pt == ptfig->LOTRS)
	   ptfig->LOTRS = pt->NEXT;
	else
	   ptsav->NEXT = pt->NEXT;

	mbkfree((void *)pt->GRID);
	mbkfree((void *)pt->SOURCE);
	mbkfree((void *)pt->DRAIN);
	mbkfree((void *)pt);
	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- dellotrs  : \n");
	return 1;
}  

/*******************************************************************************
* function delloins()                                                          *
*******************************************************************************/
int delloins(ptfig, insname)
lofig_list *ptfig;
char *insname;
{
loins_list *ptins;
locon_list *ptcon;
chain_list *ptchain;
chain_list *pttmpchain;
void    *pt;
char *figname;

	insname = namealloc(insname);
	for (ptins = ptfig->LOINS; ptins; ptins = ptins->NEXT) {
	   if (ptins->INSNAME == insname)
	      break;
	   pt = (void *)ptins;
	}
	if (ptins == NULL)   
	   return 0;
	if (ptins == ptfig->LOINS) {
	   figname = ptins->FIGNAME;
	   ptfig->LOINS = ptins->NEXT;
	} else {
	   figname = ptins->FIGNAME;
	   ((loins_list *)pt)->NEXT = ptins->NEXT;
	}
	for (ptcon = ptins->LOCON; ptcon; ptcon = (locon_list *)pt) {
	   pt = (void *)ptcon->NEXT;
	   mbkfree((void *)ptcon);
	}

	mbkfree((void *)ptins);

	for (ptins = ptfig->LOINS; ptins; ptins = ptins->NEXT)
	   if (ptins->FIGNAME == figname)
	      break;
	if (ptins == NULL) { /* if no more instance have this model, destroy */
	   for (ptchain = ptfig->MODELCHAIN; ptchain; ptchain = ptchain->NEXT) {
	      if (ptchain->DATA == (void *)figname)
	         break;
	      pttmpchain = ptchain;
	   }
	   if (ptchain == ptfig->MODELCHAIN && ptchain != NULL)
	      ptfig->MODELCHAIN = ptchain ->NEXT;
	   else if (ptchain)
	      pttmpchain->NEXT = ptchain->NEXT;
	}

	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- delloins  : %s\n", insname);
	return 1;
}

/*******************************************************************************
* function dellocon()                                                          *
*******************************************************************************/
int dellocon(ptfig, name)
lofig_list *ptfig;
char *name;
{
locon_list *ptcon;
locon_list *ptsav;

	name = namealloc(name);
	for (ptcon = ptfig->LOCON; ptcon; ptcon = ptcon->NEXT) {
	   if (ptcon->NAME == name)
	      break;
	   ptsav = ptcon;
	}
	if (ptcon == NULL)    
	   return 0;
	else if (ptcon == ptfig->LOCON)   
	   ptfig->LOCON = ptcon->NEXT;
	else 
	   ptsav->NEXT = ptcon->NEXT;
	mbkfree((void *)ptcon);
	if (TRACE_MODE == 'Y')
	   (void)fprintf(stdout, "--- mbk --- dellocon  : %s\n", name);

	return 1;
}

/*******************************************************************************
* function getlomodel                              *
* gives a pointer to a model or NULL if it doesn't exist             *
*******************************************************************************/
lofig_list *getlomodel(ptmodel, name)
lofig_list *ptmodel;
char *name;
{
lofig_list *ptfig;

	name = namealloc(name);
	for (ptfig = ptmodel; ptfig; ptfig = ptfig->NEXT)
	   if (ptfig->NAME == name)
	      return ptfig;
	return NULL;
}

/*******************************************************************************
* function getloins()                                                          *
*******************************************************************************/
loins_list *getloins(ptfig, name)
lofig_list *ptfig;
char *name;
{
loins_list *ptins;

	name = namealloc(name);

	for (ptins = ptfig->LOINS; ptins; ptins = ptins->NEXT)
	   if (ptins->INSNAME == name)
	      return ptins;

	(void)fflush(stdout);
	(void)fprintf(stderr, "*** mbk error ***\n");
	(void)fprintf(stderr, "getloins impossible :\n");
	(void)fprintf(stderr, "instance %s doesn't exist in figure %s\n", 
	                 name, ptfig->NAME);
	EXIT(1);
}

/*******************************************************************************
* function getlocon()                                                          *
*******************************************************************************/
locon_list *getlocon(ptfig, name)
lofig_list  *ptfig;
char   *name;
{
locon_list  *ptcon;

	name = namealloc(name);

	for (ptcon = ptfig->LOCON; ptcon; ptcon = ptcon->NEXT)
	   if (ptcon->NAME == name)
	return ptcon;

	(void)fflush(stdout);
	(void)fprintf(stderr, "*** mbk error ***\n");
	(void)fprintf(stderr, "getlocon impossible :\n");
	(void)fprintf(stderr, "connector %s doesn't exist in figure %s\n", 
	                 name, ptfig->NAME);
	EXIT(1);
}

/*******************************************************************************
* function getlosig()                                                          *
*******************************************************************************/
losig_list *getlosig(ptfig, index)
lofig_list *ptfig;
long index;
{
losig_list *ptsig;
ptype_list *pt;
short low;
short high;

	low = (short)(index % SIGSIZE);
	high = (short)(index / SIGSIZE);
	for (pt = ptfig->BKSIG; pt; pt = pt->NEXT)
	   if (pt->TYPE == high) break;
	if (pt != NULL) {
	   ptsig = (losig_list *)(pt->DATA) + low;
	   if (ptsig->INDEX == index)
	      return ptsig;
	}

	(void)fflush(stdout);
	(void)fprintf(stderr, "*** mbk error ***\n");
	(void)fprintf(stderr, "getlosig impossible :\n");
	(void)fprintf(stderr, "signal %ld doesn't exist in figure %s\n", 
	                 index, ptfig->NAME);
	EXIT(1);
}

/*******************************************************************************
* function addcapa                               *
*******************************************************************************/
void addcapa(ptsig, ctot)
losig_list *ptsig;
float ctot;
{
	ptsig->CAPA += ctot;
}

/*******************************************************************************
* function  lofigchain()                                                       *
* For each signal, construct the list of connectors associated                 *
* with the signal.(Field   USER  of the "losig" structure with                 *
* the code "LOFIGCHAIN")                                                       *
* This provide the "dual" representation of the net-list                       *
*******************************************************************************/
void lofigchain(ptfig)
lofig_list *ptfig;
{
locon_list *ptcon = NULL;
losig_list *ptsig = NULL;
loins_list *ptins = NULL;
lotrs_list *pttrs = NULL;
ptype_list *ptype = NULL;

	if (ptfig->MODE != 'A') {
	   (void)fflush(stdout);
	   (void)fprintf(stderr, "*** mbk error ***\nlofigchain impossible ");
	   (void)fprintf(stderr, ": figure %s is interface only\n", 
	                  ptfig->NAME);
	   EXIT(1);
	}

	/*  cleaning ...   */
	for (ptsig = ptfig->LOSIG; ptsig; ptsig = ptsig->NEXT) {
	   ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
	   if (ptype != (ptype_list *)NULL) {
	      freechain((chain_list *)ptype->DATA);
	      ptype->DATA = (void *)NULL;
	   } else
	      ptsig->USER = addptype(ptsig->USER, (long)LOFIGCHAIN, (void *)NULL);
	}

	/*  scan connector list  */
	for (ptcon=ptfig->LOCON; ptcon; ptcon=ptcon->NEXT) {
	   ptsig = ptcon->SIG;
	   ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
	   ptype->DATA = (void *)addchain((chain_list *)ptype->DATA, (void *)ptcon);
	}

	/*  scan instance  list    */ 
	for (ptins =ptfig->LOINS; ptins; ptins=ptins->NEXT) {
	   for (ptcon=ptins->LOCON; ptcon; ptcon=ptcon->NEXT) {
	      ptsig=ptcon->SIG;
	      ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
	      ptype->DATA = (void *)addchain((chain_list *)ptype->DATA,
	                                       (void *)ptcon);
	   }
	}

	/*  scan transistor list   */
	for (pttrs = ptfig->LOTRS; pttrs; pttrs = pttrs->NEXT) {
	   ptsig = pttrs->GRID->SIG;
	   ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
	   ptype->DATA = (void *)addchain((chain_list *)ptype->DATA, 
	                                    (void *)pttrs->GRID);
	   ptsig = pttrs->SOURCE->SIG;
	   ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
	   ptype->DATA = (void *)addchain((chain_list *)ptype->DATA, 
	                                    (void *)pttrs->SOURCE);
	   ptsig = pttrs->DRAIN->SIG;
	   ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
	   ptype->DATA = (void *)addchain((chain_list *)ptype->DATA, 
	                                    (void *)pttrs->DRAIN);
	}
	if (DEBUG_MODE == 'Y')
	   (void)printf("--- mbk --- lofigchain %s\n", ptfig->NAME);
}

/*******************************************************************************
* function getsigname()                                                        *
* choose the least concatened signal name                                      *
*******************************************************************************/
char *getsigname(ptsig)
losig_list *ptsig;
{
chain_list *ptscan;
char *ptchar;
char buffer[50];
char *result = NULL;
register int nseparmin = 1000;

	if (ptsig == NULL)
	   return NULL;

	for (ptscan = ptsig->NAMECHAIN; ptscan; ptscan = ptscan->NEXT) {
	register int nsepar = 0;
	   if (ptscan->DATA != NULL) {
	      for (ptchar = (char *)ptscan->DATA; *ptchar != '\0'; ptchar++)
	         if (*ptchar == SEPAR)
	            nsepar++;
	      if (nsepar < nseparmin) {
	         nseparmin = nsepar;
	         result = (char *)ptscan->DATA;
	      }
	   }
	}
	if (!result) {
	   (void)sprintf(buffer, "%ld", ptsig->INDEX);
	   result = namealloc(buffer);
	}
	return result;
}

/*******************************************************************************
* function viewlo()                                                            *
* display on screen the content of all logical figures                         *
*******************************************************************************/
void viewlo()
{
lofig_list  *ptfig;

	if (HEAD_LOFIG == NULL) {
	   (void)printf("\n!!! viewlo : empty list of figure !!!\n");
	   return;
	} else for (ptfig = HEAD_LOFIG; ptfig; ptfig = ptfig->NEXT)
	   viewlofig(ptfig);
}

/*******************************************************************************
* function viewlofig()                                                         *
* display on screen the content of logical figure ptfig                        *
*******************************************************************************/
void viewlofig(ptfig)
lofig_list  *ptfig;
{
locon_list *ptcon;
losig_list *ptsig;
loins_list *ptins;
lotrs_list *pttrs;

	if (ptfig->NAME == NULL)
		(void)printf("!!! figure without name !!! /n");
	else
		(void)printf("\nfigure   : %-20s  mode : %c\n", ptfig->NAME, ptfig->MODE);

	if (ptfig->LOCON == NULL) 
		(void)printf("   |---empty connector list\n");   
	else for (ptcon = ptfig->LOCON; ptcon; ptcon = ptcon->NEXT)
		viewlofigcon(ptcon);

	if (ptfig->LOSIG == NULL)
		(void)printf("   |---empty signal list\n");
	else for (ptsig = ptfig->LOSIG; ptsig; ptsig = ptsig->NEXT)
		viewlosig(ptsig);

	if (ptfig->LOINS == NULL)
		(void)printf("   |---empty instance list\n");
	else for (ptins = ptfig->LOINS; ptins; ptins = ptins->NEXT)
		viewloins(ptins);

	if (ptfig->LOTRS == NULL)
		(void)printf("   |---empty transistor list\n");
	else for (pttrs = ptfig->LOTRS; pttrs; pttrs = pttrs->NEXT)
		viewlotrs(pttrs);

	if (ptfig->USER != NULL)
		(void)printf("   |---non empty USER field\n");

	(void)printf("   | \n");
}   

/*******************************************************************************
* function viewlofigcon()                                                      *
*******************************************************************************/
void viewlofigcon(ptcon)
locon_list  *ptcon; 
{ 
	if (ptcon->NAME == NULL)
		(void)printf("   |--- !!! connector without name !!!\n");
	else
		(void)printf("   |---connector  : %s\n", ptcon->NAME);
	(void)printf("   |    |---direction  : %c\n", ptcon->DIRECTION);
	if (ptcon->SIG == NULL)
		(void)printf("   |    |---no signal\n");
	else
		(void)printf("   |    |---signal    : %ld\n", ptcon->SIG->INDEX);
	if (ptcon->ROOT == NULL)
		(void)printf("   |---no root\n");
	else
		(void)printf("   |    |---root    : %s\n",
									((char *)(((lofig_list *)(ptcon->ROOT))->NAME)));
	(void)printf("   |    |---type    : %c \n", ptcon->TYPE);
	if (ptcon->USER != NULL)
		(void)printf("   |    |---non empty USER field\n");
	(void)printf("   |\n");
}

/*******************************************************************************
* function viewlosig()                                                         *
*******************************************************************************/
void viewlosig(ptsig)
losig_list  *ptsig;
{ 
chain_list  *ptchain;

	(void)printf("   |---signal    : %ld \n" , ptsig->INDEX);
	if (ptsig->NAMECHAIN == NULL)
		(void)printf("   |    |---no alias names\n");
	else for (ptchain = ptsig->NAMECHAIN; ptchain; ptchain = ptchain->NEXT) {  
  		if (ptchain->DATA == NULL)
			(void)printf("   |    |--- !!! empty name !!!\n");
  		else
			(void)printf("   |    |---alias   : %s\n", (char *)ptchain->DATA);
	}
	(void)printf("   |    |---capacitance : %f\n" , ptsig->CAPA);
	(void)printf("   |    |---type    : %c\n" , ptsig->TYPE);
	if (ptsig->USER != NULL)
		(void)printf("   |    |---non empty USER field\n");
	(void)printf("   | \n");
}


/*******************************************************************************
* function viewloins()                                                         *
*******************************************************************************/
void viewloins(ptins)
loins_list  *ptins;
{ 
locon_list  *ptcon;

if (ptins->INSNAME == NULL)
	(void)printf("   |--- !!! no instance name !!!\n");
else
	(void)printf("   |---instance   : %s\n", ptins->INSNAME);
if (ptins->FIGNAME == NULL)
	(void)printf("   |   |--- !!! no instance model	!!!\n");
else
	(void)printf("   |   |---model     : %s \n" , ptins->FIGNAME);
if (ptins->LOCON == NULL)
	(void)printf("   |   |---empty list of connectors\n");
else for (ptcon = ptins->LOCON; ptcon != NULL; ptcon = ptcon->NEXT)
	viewloinscon(ptcon);
if (ptins->USER != NULL)
	(void)printf("   |   |---non empty USER field\n");
	(void)printf("   | \n");
}

/*******************************************************************************
* function viewlotrs()                                                         *
*******************************************************************************/
void viewlotrs(pttrs)
lotrs_list  *pttrs;
{ 
	(void)printf("   |---transistor\n");
if (pttrs->TYPE == TRANSN)
	(void)printf("   |   |---type  : TRANSN \n");
else if (pttrs->TYPE == TRANSP)
	(void)printf("   |   |---type  : TRANSP \n");
else 
	(void)printf("   |   |---illegal type\n");
if (pttrs->SOURCE == NULL)
	(void)printf("   |   |--- !!! no signal on source !!! \n");
else
	(void)printf("   |   |---source signal : %ld\n", pttrs->SOURCE->SIG->INDEX);
if (pttrs->GRID == NULL)
	(void)printf("   |   |--- !!! no signal on grid !!!\n");
else
	(void)printf("   |   |---grid signal : %ld\n", pttrs->GRID->SIG->INDEX);
if (pttrs->DRAIN == NULL)
	(void)printf("   |   |--- !!! no signal on drain !!!\n");
else
	(void)printf("   |   |---drain signal : %ld\n", pttrs->DRAIN->SIG->INDEX);
	(void)printf("   |   |---x   : %ld\n", pttrs->X);
	(void)printf("   |   |---y   : %ld\n", pttrs->Y);
	(void)printf("   |   |---width  : %d\n", pttrs->WIDTH);
	(void)printf("   |   |---length : %d\n", pttrs->LENGTH);
	(void)printf("   |   |---ps    : %d\n", pttrs->PS);
	(void)printf("   |   |---pd    : %d\n", pttrs->PD);
	(void)printf("   |   |---xs    : %d\n", pttrs->XS);
	(void)printf("   |   |---xd    : %d\n", pttrs->XD);
if (pttrs->USER != NULL)
	(void)printf("   |   |---non empty USER field\n");
	(void)printf("   |\n");
}

/*******************************************************************************
* function viewloinscon()                                                      *
*******************************************************************************/
void viewloinscon(ptcon)
locon_list  *ptcon;
{
if (ptcon->NAME == NULL)
	(void)printf("   |   |---no instance connector name\n");
else
	(void)printf("   |   |---connector  : %s\n" , ptcon->NAME);
	(void)printf("   |   |    |---direction  : %c\n" , ptcon->DIRECTION);
if (ptcon->SIG == NULL)
	(void)printf("   |   |    |---no signal\n");
else
	(void)printf("   |   |    |---signal    : %ld\n" , ptcon->SIG->INDEX);
if ((ptcon->ROOT) == NULL)
	(void)printf("   |   |    |---no root\n");
else
	(void)printf("   |   |    |---root    : %s\n" , ((char*)(((loins_list *)(ptcon->ROOT))->INSNAME)));
	(void)printf("   |   |    |---type    : %c\n" , ptcon->TYPE);
if (ptcon->USER != NULL)
	(void)printf("   |   |    |---non empty USER field\n");
	(void)printf("   |   | \n");
}
