/*******************************************************************************
* mbk     : acces functions to physical structures                             *
*                                                                              *
* version : 3.06                                                               *
* date    : 05/11/92                                                           *
*******************************************************************************/

#include MUT_H
#include MPH_H
#include "mbk_ph.h"

/*******************************************************************************
* global variable for physical view                                            *
*******************************************************************************/
phfig_list *HEAD_PHFIG;                        /* logical figure list head    */

/*******************************************************************************
* fonction addphfig                                                            *
*******************************************************************************/
phfig_list *addphfig(figname)
char *figname;
{
phfig_list *ptfig;

	figname = namealloc(figname);

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

	/* scan figure_list */
	for (ptfig = HEAD_PHFIG; ptfig; ptfig = ptfig->NEXT)
		if (ptfig->NAME == figname)
			break;

	if (ptfig != NULL) {  /* figure exists */
		(void)fflush(stdout);
		(void)fprintf(stderr, "\n*** mbk error *** illegal addphfig\n");
		(void)fprintf(stderr, "figure %s already exists\n", figname);
		EXIT(1);
	}
	ptfig = (phfig_list *)mbkalloc(sizeof(phfig_list));
	ptfig->MODE       = 'A';
	ptfig->NAME       = figname;
	ptfig->MODELCHAIN = NULL;
	ptfig->PHSEG      = NULL;
	ptfig->PHCON      = NULL;
	ptfig->PHINS      = NULL;
	ptfig->PHVIA      = NULL;
	ptfig->PHREF      = NULL;
	ptfig->XAB1       = 0;
	ptfig->YAB1       = 0;
	ptfig->XAB2       = 0;
	ptfig->YAB2       = 0;
	ptfig->USER       = NULL;
	ptfig->NEXT       = HEAD_PHFIG;
	HEAD_PHFIG = ptfig;

	return ptfig;
}

/*******************************************************************************
* fonction addphins                                                            *
*******************************************************************************/
phins_list *addphins(ptfig, figname, insname, sym, x, y)
phfig_list *ptfig;
char *figname;
char *insname;
char sym;
long x, y;
{
phins_list *ptins;
chain_list *ptchain;
chain_list *addchain();

	insname = namealloc(insname);
	figname = namealloc(figname);

	/*  check  consistency    */
	if (FAST_MODE != 'Y' && strcmp(insname, "*")) {
		if (sym != NOSYM && sym != SYM_X && sym != SYM_Y && sym != SYMXY &&
				sym != ROT_P && sym != ROT_M && sym != SY_RP && sym != SY_RM) {
			(void)fflush(stdout);
			(void)fprintf(stderr, "\n*** mbk error *** illegal addphins ");
			(void)fprintf(stderr, "transformation %ld in : %s\n",
								(long)sym, insname);
			EXIT(1);
		}

		/* check instance name unicity  */
		for (ptins = ptfig->PHINS; ptins; ptins = ptins->NEXT)
			if (ptins->INSNAME == insname)
				break;
		if (ptins != NULL) {
			(void)fflush(stdout);
			(void)fprintf(stderr, "\n*** mbk error *** illegal addphins\n");
			(void)fprintf(stderr, "duplicate instance name : %s\n", insname);
			EXIT(1);
		}
		if (ptfig->NAME == figname) {
			(void)fflush(stdout);
			(void)fprintf(stderr, "*** mbk error ***\naddphins\n");
			(void)fprintf(stderr, "figure %s cannot be part of itself\n", figname); 
			EXIT(1);
		}
	}

	/* update instance list  */
	ptins = (phins_list *)mbkalloc(sizeof(phins_list));
	ptins->INSNAME = insname;
	ptins->FIGNAME = figname;
	ptins->TRANSF  = sym;
	ptins->XINS    = x;
	ptins->YINS    = y;
	ptins->USER    = NULL;
	ptins->NEXT    = ptfig->PHINS;
	ptfig->PHINS  = ptins;

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

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

	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- addphins : ");
		(void)fprintf(stdout, "%s  x=%ld  y=%ld trans=%ld\n", insname, x, y, 
			(long)(ptins->TRANSF));
	}
	return ptins;
}

