/*******************************************************************************
* mbk     : utilities for logical structures                                   *
*                                                                              *
* version : 4.02                                                              *
* date    : 05/11/92                                                           *
*******************************************************************************/

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include MUT_H
#include MLO_H
#include MLU_H
#include "mbk_lo_util.h"

/*******************************************************************************
* function getlofig()                                                          *
* if mode == 'A'  all the figure is needed                                     *
* if mode != 'A'  interface only is needed                                     *
*******************************************************************************/
lofig_list *getlofig(figname, mode)
char *figname;
char mode;
{
lofig_list *ptfig;

	figname = namealloc(figname);
	/* scan figure list */
	for (ptfig = HEAD_LOFIG; ptfig; ptfig = ptfig->NEXT)
		if (ptfig->NAME == figname)
			break;

	if (ptfig == NULL) { /* figure doesn't exist */
		ptfig = (lofig_list *)mbkalloc(sizeof(lofig_list));
		ptfig->NAME   = figname;
		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 (mode == 'A') {
			ptfig->MODE = 'A';
			loadlofig(ptfig, figname, 'A');
			return ptfig;
		} else {
			ptfig->MODE = 'P';
			loadlofig(ptfig, figname, 'P');
			return ptfig;
		}
	}

	if (ptfig->MODE != 'A') {   /* figure exists interface only */
		if (mode == 'A') {
			ptfig->MODE = 'A';
			loadlofig(ptfig, figname, 'C');
			return ptfig;
		} else
			return ptfig;
	} else           /* figure exists interface and body */
		return ptfig;
}

/*******************************************************************************
* function givelosig()                                                         *
*******************************************************************************/
losig_list *givelosig(ptfig, index)
lofig_list *ptfig;
long index;
{
losig_list *ptsig = NULL;
ptype_list *pt = NULL;
short low;
short type;

	low = (short)(index % SIGSIZE);
	type = (short)(index / SIGSIZE);
	for (pt = ptfig->BKSIG; pt; pt = pt->NEXT)
	if (pt->TYPE == type)
		break;
	if (pt != NULL) {
		ptsig = (losig_list *)(pt->DATA) + low;
		if (ptsig->INDEX == index)
			return ptsig;
	}
	return addlosig(ptfig, index, (chain_list *)NULL, 'I', 0.0);
}

/*******************************************************************************
* function  flattenlofig()                                                     *
*                                                                              *
* the instance "insname" is suppressed as a hierarchical level                 *
* in figure pointed by "ptfig". Capacitances and netlist                       *
* consistency is preserved.                                                    *
*******************************************************************************/
void flattenlofig(ptfig, insname, concat)
lofig_list *ptfig;
char *insname;
char concat;
{
long maxindex = 0;
ptype_list *ptype;
lofig_list *ptnewfig;
losig_list *ptsig;
locon_list *ptcon;
locon_list *ptconext;
loins_list *ptoldins;

	/* retrieving the model of the instance to be flattened */
	ptoldins = getloins(ptfig, insname);
	ptnewfig = rduplofig(getlofig(ptoldins->FIGNAME, 'A'));
	for (ptcon = ptnewfig->LOCON; ptcon; ptcon = ptcon->NEXT)
		maxindex++;
	for (ptcon = ptoldins->LOCON; ptcon; ptcon = ptcon->NEXT)
		maxindex--;
	if (maxindex) {
		fflush(stdout);
		fputs("*** mbk error ***\n", stderr);
		fputs("flattenlofig : connector number inconsistency between model",
				stderr);
		fprintf(stderr, " '%s' and instance '%s'\n",
				ptnewfig->NAME, ptoldins->INSNAME);
		EXIT(1);
	}
  
	/* build the dual representation of netlist */ 
	lofigchain(ptfig);
	lofigchain(ptnewfig);

	/* computes the highest signal index in the root figure */
	for (ptsig = ptfig->LOSIG; ptsig; ptsig = ptsig->NEXT)
		if (ptsig->INDEX > maxindex)
			maxindex = ptsig->INDEX;

	/* scan signal list of the model of the flatenned instance  */
	for (ptsig = ptnewfig->LOSIG; ptsig; ptsig = ptsig->NEXT) {
		ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
		if (ptsig->TYPE == INTERNAL) {  /*  internal signal   */
		chain_list *ptc;
		losig_list *ptnewsig;

			/* build pathnames for all names if needed */
			if (concat != NO)
				for (ptc = ptsig->NAMECHAIN; ptc; ptc = ptc->NEXT)
					ptc->DATA = (void *)concatname(insname, (char *)ptc->DATA);
			/* create a new internal signal */
			ptnewsig = addlosig(ptfig, ++maxindex, ptsig->NAMECHAIN, INTERNAL,
										ptsig->CAPA);
			/* changes the signal on linked connectors */
			for (ptc = (chain_list *)ptype->DATA; ptc; ptc = ptc->NEXT)
				((locon_list *)ptc->DATA)->SIG = ptnewsig;
    	} else { /* external signal */
		chain_list *ptint = NULL;
		chain_list *ptext = NULL;
		locon_list *ptconfirst;
		losig_list *ptsigfirst, *ptsignext;
		ptype_list *ptypenext;
		chain_list *ptc, *ptscan;
			/* build two list : external and internal connectors */
			for (ptc = (chain_list *)ptype->DATA; ptc; ptc = ptc->NEXT) {
				ptcon = (locon_list *)ptc->DATA;
				if (ptcon->TYPE == EXTERNAL)
					ptext = addchain(ptext, (void *)ptcon);
				else
					ptint = addchain(ptint, (void *)ptcon);
			}
  
			/* find connector of the model corresponding to the instance one */
			ptconfirst = (locon_list *)ptext->DATA;
			for (ptcon = ptoldins->LOCON; ptcon; ptcon = ptcon->NEXT) 
				if (ptcon->NAME == ptconfirst->NAME) {
					ptsigfirst = ptcon->SIG;
					break;
				} 
			if (ptcon == (locon_list *)NULL) {
				fputs("*** mbk error ***\n", stderr);
				fprintf(stderr,
						"flattenlofig : interface name inconsistency between model");
				fprintf(stderr,
						" '%s' and instance '%s' on figure connector '%s'\n",
						ptnewfig->NAME, ptoldins->INSNAME, ptconfirst->NAME);
				EXIT(1);
			}
			/* merge other external signal if neccessary   */
			for (ptc = ptext->NEXT; ptc; ptc = ptc->NEXT) {
				ptconext = (locon_list *)ptc->DATA;
				for (ptcon = ptoldins->LOCON; ptcon; ptcon = ptcon->NEXT) {
					if (ptcon->NAME == ptconext->NAME) {
						ptsignext = ptcon->SIG;
						break;
					}
					if (ptcon == (locon_list *)NULL) {
						fputs("*** mbk error ***\n", stderr);
						fprintf(stderr,
						"flattenlofig : interface name inconsistency between model");
						fprintf(stderr,
								" '%s' and instance '%s' on figure connector '%s'\n",
								ptnewfig->NAME, ptoldins->INSNAME, ptconext->NAME);
						EXIT(1);
					}
				}
				if (ptsignext != ptsigfirst) {
					ptypenext = getptype(ptsignext->USER, (long)LOFIGCHAIN);
					for (ptscan = (chain_list *)ptypenext->DATA; ptscan;
							ptscan = ptscan->NEXT)
						((locon_list *)ptscan->DATA)->SIG = ptsigfirst;
					addcapa(ptsigfirst, ptsignext->CAPA);
					freechain((chain_list *)ptypenext->DATA);
					freeptype(ptsignext->USER);
					(void)dellosig(ptfig, ptsignext->INDEX);
				}
			}
  
			/* reconstruct connectivity for the new instances  */
			for (ptc = ptint; ptc; ptc = ptc->NEXT)
				((locon_list *)ptc->DATA)->SIG = ptsigfirst;
			addcapa(ptsigfirst, ptsig->CAPA);
			/* delete the two connectors lists */ 
			freechain(ptint);
			freechain(ptext);
		}
	}
  
	/* append  new instances */
	(void)delloins(ptfig, ptoldins->INSNAME);
	if (concat != NO)
		for (ptoldins = ptnewfig->LOINS; ptoldins; ptoldins = ptoldins->NEXT)
			ptoldins->INSNAME = concatname(insname, ptoldins->INSNAME);

	ptfig->LOINS = (loins_list *)append((chain_list *)ptfig->LOINS, 
													(chain_list *)ptnewfig->LOINS);
	ptfig->LOTRS = (lotrs_list *)append((chain_list *)ptfig->LOTRS, 
													(chain_list *)ptnewfig->LOTRS);
  
	/* house cleaning */
	ptnewfig->LOINS = NULL;
	ptnewfig->LOTRS = NULL;

	/* delete duplicated figure */
	for (ptype = ptnewfig->BKSIG; ptype; ptype = ptype->NEXT)
		mbkfree((void *)ptype->DATA);
	freeptype(ptnewfig->BKSIG);
	for (ptcon = ptnewfig->LOCON; ptcon; ptcon = ptconext) {
		ptconext = ptcon->NEXT;
		mbkfree((void *)ptcon);
	}
	freechain(ptnewfig->MODELCHAIN);
	mbkfree((void *)ptnewfig);

	/* chose a unique name for each signal and free lofigchain space */
	for (ptsig = ptfig->LOSIG; ptsig; ptsig = ptsig->NEXT) {
		if (ptsig->NAMECHAIN != NULL) {
			ptsig->NAMECHAIN = addchain(ptsig->NAMECHAIN,
													(void *)getsigname(ptsig));
			freechain(ptsig->NAMECHAIN->NEXT);
			ptsig->NAMECHAIN->NEXT = (chain_list *)NULL;
		}
		ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
		if (ptype != NULL) {
			freechain((chain_list *)ptype->DATA);
			ptsig->USER = delptype(ptsig->USER, (long)LOFIGCHAIN);
		}
	}
}