/*******************************************************************************
* fonction addphvia                                                            *
*******************************************************************************/
phvia_list *addphvia(ptfig, viatype, x, y)
phfig_list *ptfig;
char viatype;
long x, y;
{
phvia_list *ptvia;

/*  check  consistency    */
	if (viatype < 0 || viatype > LAST_CONTACT) {
		(void)fflush(stdout);
		(void)fprintf(stderr, "*** mbk error ***\nillegal addphvia viatype ");
		(void)fprintf(stderr, ": %ld at x=%ld y=%ld\n", (long)viatype, x, y);
		EXIT(1);
	}

	/* update via list  */
	ptvia = (phvia_list *)mbkalloc(sizeof(phvia_list));
	ptvia->TYPE = viatype;
	ptvia->XVIA = x;
	ptvia->YVIA = y;
	ptvia->USER = NULL;
	ptvia->NEXT = ptfig->PHVIA;
	ptfig->PHVIA = ptvia;

	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- addphvia  : ");
		(void)fprintf(stdout, "type=%ld  x=%ld  y=%ld \n", (long)viatype, x, y);
	}
	return ptvia;
}

/*******************************************************************************
* fonction addphref                                                            *
*******************************************************************************/
phref_list *addphref(ptfig, type, name, x, y)
phfig_list *ptfig;
char *type;
char *name;
long x, y;
{
phref_list *ptref;

	name = namealloc(name);
	type = namealloc(type);

	/* update ref list  */
	ptref = (phref_list *)mbkalloc(sizeof(phref_list));
	ptref->FIGNAME = type;
	ptref->NAME = name;
	ptref->XREF = x;
	ptref->YREF = y;
	ptref->USER = NULL;
	ptref->NEXT = ptfig->PHREF;
	ptfig->PHREF = ptref;

	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- addphref  : ");
		(void)fprintf(stdout, "type %s name %s x=%ld  y=%ld \n", type, name, x, y);
	}
	return ptref;
}

/*******************************************************************************
* fonction addphseg                                                            *
*******************************************************************************/
phseg_list *addphseg(ptfig, layer, width, x1, y1, x2, y2, nodename)
phfig_list *ptfig;
char layer;
long width;
long x1, y1, x2, y2;
char *nodename;
{
phseg_list *ptseg;

	nodename = namealloc(nodename);
	if (layer < 0 || layer > LAST_LAYER) {
		(void)fflush(stdout);
		(void)fprintf(stderr, "*** mbk error ***\nillegal addphseg");
		(void)fprintf(stderr, "wrong layer code = %ld on segment ", (long)layer);
		(void)fprintf(stderr, "x1=%ld y1=%ld x2=%ld y2=%ld\n", x1, y1, x2, y2);
		EXIT(1);
	}

	/*  update segment list  */
	ptseg = (phseg_list *)mbkalloc(sizeof(phseg_list));

	if (y1 == y2) {
		ptseg->Y1 = ptseg->Y2 = y1;
		if (x1 < x2) {
			ptseg->TYPE = RIGHT;
			ptseg->X1 = x1;
			ptseg->X2 = x2;
		} else {
			ptseg->TYPE = LEFT;
			ptseg->X1 = x2;
			ptseg->X2 = x1;
		}
	} else if (x1 == x2) {
		ptseg->X1 = ptseg->X2 = x1;
		if (y1 < y2) {
			ptseg->TYPE = UP;
			ptseg->Y1 = y1;
			ptseg->Y2 = y2;
		} else {
			ptseg->TYPE = DOWN;
			ptseg->Y1 = y2;
			ptseg->Y2 = y1;
		}
	} else {
		(void)fflush(stdout);
		(void)fprintf(stderr, "\n*** mbk error *** illegal addphseg\n");
		(void)fprintf(stderr, "x1=%ld  y1=%ld  x2=%ld  y2=%ld  layer=%ld\n", 
							x1, y1, x2, y2, (long)layer);
		EXIT(1);
	}
	ptseg->LAYER = layer;
	ptseg->NAME = nodename;
	ptseg->WIDTH = width;
	ptseg->USER = NULL;
	ptseg->NEXT = ptfig->PHSEG;
	ptfig->PHSEG = ptseg;
	
	if (TRACE_MODE == 'Y') {
	(void)fprintf(stdout, "--- mbk --- addphseg  : ");
	if (nodename == namealloc("") || nodename == namealloc("*") 
			|| nodename == NULL)
		(void)printf("x1=%ld y1=%ld x2=%ld y2=%ld layer=%ld width=%ld\n", 
							x1, y1, x2, y2, (long)layer, width);
	else 
		(void)printf("x1=%ld y1=%ld x2=%ld y2=%ld layer=%ld width=%ld name=%s\n",
							x1, y1, x2, y2, (long)layer, width, nodename);
	}
	return ptseg;
}

/*******************************************************************************
* fonction addsorted                                                           *
*******************************************************************************/
static chain_list *addsorted(pa, pco, dx)
chain_list *pa;
phcon_list *pco;
long dx;
{
chain_list *ptchain, *oldp;

	if (pa == NULL) /* first connector */
		return addchain((chain_list *)NULL, (void *)pco);
	if ((((phcon_list *)pa->DATA)->XCON + /* insert in head */
			(((phcon_list *)pa->DATA)->YCON + 1) * dx) >
			(pco->XCON + (pco->YCON + 1) * dx))
		return addchain(pa, (void *)pco);
	else if ((((phcon_list *)pa->DATA)->XCON + /* insert in head */
			(((phcon_list *)pa->DATA)->YCON + 1) * dx) ==
			(pco->XCON + (pco->YCON + 1) * dx))
			if (((phcon_list *)pa->DATA)->LAYER > pco->LAYER) {
			  return addchain(pa, (void *)pco);
			} else {
			  pa->NEXT = addchain(pa->NEXT, (void *)pco);
			  return pa;
		}
	for (ptchain = pa->NEXT, oldp = pa; ptchain != NULL; /* general case */
			oldp = ptchain, ptchain = ptchain->NEXT)
		if ((((phcon_list *)ptchain->DATA)->XCON +
				(((phcon_list *)ptchain->DATA)->YCON + 1) * dx) >
				(pco->XCON + (pco->YCON + 1) * dx)) {
			oldp->NEXT = addchain(ptchain, (void *)pco);
			return pa;
		} else if ((((phcon_list *)ptchain->DATA)->XCON +
				(((phcon_list *)ptchain->DATA)->YCON + 1) * dx) ==
				(pco->XCON + (pco->YCON + 1) * dx))
			if (((phcon_list *)ptchain->DATA)->LAYER > pco->LAYER) {
			  oldp->NEXT = addchain(ptchain, (void *)pco);
			  return pa;
			} else {
			  ptchain->NEXT = addchain(ptchain->NEXT, (void *)pco);
			  return pa;
			}
	/* put it at the end */
	oldp->NEXT = addchain((chain_list *)NULL, (void *)pco);
	return pa;
}

/*******************************************************************************
* fonction addphcon                                                            *
*******************************************************************************/
phcon_list *addphcon(ptfig, orient, conname, x, y, layer, width)
phfig_list *ptfig;
char orient;
char *conname;
long x, y;
char layer;
long width;
{
phcon_list *ptcon, *ptscan;
chain_list *pt, *ptchain = NULL;
long index;

   conname = namealloc(conname);
   /* check consistency */
   if (layer < 0 || layer > LAST_LAYER) {
		(void)fflush(stdout);
      (void)fprintf(stderr, "\n*** mbk error *** illegal addphcon\n");
      (void)fprintf(stderr, "figure : %s\n", ptfig->NAME);
      (void)fprintf(stderr, "code layer is %ld in %s\n", (long)layer, conname);
      EXIT(1);
   }
   if (orient != NORTH && orient != EAST && orient != SOUTH &&
       orient != WEST) {
		(void)fflush(stdout);
      (void)fprintf(stderr, "\n*** mbk error *** illegal addphcon\n");
      (void)fprintf(stderr, "figure : %s\n", ptfig->NAME);
      (void)fprintf(stderr, "orientation is %ld in : %s\n", (long)orient, 
           conname);
      EXIT(1);
   }
   if (x < ptfig->XAB1 || x > ptfig->XAB2 || y < ptfig->YAB1
       || y > ptfig->YAB2) {
		(void)fflush(stdout);
      (void)fprintf(stderr, "\n*** mbk error ***    illegal addphcon\n");
      (void)fprintf(stderr, "connector %s (%ld, %ld) not in abutement box\n", 
           conname, x, y);
      EXIT(1);
   }
   /* update connector list */
   ptcon = (phcon_list *)mbkalloc(sizeof(phcon_list));
   ptcon->INDEX = 0;
   ptcon->XCON = x;
   ptcon->YCON = y;
   ptcon->WIDTH = width;
   ptcon->ORIENT = orient;
   ptcon->NAME = conname;
   ptcon->LAYER = layer;
   ptcon->USER = NULL;
   ptcon->NEXT = ptfig->PHCON;
   ptfig->PHCON = ptcon;

   /* update index list with topological sort */
   for (ptscan = ptfig->PHCON; ptscan; ptscan = ptscan->NEXT) {
      if (conname == ptscan->NAME) /* if such a connector already exists*/
         ptchain = addsorted(ptchain, ptscan, ptfig->XAB2 - ptfig->XAB1);
   }
   for (pt = ptchain, index = 0; pt != NULL; index++, pt = pt->NEXT)
         ((phcon_list *)pt->DATA)->INDEX = index;
   freechain(ptchain);
 
   if (TRACE_MODE == 'Y') {
      (void)fprintf(stdout, "--- mbk --- addphcon  : ");
      (void)fprintf(stdout, "%s.%ld x=%ld  y=%ld w=%ld\n", conname, 
           index, x, y, width);
   }
   return ptcon;
}