/*******************************************************************************
* function loadlofig                                                           *
*******************************************************************************/
void loadlofig(ptfig, name, mode)
lofig_list *ptfig;
char *name;
char mode;
{
	if (TRACE_MODE == 'Y')
		(void)fprintf(stdout,
							"--- mbk --- loadlofig : reading file %s.%s mode %c\n",
							name, IN_LO, mode);
	if ((!strcmp(IN_LO, "hns")) || (!strcmp(IN_LO, "fne"))
			|| (!strcmp(IN_LO, "hdn")) || (!strcmp(IN_LO, "fdn")))
		vtiloadlofig(ptfig, name, mode);
	else if ((!strcmp(IN_LO, "al")) || (!strcmp(IN_LO, "alx")))
		alcloadlofig(ptfig, name, mode);
	else if (!strcmp(IN_LO, "spi"))
		spiceloadlofig(ptfig, name, mode);
	else if (!strcmp(IN_LO, "edi"))
		edifloadlofig(ptfig, name, mode);
	else if (!strcmp(IN_LO, "vst"))
		vhdlloadlofig(ptfig, name, mode);
	else {
		(void)fflush(stdout);
		(void)fprintf(stderr, "*** mbk error ***\n");
		(void)fprintf(stderr, "MBK_IN_LO : '%s' unknown format\n", IN_LO);
		EXIT(1);
	}
	if (TRACE_MODE == 'Y')
		(void)fprintf(stdout,
							"--- mbk --- loadlofig : done reading file %s.%s\n",
							name, IN_LO);
}

/*******************************************************************************
* function savelofig                                                           *
*******************************************************************************/
void savelofig(ptfig)
lofig_list *ptfig;
{
	if ((!strcmp(OUT_LO, "hns")) || (!strcmp(OUT_LO, "fne"))
			|| (!strcmp(OUT_LO, "hdn")) || (!strcmp(OUT_LO, "fdn")))
		vtisavelofig(ptfig);
	else if ((!strcmp(OUT_LO, "al")) || (!strcmp(OUT_LO, "alx")))
		alcsavelofig(ptfig);
	else if (!strcmp(OUT_LO, "spi"))
		spicesavelofig(ptfig);
	else if (!strcmp(OUT_LO, "edi"))
		edifsavelofig(ptfig);
	else if (!strcmp(OUT_LO, "vst"))
		vhdlsavelofig(ptfig);
	else if (!strcmp(OUT_LO, "cct"))
		hilosavelofig(ptfig);
	else {
		(void)fflush(stdout);
		(void)fprintf(stderr, "*** mbk error ***\n");
		(void)fprintf(stderr, "MBK_OUT_LO : %s unknown format\n", OUT_LO);
		EXIT(1);
	}
}

/*******************************************************************************
* function rflattenlofig()                                                     *
* flatten recursif sur une figure logique ptfig.                               *
* concat permet de generer les cheminons (concat != 'N')                       *
* la mise a plat s'effectue jusqu'au cellules du catalogue                     *
* non comprises.                                                               *
* catal = `y` ou catal=`Y` indique qu`il faut tenir compte du                  *
* catalogue. Une autre valeur implique un flatten complet.                     *
*******************************************************************************/
void rflattenlofig(ptfig, concat, catal)
lofig_list *ptfig;
char concat, catal;
{
loins_list *p;
chain_list *c;

	catal = catal == NO ? 0 : 1;
	for (p = ptfig->LOINS; p != NULL;) { 
		if (!catal || !incatalog(p->FIGNAME) || incatalogdelete(p->FIGNAME)) {
			flattenlofig(ptfig, p->INSNAME, concat);
			p = ptfig->LOINS;
		}
		else
			p = p->NEXT;
	}
	freechain(ptfig->MODELCHAIN);
	ptfig->MODELCHAIN = NULL;
	p = ptfig->LOINS;
	while (p != NULL) {
		c = ptfig->MODELCHAIN;
		while (c != NULL) {
			if ((char *)c->DATA == p->FIGNAME)
				break;
			c = c->NEXT;
		}
		if (c == NULL)
			ptfig->MODELCHAIN = addchain(ptfig->MODELCHAIN, (void *)p->FIGNAME);
		p = p->NEXT;
	} 
}