/*******************************************************************************
* fonction defab                                                               *
*******************************************************************************/
void defab(ptfig, x1, y1, x2, y2)
phfig_list    *ptfig;
long           x1, x2, y1, y2;
{
	ptfig->XAB1 = x1;
	ptfig->YAB1 = y1;
	ptfig->XAB2 = x2;
	ptfig->YAB2 = y2;

	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- defab    : ");
		(void)fprintf(stdout, "%s x1= %ld y1=%ld x2=%ld y2=%ld\n",
							ptfig->NAME, x1, y1, x2, y2);
	}
}

/*******************************************************************************
* fonction getphins                                                            *
*******************************************************************************/
phins_list *getphins(ptfig, insname)
phfig_list *ptfig;
char *insname;
{
phins_list *ptins;

	insname = namealloc(insname);
	for (ptins = ptfig->PHINS; ptins; ptins = ptins->NEXT)
		if (ptins->INSNAME == insname)
			return ptins;
	(void)fflush(stdout);
	(void)fprintf(stderr, "\n*** mbk error ***\nillegal getphins ");
	(void)fprintf(stderr, "instance %s doesn't exist in figure %s\n", 
						insname, ptfig->NAME);
	EXIT(1);
}

/*******************************************************************************
* fonction getphcon                                                            *
*******************************************************************************/
phcon_list *getphcon(ptfig, conname, index)
phfig_list *ptfig;
char *conname;
long index;
{
phcon_list *ptcon;
 
   conname = namealloc(conname);
 
   if (ptfig->PHCON != NULL)
      for (ptcon = ptfig->PHCON; ptcon; ptcon = ptcon->NEXT)
         if (ptcon->NAME == conname && ptcon->INDEX == index)
            return ptcon;
 
	(void)fflush(stdout);
   (void)fprintf(stderr, "\n*** mbk error ***   illegal getphcon\n");
   (void)fprintf(stderr, "connector %s.%ld doesn't exist in figure %s\n", 
        conname, index, ptfig->NAME);
   EXIT(1);
}

/*******************************************************************************
* fonction getphref                                                            *
*******************************************************************************/
phref_list *getphref(ptfig, refname)
phfig_list *ptfig;
char *refname;
{
phref_list *ptref;

	refname = namealloc(refname);
	for (ptref = ptfig->PHREF; ptref; ptref = ptref->NEXT)
		if (ptref->NAME == refname)
			return ptref;
	(void)fflush(stdout);
	(void)fprintf(stderr, "\n*** mbk error ***\nillegal getphref ");
	(void)fprintf(stderr, "reference %s doesn't exist in figure %s\n", 
						refname, ptfig->NAME);
	EXIT(1);
}

/*******************************************************************************
* fonction delphcon                                                            *
*******************************************************************************/
int delphcon(ptfig, ptdelcon)
phfig_list *ptfig;
phcon_list *ptdelcon;
{
phcon_list *ptsav;
phcon_list *ptcon, *ptscan;
chain_list *pt, *ptchain = NULL;
long index;
char  *conname;
 
   for (ptcon = ptfig->PHCON; ptcon; ptcon = ptcon->NEXT) {
      if (ptcon == ptdelcon)
         break;
      ptsav = ptcon;
   }
   if (ptcon == NULL)
      return 0;
   else if (ptcon == ptfig->PHCON) {
      ptfig->PHCON = ptcon->NEXT;
      conname = ptcon->NAME;
   } else {
      ptsav->NEXT = ptcon->NEXT;
      conname = ptcon->NAME;
   }
   /* update index list with topological sort */
   for (ptscan = ptfig->PHCON; ptscan; ptscan = ptscan->NEXT) {
      if (conname == ptscan->NAME) /* if such a connector already exists*/
         ptchain = addsorted(ptchain, ptscan, ptfig->XAB2 - ptfig->XAB1);
   }
   for (pt = ptchain, index = 0; pt != NULL; index++, pt = pt->NEXT)
         ((phcon_list *)pt->DATA)->INDEX = index;
   freechain(ptchain);
 
   if (TRACE_MODE == 'Y') {
      (void)fprintf(stdout, "--- mbk --- delphcon  : ");
      (void)fprintf(stdout, "%s.%ld\n", ptdelcon->NAME, ptdelcon->INDEX);
   }
   mbkfree((void *)ptdelcon);
   return 1;
}

/*******************************************************************************
* fonction delphseg                                                            *
*******************************************************************************/
int delphseg(ptfig, ptseg)
phfig_list *ptfig;
phseg_list *ptseg;
{
phseg_list *ptsav;
phseg_list *pttmp;

	for (pttmp = ptfig->PHSEG; pttmp; pttmp = pttmp->NEXT) {
		if (pttmp == ptseg)
			break;
		ptsav = pttmp;
	}

	if (pttmp == NULL)
		return 0;
	else if (ptseg == ptfig->PHSEG)
		ptfig->PHSEG = pttmp->NEXT;
	else
		ptsav->NEXT = pttmp->NEXT;

	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- delphseg  : ");
		(void)fprintf(stdout, "%s \n", ptseg->NAME);
	}

	mbkfree((void *)ptseg);
	return 1;
}

/*******************************************************************************
* fonction delphvia                                                            *
*******************************************************************************/
int delphvia(ptfig, ptvia)
phfig_list *ptfig;
phvia_list *ptvia;
{
phvia_list *ptsav;
phvia_list *pttmp;

	for (pttmp = ptfig->PHVIA; pttmp; pttmp = pttmp->NEXT) {
		if (pttmp == ptvia)
			break;
		ptsav = pttmp;
	}

	if (pttmp == NULL)
		return 0;
	else if (ptvia == ptfig->PHVIA)
		ptfig->PHVIA = pttmp->NEXT;
	else
		ptsav->NEXT = pttmp->NEXT;

	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- delphvia  : ");
		(void)fprintf(stdout, "%ld \n", (long)(ptvia->TYPE));
	}
	mbkfree((void *)ptvia);
	return 1;
}

/*******************************************************************************
* fonction delphref                                                            *
*******************************************************************************/
int delphref(ptfig, ptref)
phfig_list *ptfig;
phref_list *ptref;
{
phref_list *ptsav;
phref_list *pttmp;

	for (pttmp = ptfig->PHREF; pttmp; pttmp = pttmp->NEXT) {
		if (pttmp == ptref)
			break;
		ptsav = pttmp;
	}

	if (pttmp == NULL)
		return 0;
	else if (ptref == ptfig->PHREF)
		ptfig->PHREF = pttmp->NEXT;
	else
		ptsav->NEXT = pttmp->NEXT;

	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- delphref  : ");
		(void)fprintf(stdout, "%s \n", ptref->NAME);
	}
	mbkfree((void *)ptref); 
	return 1;
}

/*******************************************************************************
* fonction delphins                                                            *
*******************************************************************************/
int delphins(ptfig, insname)
phfig_list *ptfig;
char *insname;
{
phins_list *ptsav;
phins_list *ptins;
chain_list *ptchain;
chain_list *pttmpchain;
char *figname;

	insname = namealloc(insname);

	for (ptins = ptfig->PHINS; ptins; ptins = ptins->NEXT) {
		if (ptins->INSNAME == insname)
			break;
		ptsav = ptins;
	}

	if (ptins == NULL)
		return 0;
	else if (ptins == ptfig->PHINS) {
		figname = ptins->FIGNAME;
		ptfig->PHINS = ptins->NEXT;
	} else {
		figname = ptins->FIGNAME;
		ptsav->NEXT = ptins->NEXT;
	}

	mbkfree((void *)ptins);

	for (ptins = ptfig->PHINS; ptins; ptins = ptins->NEXT)
		if (ptins->FIGNAME == figname)
			break;
	if (ptins == NULL)   {
		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 != NULL)
			pttmpchain->NEXT = ptchain->NEXT;
	}
	if (TRACE_MODE == 'Y') {
		(void)fprintf(stdout, "--- mbk --- delphins  : ");
		(void)fprintf(stdout, "%s of figure %s\n", insname, figname);
	}
	return 1;
}
 