/*
UNFLATLOFIG

II. Algorithme
--------------

1. On fait un LOFIGCHAIN sur 'ptfig'.

2. On veut construire deux 'chain_list' :
   LI : signaux internes a la nouvelle figure
   LX : signaux externes a la nouvelle figure

   Pour la figure 'ptfig', on parcourt la liste des signaux :
      Pour chaque signal, on parcourt la liste des connecteurs qui lui
      sont associes (par LOFIGCHAIN):
        * Si AUCUN connecteur n'appartient a une instance presente dans
          la liste 'list', on passe au signal suivant (pas d'insertion)

        * Sinon, si TOUS les connecteurs appartiennent a une instance
          presente dans la liste 'list', le signal est insere dans la
          liste LI
        * Sinon, le signal est insere dans la liste LX
          (au moins un connecteur n'appartient pas a la nouvelle figure)

3. On construit la nouvelle figure. Il faut creer :
   - une liste des signaux
   - une liste des connecteurs externes
   - une liste des instances, chacune contenant une liste de connecteurs

 a. liste des signaux
    on parcourt la liste LI et la liste LX : on ajoute chaque signal a
    la liste des signaux de la nouvelle figure.
    On construit une structure ptype (de nom UNFLATLOFIG), donnant a
    chaque signal de LI ou LX un pointeur vers le signal cree dans la
    nouvelle figure.

 b. liste des connecteurs externes
    on parcourt la liste LX :
    pour chaque signal, on cherche le premier connecteur interne (a la
    nouvelle figure) et le premier connecteur externe (a la nouvelle
    figure), de preference un terminal de la figure pere: s'il en
    existe un (terminal) on prend celui-la, sinon on prend le
    premier externe a la nouvelle figure, mais non terminal dans
    la figure pere.
    On ajoute un connecteur externe a la nouvelle figure. Il pointe
    sur le signal courant (dans la nouvelle). Sa direction est:
    - si le connecteur n'appartenant pas a la nouvelle figure est
      un terminal du pere (externe), le nouveau connecteur prend la
      direction de ce terminal.
    - si le connecteur n'appartenant pas a la nouvelle figure est un
      connecteur d'instance, le nouveau connecteur prend la direction
      du premier connecteur INTERNE a la nouvelle figure trouve 
      precedemment. 
    Le nom du nouveau connecteur est:
    - le nom du signal auquel il est connecte si ce dernier en a un.
    - sinon :
      . si le premier connecteur n'appartenant pas a la nouvelle
        figure est un terminal, le nouveau prend ce nom,
      . si le premier connecteur n'appartenant pas a la nouvelle
        figure est un connecteur d'instance, le nouveau prend le
        nom du connecteur INTERNE a la nouvelle figure (comme pour
        la direction).
    Dans tous les cas, on concatene au nom un compteur (comptant le
    nombre de connecteurs externes crees) pour assurer l'unicite.

 c. liste des instances
    on parcourt la liste 'list' :
    on insere chaque instance dans la liste d'instances de la nouvelle
    figure. Pour chaque connecteur d'une instance de 'list', on
    ajoute un connecteur dans la liste des connecteurs de l'instance
    dans la nouvelle figure, dont le signal dans la nouvelle figure est
    obtenu en consultant la structure ptype du signal dans la figure pere.
    Les connecteurs prennent les directions des connecteurs dans les
    instances de la figure pere.

4. On modifie la figure pere.
    On instancie la nouvelle figure.
    On detruit les signaux internes (LI).
    On detruit les instances de la liste 'list'.
*/
/*******************************************************************************
* function unflattenlofig                                                      *
*******************************************************************************/
lofig_list *unflattenlofig(ptfig, figname, insname, list)
lofig_list *ptfig;
char	*figname;
char	*insname;
chain_list *list;
{
lofig_list *newlofig = NULL;
chain_list *li_head = NULL, *lx_head = NULL, *ptchain;
losig_list *ptsig;
unsigned long int	newtermcount = 0;

	if (ptfig == NULL) 
		return NULL;
	lofigchain(ptfig);
	/* scan signals:
	   construct LI and LX. */
	for (ptsig = ptfig->LOSIG; ptsig != NULL; ptsig = ptsig->NEXT) {
	chain_list *loconchain;
	int found_int = 0, found_ext = 0;
		/* scan connectors of signal */
		for (loconchain =
				(chain_list * )((getptype (ptsig->USER, (long)LOFIGCHAIN))->DATA);
				loconchain != NULL; loconchain = loconchain->NEXT) {
		locon_list *ptcon;
		chain_list *loinschain;
			ptcon = (locon_list * )(loconchain->DATA);
			for (loinschain = list; loinschain != NULL;
					loinschain = loinschain->NEXT)
				if ((void *)(loinschain->DATA) == ptcon->ROOT) 
					break;
			if (loinschain == NULL) 
				found_ext ++; 
			else 
				found_int ++;
		}
		if (found_int == 0) 
			continue; /* no insertion */
		if (found_ext == 0) 
			li_head = addchain(li_head, (void *)(ptsig)); /* insert LI */
		else 
			lx_head = addchain(lx_head, (void *)(ptsig)); /* insert LX */
	} /* endfor ptsig */

	/***** add new figure : */
	/* create signals list */
	newlofig = addlofig(figname);
	for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT) {
		losig_list * ptlosig;
		ptype_list * ptype;
		chain_list * namechain = NULL, *ptaux;

		ptlosig = (losig_list *)(ptchain->DATA);
		for (ptaux = ptlosig->NAMECHAIN; ptaux != NULL; ptaux =
			 ptaux->NEXT)
			namechain = addchain(namechain, ptaux->DATA);
		newlofig->LOSIG = addlosig(newlofig, ptlosig->INDEX, namechain,
														 INTERNAL, ptlosig->CAPA);
		ptlosig->USER = addptype(ptlosig->USER, (long)UNFLATLOFIG,
			  (void * )NULL);
		ptype = getptype(ptlosig->USER, (long)UNFLATLOFIG);
		ptype->DATA = (void *)addchain((chain_list * )ptype->DATA,
			  (void *)(newlofig->LOSIG));
	}
	for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
	losig_list *ptlosig;
	ptype_list *ptype;
	chain_list *namechain = NULL, *ptaux;

		ptlosig = (losig_list *)(ptchain->DATA);
		for (ptaux = ptlosig->NAMECHAIN; ptaux != NULL; ptaux =
			 ptaux->NEXT)
			namechain = addchain(namechain, ptaux->DATA);
		newlofig->LOSIG = addlosig(newlofig, ptlosig->INDEX, namechain,
														 EXTERNAL, ptlosig->CAPA);
		ptlosig->USER = addptype(ptlosig->USER, (long)UNFLATLOFIG,
			  (void * )NULL);
		ptype = getptype (ptlosig->USER, (long)UNFLATLOFIG);
		ptype->DATA = (void *)addchain((chain_list *)ptype->DATA,
			  (void *)(newlofig->LOSIG));
	}

	/* create terminals list */
	for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
	locon_list *intlocon = NULL, *extlocon = NULL;
	losig_list *ptlosig, *newlosig;
	ptype_list *ptype;
	chain_list *loconchain, *auxchain;
	static char	loconname[BUFSIZE];
	char	*name; 
	char	locondir; 
	int	i, foundterm = 0;

		/* scan connectors list of the current signal */
		ptlosig = (losig_list *)(ptchain->DATA);
		for (loconchain =
				(chain_list *)((getptype (ptlosig->USER, (long)LOFIGCHAIN))->DATA);
				loconchain != NULL; loconchain = loconchain->NEXT) {
		locon_list *ptlocon;
		chain_list *loinschain;

			ptlocon = (locon_list *)(loconchain->DATA);
			for (loinschain = list; loinschain != NULL; loinschain =
				 loinschain->NEXT)
				if ((void *)(loinschain->DATA) == ptlocon->ROOT) 
					break;
			if (loinschain == NULL) { /* external connector of new figure */
				if (ptlocon->TYPE == EXTERNAL) /* external con. in root figure too */ { 
					foundterm++; 
					extlocon = ptlocon; 
				} else if (extlocon == NULL) 
					extlocon = ptlocon;
			} else if (intlocon == NULL) 
				intlocon = ptlocon; /* internal con. in new */
		} /* endfor loconchain */

		/* create new external connector for the new figure */
		locondir = foundterm ? extlocon->DIRECTION : intlocon->DIRECTION;
		name = (ptlosig->NAMECHAIN != NULL) ?  getsigname(ptlosig) :
			 foundterm ? extlocon->NAME : intlocon->NAME;
		i = 0;
		while ( (name[i] != '\0') && (name[i] != ' ') ) { 
			loconname [i] = name[i]; 
			i++; 
		}
		loconname[i] = '\0';
      /* the format used to be %s%lu%s but it generates vectors with a
         unique base name. 
			sprintf(loconname, "%s%lu%s", loconname, newtermcount++, &(name[i]));
         Since the interface of the resulting figure is not supposed to be
         used by humans, let's make simple names.
         Hey Hey, this was true a while ago, but as always, now we want
         humans to predict the ouput of the function. Fun, ain'it? */
		sprintf(loconname, "%s_%lu", loconname, newtermcount++);
		ptype = getptype(ptlosig->USER, (long)UNFLATLOFIG);
		auxchain = (chain_list *)(ptype->DATA);
		newlosig = (losig_list *)(auxchain->DATA);
		newlofig->LOCON = addlocon(newlofig, loconname, newlosig, locondir);
	} /* endfor ptchain */


	/* create instances list */
	for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT) {
		loins_list *ptloins;
		locon_list *ptlocon, *ptaux;
		chain_list *signal = NULL;

		ptloins = (loins_list *)(ptchain->DATA);
		for (ptlocon = ptloins->LOCON; ptlocon != NULL; ptlocon = ptlocon->NEXT) {
			chain_list *sigchain;
			sigchain = (chain_list *)((getptype(ptlocon->SIG->USER,
														 (long)UNFLATLOFIG))->DATA);
			signal = addchain(signal, (void *)(sigchain->DATA));
		}
		signal = reverse(signal);
		newlofig->LOINS = addloins(newlofig, ptloins->INSNAME,
											 getlofig(ptloins->FIGNAME, 'A'), signal);
		for (ptlocon = newlofig->LOINS->LOCON, ptaux = ptloins->LOCON;
			 (ptlocon != NULL) && (ptaux != NULL);  ptlocon = ptlocon->NEXT,
			  ptaux = ptaux->NEXT)
			ptlocon->DIRECTION = ptaux->DIRECTION;
	}

	/***** free ptype lists (lofigchain and unflatlofig) */
	/* free lofigchain */
	for (ptsig = ptfig->LOSIG; ptsig != NULL; ptsig = ptsig->NEXT) {
	ptype_list *ptype;

		ptype = getptype(ptsig->USER, (long)LOFIGCHAIN);
		freechain ((chain_list *)ptype->DATA);
		ptype->DATA = (void *)NULL;
		ptsig->USER = delptype(ptsig->USER, (long)LOFIGCHAIN);
	}

	/* free unflatlofig in lx signals */
	for (ptchain = lx_head; ptchain != NULL; ptchain = ptchain->NEXT) {
	ptype_list *ptype;
	losig_list *ptlosig;

		ptlosig = (losig_list *)(ptchain->DATA);
		ptype = getptype(ptlosig->USER, (long)UNFLATLOFIG);
		freechain ((chain_list *)ptype->DATA);
		ptype->DATA = (void *)NULL;
		ptlosig->USER = delptype(ptlosig->USER, (long)UNFLATLOFIG);
	}

	/* free unflatlofig in li signals */
	for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT) {
	ptype_list *ptype;
	losig_list *ptlosig;

		ptlosig = (losig_list *)(ptchain->DATA);
		ptype = getptype (ptlosig->USER, (long)UNFLATLOFIG);
		freechain ((chain_list *)ptype->DATA);
		ptype->DATA = (void *)NULL;
		ptlosig->USER = delptype(ptlosig->USER, (long)UNFLATLOFIG);
	}

	/***** modify the root figure :*/
	/* add new instancied figure */
	lx_head = reverse (lx_head);
	ptfig->LOINS = addloins(ptfig, insname, getlofig(figname, 'A'), lx_head);

	/* delete signals */
	for (ptchain = li_head; ptchain != NULL; ptchain = ptchain->NEXT)
		dellosig(ptfig, ((losig_list *)(ptchain->DATA))->INDEX);

	/* delete instances */
	for (ptchain = list; ptchain != NULL; ptchain = ptchain->NEXT)
		delloins(ptfig, ((loins_list *)(ptchain->DATA))->INSNAME);
	return newlofig;
}

#define OK      1
#define PROBLEM 0
#define NOVBE  -1