/*******************************************************************************
* fonction delphfig                                                            *
*******************************************************************************/
int delphfig(name)
char *name;
{
phfig_list *ptfig;
phcon_list *ptcon;
phseg_list *ptseg;
phvia_list *ptvia;
phins_list *ptins;
phref_list *ptref;
phfig_list *ptfig_sav;
phcon_list *ptcon_sav;
phseg_list *ptseg_sav;
phvia_list *ptvia_sav;
phins_list *ptins_sav;
phref_list *ptref_sav;

	name = namealloc(name);

	for (ptfig = HEAD_PHFIG; ptfig; ptfig = ptfig->NEXT) {
		if (ptfig->NAME == name)
			break;
		ptfig_sav = ptfig;
	}

	if (ptfig == NULL)
		return 0;
	else if (ptfig == HEAD_PHFIG)
		HEAD_PHFIG = ptfig->NEXT;
	else
		ptfig_sav->NEXT = ptfig->NEXT;

	for (ptins = ptfig->PHINS; ptins; ptins = ptins_sav) {
		ptins_sav = ptins->NEXT;
		mbkfree((void *)ptins);
	}
	for (ptseg = ptfig->PHSEG; ptseg; ptseg = ptseg_sav) {
		ptseg_sav = ptseg->NEXT;
		mbkfree((void *)ptseg);
	}
	for (ptref = ptfig->PHREF; ptref; ptref = ptref_sav) {
		ptref_sav = ptref->NEXT;
		mbkfree((void *)ptref);
	}
	for (ptvia = ptfig->PHVIA; ptvia; ptvia = ptvia_sav) {
		ptvia_sav = ptvia->NEXT;
		mbkfree((void *)ptvia);
	}
	for (ptcon = ptfig->PHCON; ptcon; ptcon = ptcon_sav) {
		ptcon_sav = ptcon->NEXT;
		mbkfree((void *)ptcon);
	}

	if (TRACE_MODE == 'Y')
		(void)fprintf(stdout, "--- mbk --- delphfig  : %s\n", name);
	mbkfree((void *)ptfig);
	return 1;
}

/*******************************************************************************
* fonction xyflat                                                              *
*******************************************************************************/
void xyflat(xout, yout, x, y, xins, yins, x1, y1, x2, y2, trsf)
long *xout, *yout;
long x, y;
long xins, yins;
long x1, y1, x2, y2;
char trsf;
{
	switch (trsf) {
		case NOSYM :
			*xout = xins + x - x1;
			*yout = yins + y - y1;
			break;
		case SYM_X :
			*xout = xins - x + x2;
			*yout = yins + y - y1;
			break;
		case SYM_Y :
			*xout = xins + x - x1;
			*yout = yins - y + y2;
			break;
		case SYMXY :
			*xout = xins - x + x2;
			*yout = yins - y + y2;
			break;
		case ROT_P :
			*xout = xins - y + y2;
			*yout = yins + x - x1;
			break;
		case ROT_M :
			*xout = xins + y - y1;
			*yout = yins - x + x2;
			break;
		case SY_RP :
			*xout = xins + y - y1;
			*yout = yins + x - x1;
			break;
		case SY_RM :
			*xout = xins - y + y2;
			*yout = yins - x + x2;
		break;
	}
}

/*******************************************************************************
* fonction viewph	                                                           *
*	                                                                           *
* display on screen the content of all physical figures	                     *
*******************************************************************************/
void viewph()
{
phfig_list	*pt_fig  	= NULL;

	if (HEAD_PHFIG == NULL)
		(void)fprintf(stderr, "\n!!! viewph : empty list of figures !!!\n");
	else {
		for (pt_fig = HEAD_PHFIG; pt_fig; pt_fig = pt_fig->NEXT)
	     	viewphfig(pt_fig);
	}
}

/************************************************************************
*	fonction viewphfig()	                                              *
*	                                                                    *
* display on screen the content of physical figure ptfig	             *
************************************************************************/
void viewphfig(pt_fig)
phfig_list *pt_fig;
{
phcon_list *pt_con = NULL;
phins_list *pt_ins = NULL;
chain_list *pt_chain = NULL;
phseg_list *pt_seg = NULL;
phvia_list *pt_via = NULL;
phref_list *pt_ref = NULL;

	if (!pt_fig)
		return;

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

	(void)printf("	|---abutment box : %ld %ld %ld %ld\n", 
						pt_fig->XAB1, pt_fig->YAB1, pt_fig->XAB2, pt_fig->YAB2);

	if (pt_fig->MODELCHAIN == NULL)
		(void)printf("	|---empty list of instance names\n");
	else {
		(void)printf("	|---models \n");
		for (pt_chain = pt_fig->MODELCHAIN; pt_chain != NULL; pt_chain = pt_chain->NEXT)
			(void)printf("	|      |---%s \n", (char *)pt_chain->DATA);
	}

	if (pt_fig->PHCON == NULL) 
		(void)printf("	|---empty list of connectors\n");		
	else 
		for (pt_con = pt_fig->PHCON; pt_con != NULL; pt_con = pt_con->NEXT)
			viewphcon(pt_con);

	if (pt_fig->PHINS == NULL)
		(void)printf("	|---empty list of instances\n");
	else 
		for (pt_ins = pt_fig->PHINS; pt_ins != NULL; pt_ins = pt_ins->NEXT)
			viewphins(pt_ins);

	if (pt_fig->PHSEG == NULL)
		(void)printf("	|---empty list of segments\n");
	else 
		for (pt_seg = pt_fig->PHSEG; pt_seg != NULL; pt_seg = pt_seg->NEXT)
			viewphseg(pt_seg);

	if (pt_fig->PHVIA == NULL)
		(void)printf("	|---empty list of vias\n");
	else 
		for (pt_via = pt_fig->PHVIA; pt_via != NULL; pt_via = pt_via->NEXT)
			viewphvia(pt_via);

	if (pt_fig->PHREF == NULL)
		(void)printf("	|---empty list of references\n");
	else 
		for (pt_ref = pt_fig->PHREF; pt_ref != NULL; pt_ref = pt_ref->NEXT)
			 viewphref(pt_ref);

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

/******************************************************************************/

void viewphcon(pt_con)
phcon_list	*pt_con; 
{ 
	if (pt_con == NULL) {
		(void)printf("!!! viewphcon : null connector pointer !!!\n");
		return;
	}
	if (pt_con->NAME == NULL)
		(void)printf("	|--- !!! connector without name !!!\n");
	else
		(void)printf("	|---connector : %ld (%s) \n", pt_con->INDEX, pt_con->NAME);

	(void)printf("	|       |---coordinates   : X = %ld, Y = %ld \n",
															pt_con->XCON, pt_con->YCON);
	(void)printf("	|       |---orientation   : %c \n", pt_con->ORIENT);
	(void)printf("	|       |---width         : %ld \n", pt_con->WIDTH);

	(void)printf("	|       |---layer         ");
	switch(pt_con->LAYER) {
		case NWELL :
			(void)printf(": NWELL\n");
			break;
		case PWELL :
			(void)printf(": PWELL\n");
			break;
		case NDIF :
			(void)printf(": NDIF\n");
			break;
		case PDIF :
			(void)printf(": PDIF\n");
			break;
		case NTRANS :
			(void)printf(": NTRANS\n");
			break;
		case PTRANS :
			(void)printf(": PTRANS\n");
			break;
		case POLY :
			(void)printf(": POLY\n");
			break;
		case ALU1 :
			(void)printf(": ALU1\n");
			break;
		case ALU2 :
			(void)printf(": ALU2\n");
			break;
		case ALU3 :
			(void)printf(": ALU3\n");
			break;
		case TPOLY :
			(void)printf(": TPOLY\n");
			break;
		case TALU1 :
			(void)printf(": TALU1\n");
			break;
		case TALU2 :
			(void)printf(": TALU2\n");
			break;
		case TALU3 :
			(void)printf(": TALU3\n");
			break;
		default :
			(void)printf(": unknown\n");
		}
	if (pt_con->USER != NULL)
		(void)printf("	|       |---non empty USER field\n");
	(void)printf("	| \n");
}

/******************************************************************************/
void viewphseg(pt_seg)
phseg_list	*pt_seg;
{ 
	if (pt_seg == NULL) {
		(void)printf("!!! viewphseg : null segment pointer !!!\n");
		return;
	}

	if (pt_seg->NAME == NULL)
		(void)printf("	|--- !!! segment without name !!! \n");
	else
		(void)printf("	|---segment : %s \n", pt_seg->NAME);

	(void)printf("	|       |---type          : %c \n", pt_seg->TYPE);

	(void)printf("	|       |---coordinates   : X1 = %ld, Y1 = %ld, X2 = %ld, Y2 = %ld \n", pt_seg->X1, pt_seg->Y1, pt_seg->X2, pt_seg->Y2);

	(void)printf("	|       |---width         : %ld \n", pt_seg->WIDTH);

	(void)printf("	|       |---layer         ");
	switch(pt_seg->LAYER) {
		case NWELL :
			(void)printf(": NWELL \n");
			break;
		case PWELL :
			(void)printf(": PWELL \n");
			break;
		case NDIF :
			(void)printf(": NDIF \n");
			break;
		case PDIF :
			(void)printf(": PDIF \n");
			break;
		case NTRANS :
			(void)printf(": NTRANS \n");
			break;
		case PTRANS :
			(void)printf(": PTRANS \n");
			break;
		case POLY :
			(void)printf(": POLY \n");
			break;
		case ALU1 :
			(void)printf(": ALU1 \n");
			break;
		case ALU2 :
			(void)printf(": ALU2 \n");
			break;
		case ALU3 :
			(void)printf(": ALU3\n");
			break;
		case TPOLY :
			(void)printf(": TPOLY\n");
			break;
		case TALU1 :
			(void)printf(": TALU1\n");
			break;
		case TALU2 :
			(void)printf(": TALU2\n");
			break;
		case TALU3 :
			(void)printf(": TALU3\n");
			break;
		default :
			(void)printf(": unknown\n");
		}
	if (pt_seg->USER != NULL)
		(void)printf("	|       |---non empty USER field\n");
	(void)printf("	| \n");
}

void viewphvia(pt_via) 
phvia_list *pt_via;
{
	if (pt_via == NULL) {
		(void)printf("!!! viewphvia : null via pointeur !!!\n");
		return;
	}
	(void)printf("	|---via \n");
	(void)printf("	|       |---type       ");
	switch(pt_via->TYPE) {
		case CONT_POLY :
			(void)printf(": CONT_POLY\n");
			break;
		case CONT_VIA :
			(void)printf(": CONT_VIA\n");
			break;
		case CONT_VIA2 :
			(void)printf(": CONT_VIA2\n");
			break;
		case CONT_VIA3 :
			(void)printf(": CONT_VIA3\n");
			break;
		case CONT_DIF_N :
			(void)printf(": CONT_DIF_N\n");
			break;
		case CONT_DIF_P :
			(void)printf(": CONT_DIF_P\n");
			break;
		case CONT_BODY_N :
			(void)printf(": CONT_BODY_N\n");
			break;
		case CONT_BODY_P :
			(void)printf(": CONT_BODY_P\n");
			break;
		case C_X_N :
			(void)printf(": C_X_N\n");
			break;
		case C_X_P :
			(void)printf(": C_X_P\n");
			break;
		default :
			(void)printf(": unknown\n");
	}
	(void)printf("	|       |---coordinates: X = %ld, Y = %ld \n", pt_via->XVIA, pt_via->YVIA);
	if (pt_via->USER != NULL)
		(void)printf("	|       |---non empty USER field\n");
	(void)printf("	| \n");
}

void viewphins(pt_ins)
phins_list *pt_ins;
{ 
	if (pt_ins == NULL) {
		(void)printf("!!! viewphins : null instance pointer !!! \n");
		return;
	}
	if (pt_ins->INSNAME == NULL)
		(void)printf("	|--- !!! instance without name !!! \n");
	else
		(void)printf("	|---instance   : %s \n", pt_ins->INSNAME);

	if (pt_ins->FIGNAME == NULL)
		(void)printf("	|      |--- !!! instance without model !!! \n");
	else
		(void)printf("	|      |---model        : %s \n", pt_ins->FIGNAME);

	(void)printf("	|      |---coordinates  : X = %ld Y = %ld \n",
														pt_ins->XINS, pt_ins->YINS);

	(void)printf("	|      |---operation    \n");
	switch(pt_ins->TRANSF) {
		case NOSYM :
			(void)printf(": NOSYM\n");
			break;
		case ROT_P :
			(void)printf(": ROT_P\n");
			break;
		case SYMXY :
			(void)printf(": SYMXY\n");
			break;
		case ROT_M :
			(void)printf(": ROT_M\n");
			break;
		case SYM_X :
			(void)printf(": SYM_X\n");
			break;
		case SYM_Y :
			(void)printf(": SYM_Y\n");
			break;
		case SY_RP :
			(void)printf(": SY_RP\n");
			break;
		case SY_RM :
			(void)printf(": SY_RM\n");
			break;
		default :
			(void)printf(": unknown\n");
		}

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

void viewphref(pt_ref) 
phref_list *pt_ref;
{
	if (pt_ref == NULL) {
		(void)printf("!!! viewphref : null reference pointer !!!\n");
		return;
	}
	(void)printf("	|---reference \n");
	(void)printf("	|       |---type       : %s\n", pt_ref->FIGNAME);
	(void)printf("	|       |---name       : %s\n", pt_ref->NAME);
	if (pt_ref->USER != NULL)
		(void)printf("	|      |---non empty USER field\n");
	(void)printf("	|\n");
}