int restoredirvbe(lof)
lofig_list *lof;
{
FILE *f = NULL;
char line[BUFSIZ];
int p, q, r, from, to, inc, nbcon;
int run = 0; /* shall we interpret what we read? */
char string[128], hook[128];
locon_list * fc, *fct;
char dir;

	if (!lof) {
		fprintf(stderr, "*** mbk error *** restoredirvbe : no figure given\n");
		return PROBLEM;
	}

	if ((f = mbkfopen(lof->NAME, "vbe", "r")) == NULL)
		if ((f = mbkfopen(lof->NAME, "vst", "r")) == NULL)
			return NOVBE;
	lof->LOCON = (locon_list * )reverse((chain_list * )lof->LOCON);
	nbcon = 0;

	while (1) {
		if (fgets(line, BUFSIZ, f) == NULL)
			break;
		for (p = 0; p < BUFSIZ && line[p] && line[p] != '\n'; p++)
			if (isupper(line[p]))
				line[p] = tolower(line[p]);
		p = 0;
		while (isspace(line[p]))
			p++;

		switch (line[p]) {
		case 'e': /* either entity or end for us */
			if (!strncmp("entity", &line[p], 6)) /* we shall treat now */
				run = 1;
			if (!strncmp("end", &line[p], 3)) /* we shall exit gracefully */ {
				fclose(f);
				for (p = 0, fct = lof->LOCON; fct; fct = fct->NEXT)
					p++;
				if (p != nbcon) {
					fprintf(stderr, "*** mbk error *** restoredirvbe : figure %s have more connectors than vbe\n",
					     lof->NAME);
					return PROBLEM;
				}
				return OK;
			}
			continue; /* next line guys */
		case 'p': /* port or nothing! */
			if (!run)
				continue;
			if (!strncmp("port", &line[p], 4)) {
				p += 4;
				while (isspace(line[p])) {
					if (line[p] == '\n') {
						fgets(line, BUFSIZ, f);
						p = 0;
					} else
						p++;
				}
				if (line[p] != '(') {
					fprintf(stderr, "*** mbk error *** restoredirvbe : cannot read port well!\n");
					fclose(f);
					return PROBLEM;
				}

				while (1) {
					fgets(line, BUFSIZ, f);
					for (p = 0; p < BUFSIZ || line[p]; p++)
						if (isupper(line[p]))
							line[p] = tolower(line[p]);
					p = 0;
					while (isspace(line[p]))
						p++;
					if (line[p] == ')')
						break;
					q = p;
					while (!isspace(line[p]) && line[p] != ':')
						p++;
					strncpy(hook, &line[q], p - q);
					hook[p - q] = '\0';

					while (isspace(line[p]) || line[p] == ':')
						p++;
					q = p;
					while (!isspace(line[p]))
						p++;
					strncpy(string, &line[q], p - q);
					string[p - q] = '\0';
					while (isspace(line[p]))
						p++;
					if (line[p] == 'b' || line[p] == 'r') /* finished, dir ok */ {
						if (!strcmp("in", string))
							dir = IN;
						else if (!strcmp("out", string))
							dir = OUT;
						else
							dir = UNKNOWN;
					} else {
						if (!strcmp("inout", string))
							dir = TRANSCV;
						else if (!strcmp("out", string))
							dir = TRISTATE;
						else
							dir = UNKNOWN;
					}
					while (line[p] != '(' && line[p] != '\0')
						p++;
					if (line[p] == '\0') {
						fc = getlocon(lof, hook);
						fc->DIRECTION = dir;
						if (lof->LOCON != fc) {
							for (fct = lof->LOCON; fct->NEXT != fc; fct = fct->NEXT);
							fct->NEXT = fc->NEXT;
							fc->NEXT = lof->LOCON;
							lof->LOCON = fc;
						}
						nbcon++;
					} else { /* bit vector indeed */
						p++; /* skip ( */
						from = atoi(&line[p]);
						while (isdigit(line[p]))
							p++;
						while (isspace(line[p]))
							p++;
						if (line[p] == 'd')
							inc = -1;
						else if (line[p] == 't')
							inc = 1;
						else
						 {
							fprintf(stderr, "*** mbk error *** restoredirvbe : bit_vect neither to nor downto\n");
							fclose(f);
							return PROBLEM;
						}
						while (!isspace(line[p]))
							p++;
						to = atoi(&line[p]);

						for (r = from; r <= to; r += inc) {
							sprintf(string, "%s %d", hook, r);
							fc = getlocon(lof, string);
							fc->DIRECTION = dir;
							if (lof->LOCON != fc) {
								for (fct = lof->LOCON; fct->NEXT != fc; fct = fct->NEXT);
								fct->NEXT = fc->NEXT;
								fc->NEXT = lof->LOCON;
								lof->LOCON = fc;
							}
							nbcon++;
						}
					}
					continue;
				}
			}
			continue;
		default :
			continue;
		}
	}
	fclose(f);
	for (p = 0, fct = lof->LOCON; fct; fct = fct->NEXT)
		p++;
	if (p != nbcon) {
		fprintf(stderr, "*** mbk error *** restoredirvbe : figure %s have more connectors than vbe\n", lof->NAME);
		return PROBLEM;
	}
	return OK;
}

int guessextdir(lof)
lofig_list *lof;
{
int ret = OK;
char dir;
locon_list *ec;
chain_list *pch;
ptype_list *getptype();

	lofigchain(lof);
	for (ec = lof->LOCON; ec; ec = ec->NEXT) {
		dir = UNKNOWN;
		for (pch = (chain_list * )(getptype(ec->SIG->USER, (long)LOFIGCHAIN)->DATA);				pch; pch = pch->NEXT) {
			if (((locon_list * )(pch->DATA))->TYPE != INTERNAL)
				continue;
			switch (((locon_list * )(pch->DATA))->DIRECTION) {
			case IN :
				switch (dir) {
				case IN :
					dir = IN;
					break;
				case OUT :
					dir = INOUT;
					break;
				case INOUT :
					dir = INOUT;
					break;
				case UNKNOWN :
					dir = IN;
					break;
				case TRISTATE :
					dir = TRANSCV;
					break;
				case TRANSCV :
					dir = TRANSCV;
					break;
				}
				break;
			case OUT :
				switch (dir) {
				case IN :
					dir = INOUT;
					break;
				case OUT :
					dir = OUT;
					fprintf(stderr, "Warning : signal %s have two OUT",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case INOUT :
					dir = INOUT;
					fprintf(stderr, "Warning : signal %s have an OUT and an INOUT",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case UNKNOWN :
					dir = OUT;
					break;
				case TRISTATE :
					dir = OUT;
					fprintf(stderr, "Warning : signal %s have an OUT and a TRISTATE",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case TRANSCV :
					dir = TRANSCV;
					fprintf(stderr, "Warning : signal %s have an OUT and a TRANSCV",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				}
				break;
			case INOUT :
				switch (dir) {
				case IN :
					dir = INOUT;
					break;
				case OUT :
					dir = INOUT;
					fprintf(stderr, "Warning : signal %s have an INOUT and an OUT",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case INOUT :
					dir = INOUT;
					fprintf(stderr, "Warning : signal %s have two INOUT",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case UNKNOWN :
					dir = INOUT;
					break;
				case TRISTATE :
					dir = INOUT;
					fprintf(stderr, "Warning : signal %s have an INOUT and a TRISTATE",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case TRANSCV :
					dir = INOUT;
					fprintf(stderr, "Warning : signal %s have an INOUT and a TRANSCV",
								getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				}
				break;
			case UNKNOWN :
				switch (dir) {
				case IN :
					dir = IN;
					break;
				case OUT :
					dir = OUT;
					break;
				case INOUT :
					dir = INOUT;
					break;
				case UNKNOWN :
					dir = UNKNOWN;
					break;
				case TRISTATE :
					dir = TRISTATE;
					break;
				case TRANSCV :
					dir = TRANSCV;
					break;
				}
				break;
			case TRISTATE :
				switch (dir) {
				case IN :
					dir = TRANSCV;
					break;
				case OUT :
					dir = OUT;
					fprintf(stderr, "Warning : signal %s have a TRISTATE and an OUT", getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case INOUT :
					dir = INOUT;
					fprintf(stderr, "Warning : signal %s have a TRISTATE and an INOUT", getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case UNKNOWN :
					dir = TRISTATE;
					break;
				case TRISTATE :
					dir = TRISTATE;
					break;
				case TRANSCV :
					dir = TRANSCV;
					break;
				}
				break;
			case TRANSCV :
				switch (dir) {
				case IN :
					dir = TRANSCV;
					break;
				case OUT :
					dir = TRANSCV;
					fprintf(stderr, "Warning : signal %s have a TRANSCV and an OUT", getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case INOUT :
					dir = INOUT;
					fprintf(stderr, "Warning : signal %s have a TRANSCV and an INOUT", getsigname(ec->SIG));
					ret = PROBLEM;
					break;
				case UNKNOWN :
					dir = TRANSCV;
					break;
				case TRISTATE :
					dir = TRANSCV;
					break;
				case TRANSCV :
					dir = TRANSCV;
					break;
				}
				break;
			}
		}
		if (dir != UNKNOWN)
			ec->DIRECTION = dir;
	}
	return ret;
}

int restorealldir(lf)
lofig_list *lf;
{
int ret = OK, res;
lofig_list *lof;
loins_list *li;
locon_list *ic, *fc;

	for (li = lf->LOINS; li; li = li->NEXT) {
		/* get model of the instance and restore connector direction in it */
		for (lof = HEAD_LOFIG; lof; lof = lof->NEXT)
			if (lof->NAME == li->FIGNAME)
				break;
		if (!lof) {
			lof = getlofig(li->FIGNAME, 'P');
			res = restoredirvbe(lof);
			if (res == PROBLEM)
				ret = PROBLEM;
			else if (res == NOVBE) {
				lof = getlofig(lof->NAME, 'A');
				res = restorealldir(lof);
				if (res == PROBLEM)
					ret = PROBLEM;
				res = guessextdir(lof);
				if (res == PROBLEM)
					ret = PROBLEM;
			}
		} else if (lof->LOCON->DIRECTION == UNKNOWN) {
			res = restoredirvbe(lof);
			if (res == PROBLEM)
				ret = PROBLEM;
			else if (res == NOVBE) {
				if (lof->MODE != 'A')
					lof = getlofig(lof->NAME, 'A');
				res = restorealldir(lof);
				if (res == PROBLEM)
					ret = PROBLEM;
				res = guessextdir(lof);
				if (res == PROBLEM)
					ret = PROBLEM;
			}
		}

		/* restore connector direction in the instance */
		for (ic = li->LOCON; ic; ic = ic->NEXT) {
			fc = getlocon(lof, ic->NAME);
			ic->DIRECTION = fc->DIRECTION;
		}
	}
	return ret;
}

struct typoin				/* structure used by dast_dbg	*/
  {					/* to store its state		*/
  short  type;				/* code of the current structure*/
  short  mark;				/* stop mark			*/
  void  *data;				/* pointer of the structure	*/
  };

#define VHD_ERRDFN  -1
#define VHD__XTDFN  0
#define VHD__UPDFN  1
#define VHD__TPDFN  2
#define VHD__SPDFN  3
#define VHD__BKDFN  4

#define VHD_lofigDFN 5
#define VHD_nextDFN 6
#define VHD_modelchainDFN 7
#define VHD_loconDFN 8
#define VHD_losigDFN 9
#define VHD_bksigDFN 10
#define VHD_loinsDFN 11
#define VHD_lotrsDFN 13
#define VHD_nameDFN 14
#define VHD_modeDFN 15
#define VHD_userDFN 16
#define VHD_drainDFN 17
#define VHD_gridDFN 18
#define VHD_sourceDFN 19
#define VHD_widthDFN 20
#define VHD_lengthDFN 21
#define VHD_xDFN 22
#define VHD_yDFN 23
#define VHD_typeDFN 24
#define VHD_insnameDFN 25
#define VHD_fignameDFN 26
#define VHD_sigDFN 27
#define VHD_rootDFN 28
#define VHD_directionDFN 29
#define VHD_valDFN 30
#define VHD_namechainDFN 31
#define VHD_capaDFN 32
#define VHD_indexDFN 33
#define VHD_ptypeDFN 34
#define VHD_dataDFN 35

#define VHD_MAXDFN 36
static int vhd_getcmd();
static int vhd_hash();

void mlodebug (head_pnt,stru_name)

void  *head_pnt;
char  *stru_name;

  {

  int		 i;
  int		 state;
  int		 newsta0;
  int		 readcmd = 0;
  char		 readtab[3][20];
  int		 stk_pnt = 0;
  int            type = VHD__XTDFN;
  struct chain  *ptchain;

  struct typoin  current_pnt;
  struct typoin  stk[200];

  char           empty[4];
  char           avail[12];

  int		 key[VHD_MAXDFN];
  char		*tab[VHD_MAXDFN];
  void		*nxt[VHD_MAXDFN];
  short		 typ[VHD_MAXDFN];

  struct lofig *lofig_pnt;
  struct locon *locon_pnt;
  struct losig *losig_pnt;
  struct ptype *ptype_pnt;
  struct loins *loins_pnt;
  struct lotrs *lotrs_pnt;

key[VHD_lofigDFN]      = vhd_hash ("lofig");
key[VHD_nextDFN]       = vhd_hash ("next");
key[VHD_modelchainDFN] = vhd_hash ("modelchain");
key[VHD_loconDFN]      = vhd_hash ("locon");
key[VHD_losigDFN]      = vhd_hash ("losig");
key[VHD_bksigDFN]      = vhd_hash ("bksig");
key[VHD_loinsDFN]      = vhd_hash ("loins");
key[VHD_lotrsDFN]      = vhd_hash ("lotrs");
key[VHD_nameDFN]       = vhd_hash ("name");
key[VHD_modeDFN]       = vhd_hash ("mode");
key[VHD_userDFN]       = vhd_hash ("user");
key[VHD_drainDFN]      = vhd_hash ("drain");
key[VHD_gridDFN]       = vhd_hash ("grid");
key[VHD_sourceDFN]     = vhd_hash ("source");
key[VHD_widthDFN]      = vhd_hash ("width");
key[VHD_lengthDFN]     = vhd_hash ("length");
key[VHD_xDFN]          = vhd_hash ("x");
key[VHD_yDFN]          = vhd_hash ("y");
key[VHD_typeDFN]       = vhd_hash ("type");
key[VHD_insnameDFN]    = vhd_hash ("insname");
key[VHD_fignameDFN]    = vhd_hash ("figname");
key[VHD_sigDFN]        = vhd_hash ("sig");
key[VHD_rootDFN]       = vhd_hash ("root");
key[VHD_directionDFN]  = vhd_hash ("direction");
key[VHD_valDFN]        = vhd_hash ("val");
key[VHD_namechainDFN]  = vhd_hash ("namechain");
key[VHD_capaDFN]       = vhd_hash ("capa");
key[VHD_indexDFN]      = vhd_hash ("index");
key[VHD_ptypeDFN]      = vhd_hash ("ptype");

	/* ###------------------------------------------------------### */
	/*    Set of predefined commands				*/
	/* ###------------------------------------------------------### */

  key[0] = vhd_hash ("_exit");
  key[1] = vhd_hash ("_up");
  key[2] = vhd_hash ("_top");
  key[3] = vhd_hash ("_stop");
  key[4] = vhd_hash ("_back");

  (void)strcpy (empty,"");
  (void)strcpy (avail,"AVAILABLE");

  for (i=0 ; i<VHD_MAXDFN ; i++)
    typ[i] = i;

	/* ###------------------------------------------------------### */
	/*    Find the type of the head structure			*/
	/* ###------------------------------------------------------### */

  readcmd = vhd_hash (stru_name);
  for (i=0 ; i<VHD_MAXDFN ; i++)
    {
    if (readcmd == key[i])
      {
      type = typ[i];
      break;
      }
    }

	/* ###------------------------------------------------------### */
	/*    Exit if the head structure is empty			*/
	/* ###------------------------------------------------------### */

  if (head_pnt == NULL)
    type = VHD__XTDFN;

  current_pnt.data = head_pnt;
  current_pnt.type = type;

  state            = type;

  while (state != VHD__XTDFN)
    {
	/* ###------------------------------------------------------### */
	/*    Print structure's field until the exit command is read	*/
	/* ###------------------------------------------------------### */

    for (i=0 ; i<VHD_MAXDFN ; i++)
      {
      tab[i] = empty;
      nxt[i] = NULL;
      }

	/* ###------------------------------------------------------### */
	/*    _exit and _stop commands are allways available		*/
	/* ###------------------------------------------------------### */

    tab[VHD__XTDFN] = avail;
    tab[VHD__SPDFN] = avail;

	/* ###------------------------------------------------------### */
	/*    _up, _top, and _back commands are available only if the	*/
	/* stack is not empty						*/
	/* ###------------------------------------------------------### */

    if (stk_pnt != 0)
      {
      tab[VHD__UPDFN] = avail;
      tab[VHD__TPDFN] = avail;
      tab[VHD__BKDFN] = avail;
      }

    switch (state)
      {

    case (VHD_lofigDFN):

		/* ###--------- lofig ---------### */

      lofig_pnt = (struct lofig *)(current_pnt.data);

      if (lofig_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)lofig_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_lofigDFN;
        }
      if (lofig_pnt->LOCON != NULL)
        {
        tab[VHD_loconDFN] = avail;
        nxt[VHD_loconDFN] = (void *)lofig_pnt->LOCON;
        typ[VHD_loconDFN] = VHD_loconDFN;
        }
      if (lofig_pnt->LOSIG != NULL)
        {
        tab[VHD_losigDFN] = avail;
        nxt[VHD_losigDFN] = (void *)lofig_pnt->LOSIG;
        typ[VHD_losigDFN] = VHD_losigDFN;
        }
      if (lofig_pnt->BKSIG != NULL)
        {
        tab[VHD_bksigDFN] = avail;
        nxt[VHD_bksigDFN] = (void *)lofig_pnt->BKSIG;
        typ[VHD_bksigDFN] = VHD_ptypeDFN;
        }
      if (lofig_pnt->LOINS != NULL)
        {
        tab[VHD_loinsDFN] = avail;
        nxt[VHD_loinsDFN] = (void *)lofig_pnt->LOINS;
        typ[VHD_loinsDFN] = VHD_loinsDFN;
        }
      if (lofig_pnt->LOTRS != NULL)
        {
        tab[VHD_lotrsDFN] = avail;
        nxt[VHD_lotrsDFN] = (void *)lofig_pnt->LOTRS;
        typ[VHD_lotrsDFN] = VHD_lotrsDFN;
        }
      if (lofig_pnt->USER != NULL)
        {
        tab[VHD_userDFN] = avail;
        nxt[VHD_userDFN] = (void *)lofig_pnt->USER;
        typ[VHD_userDFN] = VHD_ptypeDFN;
        }

      ptchain = lofig_pnt->MODELCHAIN;
      (void)printf ("   modelchain  :\n");
      while (ptchain != NULL)
        {
        (void)printf ("                 %s\n",(char *)ptchain->DATA);
        ptchain = ptchain->NEXT;
        }

      (void)printf ("   name        : %s\n",lofig_pnt->NAME);
      (void)printf ("   mode        : %c\n",lofig_pnt->MODE);
      (void)printf ("-> locon       : %s\n",tab[VHD_loconDFN]);
      (void)printf ("-> losig       : %s\n",tab[VHD_losigDFN]);
      (void)printf ("-> bksig       : %s\n",tab[VHD_bksigDFN]);
      (void)printf ("-> loins       : %s\n",tab[VHD_loinsDFN]);
      (void)printf ("-> lotrs       : %s\n",tab[VHD_lotrsDFN]);
      (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
      (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);

      break;

    case (VHD_lotrsDFN):

		/* ###--------- lotrs ---------### */

      lotrs_pnt = (struct lotrs *)(current_pnt.data);

      if (lotrs_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)lotrs_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_lotrsDFN;
        }
      if (lotrs_pnt->DRAIN != NULL)
        {
        tab[VHD_drainDFN] = avail;
        nxt[VHD_drainDFN] = (void *)lotrs_pnt->DRAIN;
        typ[VHD_drainDFN] = VHD_loconDFN;
        }
      if (lotrs_pnt->GRID != NULL)
        {
        tab[VHD_gridDFN] = avail;
        nxt[VHD_gridDFN] = (void *)lotrs_pnt->GRID;
        typ[VHD_gridDFN] = VHD_loconDFN;
        }
      if (lotrs_pnt->SOURCE != NULL)
        {
        tab[VHD_sourceDFN] = avail;
        nxt[VHD_sourceDFN] = (void *)lotrs_pnt->SOURCE;
        typ[VHD_sourceDFN] = VHD_loconDFN;
        }
      if (lotrs_pnt->USER != NULL)
        {
        tab[VHD_userDFN] = avail;
        nxt[VHD_userDFN] = (void *)lotrs_pnt->USER;
        typ[VHD_userDFN] = VHD_ptypeDFN;
        }

      (void)printf ("-> drain       : %s\n",tab[VHD_drainDFN]);
      (void)printf ("-> grid        : %s\n",tab[VHD_gridDFN]);
      (void)printf ("-> source      : %s\n",tab[VHD_sourceDFN]);
      (void)printf ("   length      : %d\n",lotrs_pnt->LENGTH);
      (void)printf ("   width       : %d\n",lotrs_pnt->WIDTH);
      (void)printf ("   y           : %ld\n",lotrs_pnt->Y);
      (void)printf ("   x           : %ld\n",lotrs_pnt->X);
      (void)printf ("   type        : %c\n",lotrs_pnt->TYPE);
      (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
      (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);

      break;

    case (VHD_loinsDFN):

		/* ###--------- loins ---------### */

      loins_pnt = (struct loins *)(current_pnt.data);

      if (loins_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)loins_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_loinsDFN;
        }
      if (loins_pnt->LOCON != NULL)
        {
        tab[VHD_loconDFN] = avail;
        nxt[VHD_loconDFN] = (void *)loins_pnt->LOCON;
        typ[VHD_loconDFN] = VHD_loconDFN;
        }
      if (loins_pnt->USER != NULL)
        {
        tab[VHD_userDFN] = avail;
        nxt[VHD_userDFN] = (void *)loins_pnt->USER;
        typ[VHD_userDFN] = VHD_ptypeDFN;
        }

      (void)printf ("   insname     : %s\n",loins_pnt->INSNAME);
      (void)printf ("   figname     : %s\n",loins_pnt->FIGNAME);
      (void)printf ("-> locon       : %s\n",tab[VHD_loconDFN]);
      (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
      (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);

      break;

    case (VHD_loconDFN):

		/* ###--------- locon ---------### */

      locon_pnt = (struct locon *)(current_pnt.data);

      if (locon_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)locon_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_loconDFN;
        }
      if (locon_pnt->SIG != NULL)
        {
        tab[VHD_sigDFN] = avail;
        nxt[VHD_sigDFN] = (void *)locon_pnt->SIG;
        typ[VHD_sigDFN] = VHD_losigDFN;
        }
      if (locon_pnt->ROOT != NULL)
        {
        tab[VHD_rootDFN] = avail;
        nxt[VHD_rootDFN] = (void *)locon_pnt->ROOT;
        if (locon_pnt->TYPE == 'I')
          typ[VHD_rootDFN] = VHD_loinsDFN;
        else
          typ[VHD_rootDFN] = VHD_lofigDFN;
        }
      if (locon_pnt->USER != NULL)
        {
        tab[VHD_userDFN] = avail;
        nxt[VHD_userDFN] = (void *)locon_pnt->USER;
        typ[VHD_userDFN] = VHD_ptypeDFN;
        }

      (void)printf ("   name        : %s\n",locon_pnt->NAME);
      (void)printf ("-> sig         : %s\n",tab[VHD_sigDFN]);
      (void)printf ("-> root        : %s\n",tab[VHD_rootDFN]);
      (void)printf ("   direction   : %c\n",locon_pnt->DIRECTION);
      (void)printf ("   type        : %c\n",locon_pnt->TYPE);
      (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
      (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);

      break;

    case (VHD_losigDFN):

		/* ###--------- losig ---------### */

      losig_pnt = (struct losig *)(current_pnt.data);

      if (losig_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)losig_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_losigDFN;
        }
      if (losig_pnt->USER != NULL)
        {
        tab[VHD_userDFN] = avail;
        nxt[VHD_userDFN] = (void *)losig_pnt->USER;
        typ[VHD_userDFN] = VHD_ptypeDFN;
        }

      ptchain = losig_pnt->NAMECHAIN;
      (void)printf ("   namechain   :\n");
      while (ptchain != NULL)
        {
        (void)printf ("                 %s\n",(char *)ptchain->DATA);
        ptchain = ptchain->NEXT;
        }

      (void)printf ("   capa        : %f\n",losig_pnt->CAPA);
      (void)printf ("   index       : %ld\n",losig_pnt->INDEX);
      (void)printf ("   type        : %c\n",losig_pnt->TYPE);
      (void)printf ("-> user        : %s\n",tab[VHD_userDFN]);
      (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);

      break;

    case (VHD_ptypeDFN):

		/* ###--------- ptype ---------### */

      ptype_pnt = (struct ptype *)(current_pnt.data);

      if (ptype_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)ptype_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_ptypeDFN;
        }
      if (ptype_pnt->DATA != NULL)
        {
        tab[VHD_dataDFN] = avail;
        nxt[VHD_dataDFN] = (void *)ptype_pnt->DATA;
        typ[VHD_dataDFN] = VHD_ERRDFN;
/*......typ[VHD_dataDFN] = .......................*/
        }

      (void)printf ("   type        : %ld\n",ptype_pnt->TYPE);
      (void)printf ("-> data        : %s\n",tab[VHD_dataDFN]);
      (void)printf ("-> next        : %s\n",tab[VHD_nextDFN]);

      break;


      }

	/* ###------------------------------------------------------### */
	/*    Reading new command					*/
	/* ###------------------------------------------------------### */

    readcmd = vhd_getcmd (readtab);

    for (i=0 ; i<VHD_MAXDFN ; i++)
      {
      if (readcmd == key[i])
        break;
      }
    if ((i != VHD_MAXDFN+1) && (tab[i] == avail))
      newsta0 = i;
    else
      newsta0 = -1;

	/* ###------------------------------------------------------### */
	/*    Analysing new command					*/
	/* ###------------------------------------------------------### */

    switch (newsta0)
      {
      case (VHD__UPDFN):
        current_pnt        = stk[--stk_pnt] ;
        break;

      case (VHD__BKDFN):
        while ((--stk_pnt != 0) && (stk[stk_pnt].mark != 1));
        current_pnt        = stk[stk_pnt] ;
        break;

      case (VHD__SPDFN):
        current_pnt.mark   = 1;
        break;

      case (VHD__TPDFN):
        current_pnt        = stk[0] ;
        stk_pnt        = 0 ;
        break;

      case (VHD__XTDFN):
        current_pnt.data   = NULL;
        current_pnt.type   = VHD__XTDFN;
        current_pnt.mark   = 0;
        break;

      case (VHD_ERRDFN):
        break;

      default:
        stk[stk_pnt++] = current_pnt;
        current_pnt.type   = typ[newsta0];
        current_pnt.mark   = 0;
        current_pnt.data   = nxt[newsta0];
        break;

      }

    state  = current_pnt.type;
    }
  }


static int vhd_getcmd (prvcmd)

char prvcmd[3][20];

  {
  char readstr[60];
  char comd0[20];
  char comd1[20];
  char comd2[20];
  int  code;

  (void)printf ("\n\n\n COMMAND >> ");
  comd0[0] = '\0';
  comd1[0] = '\0';
  comd2[0] = '\0';
  (void)gets   (readstr);
  (void)sscanf (readstr,"%s%s%s",comd0,comd1,comd2);

  if (strcmp(comd0,"."))
    {
    (void)strcpy (prvcmd[0], comd0);
    (void)strcpy (prvcmd[1], comd1);
    (void)strcpy (prvcmd[2], comd2);
    }
  code = vhd_hash (prvcmd[0]);

  (void)printf ("\n\n\n\n\n");
  return (code);
  }



static int vhd_hash (str)

char *str;

  {
  int code = 0;

  while(*str != '\0')
    code =  code<<1 ^ *str++;

  return (code);
  }

/*##------------------------------------------------------------------##*/
/*  Author : VUONG H.N.							*/
/*  Date   : Dec 11 1991						*/
/*  Cont.  : Essentially functions to duplicate lofig structures	*/
/*           such a complete LOFIG or just a chain_list.		*/
/*##------------------------------------------------------------------##*/

/*##------------------------------------------------------------------##*/
/*  Function : dupchainlst()						*/
/*  contents : duplicate a chain list and return a pointer on the new	*/
/*             structure.						*/
/*  called func. : reverse(), mbkalloc(),				*/
/*##------------------------------------------------------------------##*/

chain_list *dupchainlst(chain_ptr)
chain_list *chain_ptr;
  {
  chain_list *chain_rpt = NULL;		/* Returned chain pointer	*/

  while(chain_ptr != NULL)
    {
    chain_rpt = addchain(chain_rpt, chain_ptr->DATA);
    chain_ptr		= chain_ptr->NEXT;
    }
  chain_rpt = reverse(chain_rpt);
  return(chain_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duploconlst()						*/
/*  contents : duplicate a locon list and return a pointer on the new	*/
/*             structure.						*/
/*  called func. : duplocon(), reverse(),				*/
/*##------------------------------------------------------------------##*/

locon_list *duploconlst(locon_ptr)
locon_list *locon_ptr;
  {
  locon_list *locon_rpt = NULL;		/* Returned locon pointer	*/
  locon_list *locon_tmpptr = NULL;	/* Temporary pointer 		*/

  while(locon_ptr != NULL)
    {
    locon_tmpptr       = duplocon(locon_ptr);
    locon_tmpptr->NEXT = locon_rpt;
    locon_rpt          = locon_tmpptr;

    locon_ptr          = locon_ptr->NEXT;
    }
  locon_rpt = (locon_list *)reverse((chain_list *)locon_rpt);
  return(locon_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duplocon()						*/
/*  contents : duplicate a locon and return a pointer on the new	*/
/*	       structure.      						*/
/*  called func. : mbkalloc(), 		 				*/
/*  note : the ROOT and the SIG pointer are also duplicated		*/
/*##------------------------------------------------------------------##*/

locon_list *duplocon(locon_ptr)
locon_list *locon_ptr;
  {
  locon_list *locon_rpt = NULL;		/* Returned locon pointer	*/

  locon_rpt            	= (locon_list *)(mbkalloc(sizeof(locon_list)));
  locon_rpt->NEXT      	= NULL;
  locon_rpt->NAME 	= locon_ptr->NAME;
  locon_rpt->SIG      	= locon_ptr->SIG;
  locon_rpt->ROOT     	= locon_ptr->ROOT;
  locon_rpt->DIRECTION 	= locon_ptr->DIRECTION;
  locon_rpt->TYPE      	= locon_ptr->TYPE;
  locon_rpt->USER      	= NULL;		/* The ptype_list is not duplicated */

  return(locon_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duploinslst()						*/
/*  contents : duplicate a loins list and return a pointer on the new	*/
/*             structure.						*/
/*  called func. : duploins(), reverse(),				*/
/*##------------------------------------------------------------------##*/

loins_list *duploinslst(loins_ptr)
loins_list *loins_ptr;
  {
  loins_list *loins_rpt = NULL;		/* Returned loins pointer	*/
  loins_list *loins_tmpptr = NULL;	/* Temporary pointer 		*/

  while(loins_ptr != NULL)
    {
    loins_tmpptr       = duploins(loins_ptr);
    loins_tmpptr->NEXT = loins_rpt;
    loins_rpt          = loins_tmpptr;

    loins_ptr          = loins_ptr->NEXT;
    }
  loins_rpt = (loins_list *)reverse((chain_list *)loins_rpt);
  return(loins_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duploins()						*/
/*  contents : duplicate a loins and return a pointer on the new	*/
/*	       structure.      						*/
/*  called func. : mbkalloc(), 						*/
/*  note : the LOCON pointer is also duplicated				*/
/*##------------------------------------------------------------------##*/

loins_list *duploins(loins_ptr)
loins_list *loins_ptr;
  {
  loins_list *loins_rpt = NULL;		/* Returned loins pointer	*/

  loins_rpt            	= (loins_list *)(mbkalloc(sizeof(loins_list)));
  loins_rpt->NEXT      	= NULL;
  loins_rpt->LOCON 	= loins_ptr->LOCON;
  loins_rpt->INSNAME   	= loins_ptr->INSNAME;
  loins_rpt->FIGNAME 	= loins_ptr->FIGNAME;
  loins_rpt->USER      	= NULL;		/* The ptype_list is not duplicated */

  return(loins_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duplotrslst()						*/
/*  contents : duplicate a lotrs list and return a pointer on the new	*/
/*             structure.						*/
/*  called func. : duplotrs(), reverse(),				*/
/*##------------------------------------------------------------------##*/

lotrs_list *duplotrslst(lotrs_ptr)
lotrs_list *lotrs_ptr;
  {
  lotrs_list *lotrs_rpt = NULL;		/* Returned lotrs pointer	*/
  lotrs_list *lotrs_tmpptr = NULL;	/* Temporary pointer 		*/

  while(lotrs_ptr != NULL)
    {
    lotrs_tmpptr       = duplotrs(lotrs_ptr);
    lotrs_tmpptr->NEXT = lotrs_rpt;
    lotrs_rpt          = lotrs_tmpptr;

    lotrs_ptr          = lotrs_ptr->NEXT;
    }
  lotrs_rpt = (lotrs_list *)reverse((chain_list *)lotrs_rpt);
  return(lotrs_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duplotrs()						*/
/*  contents : duplicate a lotrs and return a pointer on the new	*/
/*	       structure.      						*/
/*  called func. : mbkalloc(), duplocon() 						*/
/*  note : the DRAIN, SOURCE, GRID pointers are also duplicated		*/
/*##------------------------------------------------------------------##*/

lotrs_list *duplotrs(lotrs_ptr)
lotrs_list *lotrs_ptr;
  {
  lotrs_list *lotrs_rpt = NULL;		/* Returned lotrs pointer	*/

  lotrs_rpt            	= (lotrs_list *)mbkalloc(sizeof(lotrs_list));
  lotrs_rpt->NEXT      	= NULL;
  lotrs_rpt->DRAIN 	   = lotrs_ptr->DRAIN;
  lotrs_rpt->GRID     	= lotrs_ptr->GRID;
  lotrs_rpt->SOURCE    	= lotrs_ptr->SOURCE;
  lotrs_rpt->WIDTH    	= lotrs_ptr->WIDTH;
  lotrs_rpt->LENGTH    	= lotrs_ptr->LENGTH;
  lotrs_rpt->PS        	= lotrs_ptr->PS;
  lotrs_rpt->PD        	= lotrs_ptr->PD;
  lotrs_rpt->XS        	= lotrs_ptr->XS;
  lotrs_rpt->XD        	= lotrs_ptr->XD;
  lotrs_rpt->X       	= lotrs_ptr->X;
  lotrs_rpt->Y       	= lotrs_ptr->Y;
  lotrs_rpt->TYPE    	= lotrs_ptr->TYPE;
  lotrs_rpt->USER      	= NULL;		/* The ptype_list is not duplicated */

  return(lotrs_rpt);
  }		

/*##------------------------------------------------------------------##*/
/*  Function : duplosiglst()						*/
/*  contents : duplicate a losig_list and return a pointer on the new	*/
/*             structure, a pointer on BKSIG must be given.		*/
/*  called func. :duplosig(), reverse(),				*/
/*##------------------------------------------------------------------##*/

losig_list *duplosiglst(losig_ptr,BKSIG_ptr)
losig_list *losig_ptr;
ptype_list **BKSIG_ptr;
  {
  losig_list *losig_rpt = NULL;		/* Returned losig pointer	*/
  losig_list *losig_tmpptr = NULL;	/* Temporary pointer 		*/
  ptype_list *BKSIG_rpt = NULL;     	/* Returned BKSIG pointer	*/

  while(losig_ptr != NULL)
    {
    losig_tmpptr       = duplosig(losig_ptr, &BKSIG_rpt);
    losig_tmpptr->NEXT = losig_rpt;
    losig_rpt          = losig_tmpptr;

    losig_ptr          = losig_ptr->NEXT;
    }
  losig_rpt = (losig_list *)reverse((chain_list *)losig_rpt);
  *BKSIG_ptr = BKSIG_rpt;
  return(losig_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duplosig()                                               */
/*  contents : duplicate a losig and return a pointer on the new        */
/*             structure, a pointer on the BKSIG must be given.         */
/*  called func. : mbkalloc, addptype, dupchainlst			*/
/*##------------------------------------------------------------------##*/

losig_list *duplosig(losig_ptr, BKSIG_ptr)
losig_list *losig_ptr;
ptype_list **BKSIG_ptr;

  {
  ptype_list *ptype_ptr = NULL;
  ptype_list *pt = NULL;
  long index = losig_ptr->INDEX;
  int i;
  short low, high;
  losig_list *ptsig = NULL;
  losig_list *pthead = NULL;

  ptype_ptr = *BKSIG_ptr;
  low = (short)(index % SIGSIZE);
  high = (short)(index / SIGSIZE);
  for (pt = ptype_ptr; pt; pt = pt->NEXT)
    if (pt->TYPE == high)
      break;
  if (pt == NULL) 
    {
    /* Initialization of the array of losig */
    pthead = (losig_list *)mbkalloc(SIGSIZE * sizeof(losig_list));
    ptsig = pthead;
    for (i = 0; i < SIGSIZE; i++) 
      {
      ptsig->INDEX = 0;
      ptsig++;
      }
    pt = ptype_ptr = (ptype_list *)addptype(ptype_ptr,(long)high,(void *)pthead);
    }
  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, "duplosig impossible :\n");
    (void)fprintf(stderr, "signal %ld already exist\n", 
    		  index);
    EXIT(1);
    }

  ptsig->NEXT      = NULL;
  ptsig->NAMECHAIN = dupchainlst(losig_ptr->NAMECHAIN);
  ptsig->CAPA      = losig_ptr->CAPA;
  ptsig->INDEX     = losig_ptr->INDEX;
  ptsig->USER      = NULL;
  ptsig->TYPE      = losig_ptr->TYPE;	/* The ptype_list is not duplicated */

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

/*##------------------------------------------------------------------##*/
/*  Function : duplofiglst()						*/
/*  contents : duplicate a lofig list and return a pointer on the new	*/
/*             structure.						*/
/*  called func. : duplofig(), reverse(),				*/
/*##------------------------------------------------------------------##*/

lofig_list *duplofiglst(lofig_ptr)
lofig_list *lofig_ptr;
  {
  lofig_list *lofig_rpt = NULL;		/* Returned lofig pointer	*/
  lofig_list *lofig_tmpptr = NULL;	/* Temporary pointer 		*/

  while(lofig_ptr != NULL)
    {
    lofig_tmpptr       = duplofig(lofig_ptr);
    lofig_tmpptr->NEXT = lofig_rpt;
    lofig_rpt          = lofig_tmpptr;

    lofig_ptr          = lofig_ptr->NEXT;
    }
  lofig_rpt = (lofig_list *)reverse((chain_list *)lofig_rpt);
  return(lofig_rpt);
  }

/*##------------------------------------------------------------------##*/
/*  Function : duplofig()						*/
/*  contents : duplicate a lofig and return a pointer on the new	*/
/*	       structure.      						*/
/*  called func. : mbkalloc(), dupchainlst(),				*/
/*  note : the LOCON, LOSIG, BKSIG, LOINS, LOTRS pointers are 		*/
/*         also duplicated						*/
/*##------------------------------------------------------------------##*/

lofig_list *duplofig(lofig_ptr)
lofig_list *lofig_ptr;
  {
  lofig_list *lofig_rpt = NULL;		/* Returned lofig pointer	*/

  lofig_rpt            	= (lofig_list *)(mbkalloc(sizeof(lofig_list)));
  lofig_rpt->NEXT      	= NULL;
  lofig_rpt->MODELCHAIN	= dupchainlst(lofig_ptr->MODELCHAIN);
  lofig_rpt->LOCON     	= lofig_ptr->LOCON;
  lofig_rpt->LOSIG    	= lofig_ptr->LOSIG;
  lofig_rpt->BKSIG    	= lofig_ptr->BKSIG;
  lofig_rpt->LOINS    	= lofig_ptr->LOINS;
  lofig_rpt->LOTRS    	= lofig_ptr->LOTRS;
  lofig_rpt->NAME    	= lofig_ptr->NAME;
  lofig_rpt->MODE    	= lofig_ptr->MODE;
  lofig_rpt->USER      	= NULL;		/* The ptype_list is not duplicated */

  return(lofig_rpt);
  }		

/*##------------------------------------------------------------------##*/
/*  Function : rduplofig()						*/
/*  contents : recursively duplicate a lofig and return a pointer on 	*/
/*             the new structure. This structure is the entirely	*/
/*             double of the lofig duplicated. Except, that all the	*/
/*             USER fields are empty.  					*/
/*  called func. : mbkalloc(), 						*/
/*##------------------------------------------------------------------##*/

lofig_list *rduplofig(lofig_ptr)
lofig_list *lofig_ptr;
  {
  lofig_list *lofig_rpt = NULL;		/* Returned lofig pointer	*/
  ptype_list *ptype_ptr = NULL;
  locon_list *locon_pt = NULL;
  loins_list *loins_pt = NULL;
  lotrs_list *lotrs_pt = NULL;
  long index = 0;
  
  lofig_rpt            	= duplofig(lofig_ptr);
  lofig_rpt->LOSIG      = duplosiglst(lofig_rpt->LOSIG, &ptype_ptr);
  lofig_rpt->BKSIG      = ptype_ptr;
  lofig_rpt->LOCON      = duploconlst(lofig_rpt->LOCON);
  lofig_rpt->LOINS      = duploinslst(lofig_rpt->LOINS);
  lofig_rpt->LOTRS      = duplotrslst(lofig_rpt->LOTRS);

  /* Now verify and restitute the coherence of the figure	*/

  /* Restitute coherence in the LOTRS List */ 
  lotrs_pt = lofig_rpt->LOTRS;
  while(lotrs_pt != NULL)
    {
    lotrs_pt->GRID 	= duplocon(lotrs_pt->GRID);
    locon_pt = lotrs_pt->GRID;
    while(locon_pt != NULL)
      {
      index 		= (locon_pt->SIG)->INDEX;
      locon_pt->SIG 	= getlosig(lofig_rpt, index);
      locon_pt->ROOT	= (void *)lotrs_pt;
      
      locon_pt = locon_pt->NEXT;
      }

    lotrs_pt->DRAIN 	= duplocon(lotrs_pt->DRAIN);
    locon_pt = lotrs_pt->DRAIN;
    while(locon_pt != NULL)
      {
      index 		= (locon_pt->SIG)->INDEX;
      locon_pt->SIG 	= getlosig(lofig_rpt, index);
      locon_pt->ROOT	= (void *)lotrs_pt;
      
      locon_pt = locon_pt->NEXT;
      }

    lotrs_pt->SOURCE 	= duplocon(lotrs_pt->SOURCE);
    locon_pt = lotrs_pt->SOURCE;
    while(locon_pt != NULL)
      {
      index 		= (locon_pt->SIG)->INDEX;
      locon_pt->SIG 	= getlosig(lofig_rpt, index);
      locon_pt->ROOT	= (void *)lotrs_pt;
      
      locon_pt = locon_pt->NEXT;
      }

    lotrs_pt = lotrs_pt->NEXT;
    }

  /* Restitute coherence in the LOINS List */ 
  loins_pt = lofig_rpt->LOINS;
  while(loins_pt != NULL)
    {
    loins_pt->LOCON 	= duploconlst(loins_pt->LOCON);
    locon_pt = loins_pt->LOCON;
    while(locon_pt != NULL)
      {
      index 		= (locon_pt->SIG)->INDEX;
      locon_pt->SIG 	= getlosig(lofig_rpt, index);
      locon_pt->ROOT	= (void *)loins_pt;
      
      locon_pt = locon_pt->NEXT;
      }
    loins_pt = loins_pt->NEXT;
    }

  /* Restitute coherence in the LOCON List */ 
  locon_pt = lofig_rpt->LOCON;
  while(locon_pt != NULL)
    {
    index 		= (locon_pt->SIG)->INDEX;
    locon_pt->SIG 	= getlosig(lofig_rpt, index);
    locon_pt->ROOT	= (void *)lofig_rpt;
    
    locon_pt = locon_pt->NEXT;
    }
  
  return(lofig_rpt);
  }

/* sort routines :
   connectors and signals may have to be sorted by name for some
   language purposes. */

static char	Buffer0[255]; /* may be of use for other functions */

static int
	connectorcmp(flc, slc)
locon_list **flc, **slc;
{
	return naturalstrcmp((*slc)->NAME, (*flc)->NAME);
}

void
	sortlocon(connectors)
locon_list **connectors;
{
long n, i;
locon_list *lc, **tc;

	if (!connectors || !(*connectors)) 
		return;

	/* first :
	   count connectors. */
	for (n = 0, lc = *connectors; lc; lc = lc->NEXT)
		n++;
	tc = (locon_list **)mbkalloc(n * sizeof(locon_list *));
	for (n = 0, lc = *connectors; lc; lc = lc->NEXT)
		tc[n++] = lc;
	/* second :
	   sort them. */
	qsort((void *)tc, n, sizeof(locon_list *), connectorcmp);
	/* tables :
	   the last element of the table is t[n - 1].
	   relink the list in the sorted order. */
	n--;
	*connectors = tc[0];
	for (i = 0; i < n; i++)
		tc[i]->NEXT = tc[i + 1];
	tc[n]->NEXT = (locon_list *)NULL;
	mbkfree((void *)tc);
}

static int
	signalcmp(fls, sls)
locon_list **fls, **sls;
{
	return naturalstrcmp(getsigname(*fls), getsigname(*sls));
}

void
	sortlosig(signals)
losig_list **signals;
{
long n, i;
losig_list *lc, **tc;

	if (!signals || !(*signals)) 
		return;

	/* first :
	   count signals. */
	for (n = 0, lc = *signals; lc; lc = lc->NEXT)
		n++;
	tc = (losig_list **)mbkalloc(n * sizeof(losig_list *));
	for (n = 0, lc = *signals; lc; lc = lc->NEXT)
		tc[n++] = lc;
	/* second :
	   sort them. */
	qsort((void *)tc, n, sizeof(losig_list *), signalcmp);
	/* tables :
	   the last element of the table is t[n - 1].
	   relink the list in the sorted order. */
	n--;
	*signals = tc[0];
	for (i = 0; i < n; i++)
		tc[i]->NEXT = tc[i + 1];
	tc[n]->NEXT = (losig_list *)NULL;
	mbkfree((void *)tc);
}

/* checking :
   the validity of a list of connectors for vectorization purposes
   is to be checked for some file formats, so let's do it.
   The algorithm checks that :
      vectorized radical do not appear on themselves
      vectorized connectors are all together and ordered properly */
#define HTSIZE 200
int
	checkloconorder(c)
locon_list *c;
{
char *s, *t;
ht *table;
char first = 1, previous, delta, current;

	table = addht(HTSIZE);
	while (c) {
		/* vectorized ?
		   no. */
		if ((s = strchr(c->NAME, ' ')) == NULL) {
avoid_redundancy :
			if (sethtitem(table, (void *)c->NAME, 0)) {
				(void)fflush(stdout);
				(void)fprintf(stderr, "*** mbk error ***\n");
				(void)fprintf(stderr,
									"the radical %s is already used in a vector\n",
									c->NAME);
				delht(table);
				EXIT(1);
				return 1;
			}
			first = 1;
			c = c->NEXT;
		} else {
			while (c) {
			int i = 1;
				/* redundancy :
				   I'ven't found an elegant way to do that, too bad. */
				if (!s)
					if ((s = strchr(c->NAME, ' ')) == NULL)
						goto avoid_redundancy;
				/* Temporary change :
				   alter the string contents just a microsecond. */
				*s = '\0';
				strcpy(Buffer0, c->NAME);
				*s = ' ';
				while (*(s + i) && isdigit(*(s + i)))
					i++;
				if (*(s + i)) {
					(void)fflush(stdout);
					(void)fprintf(stderr, "*** mbk error ***\n");
					(void)fprintf(stderr,
							"the radical %s has a spurious vectorized value %s (%s)\n",
							Buffer0, s + 1, c->NAME);
					delht(table);
					EXIT(1);
					return 1;
				}
				current = atoi(s + 1);
				s = NULL;
				/* first :
				   the name is not yet known. so I store it.
				   we do that each time a new vector is encountered. */
				if (first) {
its_first:
					if (sethtitem(table, (void *)(t = namealloc(Buffer0)), 0)) {
						(void)fflush(stdout);
						(void)fprintf(stderr, "*** mbk error ***\n");
						(void)fprintf(stderr,
											"the radical %s is already used in a vector\n",
											Buffer0);
						delht(table);
						EXIT(1);
						return 1;
					}
					delta = first = 0;
					previous = current;
					c = c->NEXT;
				} else { /* let's see if it's a good vhdl legal vector */
					/* its a new vector :
					   in fact this vector follows an other vector! */
					if (t != namealloc(Buffer0))
						goto its_first;
					if (!delta)
						delta = previous - current;
					else if (delta != previous - current) {
						(void)fflush(stdout);
						(void)fprintf(stderr, "*** mbk error ***\n");
						(void)fprintf(stderr,
										"the radical %s is not vectorized properly,",
										Buffer0);
						(void)fprintf(stderr,
										" %s %d follows %s %d\n", Buffer0, previous,
																			Buffer0, current);
						delht(table);
						EXIT(1);
						return 1;
					}
					if (delta != 1 && delta != -1) {
						(void)fflush(stdout);
						(void)fprintf(stderr, "*** mbk error ***\n");
						(void)fprintf(stderr,
										"the radical %s is not vectorized properly,",
										c->NAME);
						(void)fprintf(stderr,
										" %s %d follows %s %d\n", Buffer0, previous,
																			Buffer0, current);
						delht(table);
						EXIT(1);
						return 1;
					}
					previous = current;
					c = c->NEXT;
				}
			}
		}
	}
	delht(table);
	return 0;
}
