Пример #1
0
static Key *
parsechain(const char *s, const char *e, Key *spec)
{
	const char *p, *q;
	Key *chain = NULL, *last = NULL;

	XPRINTF("Parsing chain from: '%s'\n", s);

	for (p = s; p < e; p = (*q == ':' ? q + 1 : q)) {
		Key *k;

		for (q = p;
		     q < e && (isalnum(*q) || isblank(*q) || *q == '_' || *q == '+');
		     q++) ;
		if (q < e && *q != ':')
			q = e;
		k = ecalloc(1, sizeof(*k));
		*k = *spec;
		if (!parsekey(p, q, k)) {
			freekey(k);
			freechain(chain);
			chain = last = NULL;
			break;
		}
		chain = chain ? : k;
		if (last) {
			last->func = &k_chain;
			last->chain = k;
		}
		last = k;
	}
	if (chain)
		XPRINTF("Parsed chain: %s\n", showchain(chain));
	return chain;
}
Пример #2
0
void
addchain(Key *k)
{
	Key **kp;

	XPRINTF("Adding chain: %s ...\n", showchain(k));
	for (kp = &scr->keylist; *kp; kp = &(*kp)->cnext)
		if ((*kp)->mod == k->mod && (*kp)->keysym == k->keysym)
			break;
	if (*kp) {
		XPRINTF("Overlapping key definition %s\n", XKeysymToString(k->keysym));
		if ((*kp)->chain && k->chain)
			mergechain(*kp, k);
		else {
			XPRINTF("Overriding previous key definition: %s!\n", showchain(k));
			k->cnext = (*kp)->cnext;
			(*kp)->cnext = NULL;
			freechain(*kp);
			*kp = k;
		}
		XPRINTF("... added chain: %s\n", showchain(*kp));
	} else {
		XPRINTF("Adding new key %s\n", XKeysymToString(k->keysym));
		k->cnext = scr->keylist;
		scr->keylist = k;
		XPRINTF("... added chain: %s\n", showchain(k));
	}
}
Пример #3
0
/*
 * (*kp) and k have the same mod and keysym.  Both have a non-null ->chain.
 * if there is a key in the (*kp)->chain list (*lp) that has the same mod and
 * keysm as k->chain, then free (*lp) and set its location to *kp->chain
 */
static void
mergechain(Key *c, Key *k)
{
	Key **lp;
	Key *next = k->chain;

	XPRINTF("Merging chain %s\n", showchain(k));
	XPRINTF("   into chain %s\n", showchain(c));
	k->chain = NULL;
	freekey(k);
	k = next;

	for (lp = &c->chain; *lp; lp = &(*lp)->cnext)
		if ((*lp)->mod == k->mod && (*lp)->keysym == k->keysym)
			break;
	if (*lp) {
		if ((*lp)->chain && k->chain)
			mergechain(*lp, k);
		else {
			XPRINTF("Overriding previous key alternate %s!\n", showchain(k));
			k->cnext = (*lp)->cnext;
			(*lp)->cnext = NULL;
			freechain(*lp);
			*lp = k;
		}
	} else {
		k->cnext = NULL;
		*lp = k;
	}
}
Пример #4
0
static int freechain(WlzLLink *l)
{
  if (l != NULL) {
    freechain(l->l_link);
    AlcFree((char *) l);
  }

  return( 0 );
}
Пример #5
0
void
freekeys(void)
{
	Key *k, *knext;

	knext = scr->keylist;
	scr->keylist = NULL;
	while ((k = knext)) {
		knext = k->cnext;
		k->cnext = NULL;
		XPRINTF("Freeing key chain: %s\n", showchain(k));
		freechain(k);
	}
}
Пример #6
0
void
freechain(Key *k)
{
	Key *c, *cnext;

	if (k) {
		XPRINTF("Freeing chain: %p: %s\n", k, showchain(k));
		cnext = k->chain;
		k->chain = NULL;
		while ((c = cnext)) {
			cnext = c->cnext;
			c->cnext = NULL;
			freechain(c);
		}
		freekey(k);
	}
}
Пример #7
0
/*
 * Load the device policy.
 * The device policy currently makes nu distinction between the
 * block and characters devices; that is generally not a problem
 * as the names of those devices cannot clash.
 */
int
devpolicy_load(int nitems, size_t sz, devplcysys_t *uitmp)
{
	int i, j;
	int nmaj = 0;
	major_t lastmajor;
	devplcysys_t *items;
	size_t mem;
	major_t curmaj;
	devplcyent_t **last, *de;

	tableent_t *newpolicy, *oldpolicy;
	devplcy_t *newnull, *newdflt, *oldnull, *olddflt;
	int oldcnt;
	int lastlen;
	int lastwild;

#ifdef lint
	/* Lint can't figure out that the "i == 1" test protects all */
	lastlen = 0;
	lastwild = 0;
	lastmajor = 0;
#endif
	/*
	 * The application must agree with the kernel on the size of each
	 * item; it must not exceed the maximum number and must be
	 * at least 1 item in size.
	 */
	if (sz != sizeof (devplcysys_t) || nitems > maxdevpolicy || nitems < 1)
		return (EINVAL);

	mem = nitems * sz;

	items = kmem_alloc(mem, KM_SLEEP);

	if (copyin(uitmp, items, mem)) {
		kmem_free(items, mem);
		return (EFAULT);
	}

	/* Check for default policy, it must exist and be sorted first */
	if (items[0].dps_maj != DEVPOLICY_DFLT_MAJ) {
		kmem_free(items, mem);
		return (EINVAL);
	}

	/*
	 * Application must deliver entries sorted.
	 * Sorted meaning here:
	 *	In major number order
	 *	For each major number, we first need to have the explicit
	 *	entries, then the wild card entries, longest first.
	 */
	for (i = 1; i < nitems; i++) {
		int len, wild;
		char *tmp;

		curmaj = items[i].dps_maj;
		len = strlen(items[i].dps_minornm);
		wild = len > 0 &&
		    (tmp = strchr(items[i].dps_minornm, '*')) != NULL;

		/* Another default major, string too long or too many ``*'' */
		if (curmaj == DEVPOLICY_DFLT_MAJ ||
		    len >= sizeof (items[i].dps_minornm) ||
		    wild && strchr(tmp + 1, '*') != NULL) {
			kmem_free(items, mem);
			return (EINVAL);
		}
		if (i == 1 || lastmajor < curmaj) {
			lastmajor = curmaj;
			nmaj++;
		} else if (lastmajor > curmaj || lastwild > wild ||
		    lastwild && lastlen < len) {
			kmem_free(items, mem);
			return (EINVAL);
		}
		lastlen = len;
		lastwild = wild;
	}

	if (AU_AUDITING())
		audit_devpolicy(nitems, items);

	/*
	 * Parse the policy.  We create an array for all major numbers
	 * and in each major number bucket we'll have a linked list of
	 * entries.  Each item may contain either a lo,hi minor pair
	 * or a string/wild card matching a minor node.
	 */
	if (nmaj > 0)
		newpolicy = kmem_zalloc(nmaj * sizeof (tableent_t), KM_SLEEP);

	/*
	 * We want to lock out concurrent updates but we don't want to
	 * lock out device opens while we still need to allocate memory.
	 * As soon as we allocate new devplcy_t's we commit to the next
	 * generation number, so we must lock out other updates from here.
	 */
	mutex_enter(&policymutex);

	/* New default and NULL policy */
	newnull = dpget();

	if (priv_isemptyset(&items[0].dps_rdp) &&
	    priv_isemptyset(&items[0].dps_wrp)) {
		newdflt = newnull;
		dphold(newdflt);
	} else {
		newdflt = dpget();
		newdflt->dp_rdp = items[0].dps_rdp;
		newdflt->dp_wrp = items[0].dps_wrp;
	}

	j = -1;

	/* Userland made sure sorting was ok */
	for (i = 1; i < nitems; i++) {
		de = parse_policy(&items[i], newnull, newdflt);

		if (j == -1 || curmaj != items[i].dps_maj) {
			j++;
			newpolicy[j].t_major = curmaj = items[i].dps_maj;
			last = &newpolicy[j].t_ent;
		}
		*last = de;
		last = &de->dpe_next;
	}

	/* Done parsing, throw away input */
	kmem_free(items, mem);

	/* Lock out all devpolicy_find()s */
	rw_enter(&policyrw, RW_WRITER);

	/* Install the new global data */
	oldnull = nullpolicy;
	nullpolicy = newnull;

	olddflt = dfltpolicy;
	dfltpolicy = newdflt;

	oldcnt = ntabent;
	ntabent = nmaj;

	totitems = nitems;

	oldpolicy = devpolicy;
	devpolicy = newpolicy;

	/* Force all calls by devpolicy_find() */
	devplcy_gen++;

	/* Reenable policy finds */
	rw_exit(&policyrw);
	mutex_exit(&policymutex);

	/* Free old stuff */
	if (oldcnt != 0) {
		for (i = 0; i < oldcnt; i++)
			freechain(oldpolicy[i].t_ent);
		kmem_free(oldpolicy, oldcnt * sizeof (*oldpolicy));
	}

	dpfree(oldnull);
	dpfree(olddflt);

	return (0);
}
Пример #8
0
extern void save_xsch(FILE* xsch_stream, lofig_list* lofig, ptype_list* long_path, int color_mode)
{
   long color;
   ptype_list* ptype, *ptype2=NULL;
   float delay=0, delay_out=0;
   char mes[1024];
   char* signame = NULL;
   locon_list* locon;
   losig_list* losig;
   float gradient=1;
   int count;
   loins_list* loins;
   char *source, *dest=NULL, *last_sig;
   chain_list* chain, *loinschain=NULL;
   chain_list* lofigchain;
   losig_list* losig_aux;

   /*build gradient*/
   if (long_path && color_mode==XSCH_GRADIENT) {
      /*get time of last entry*/
      count=1;
      for (ptype=long_path; ptype->NEXT; ptype=ptype->NEXT) count++;
      
      if (!ptype->DATA) {
         fprintf(stderr,"save_xsch: compute error\n");
         exit(1);
      }
      delay=ptype->TYPE;
      gradient=delay/((float)XSCH_COLOR_MAX);
   }
   
   /*color for signals*/
   for (losig=lofig->LOSIG; losig; losig=losig->NEXT) {

      if (!losig->NAMECHAIN || !losig->NAMECHAIN->DATA) {
         fprintf(stderr,"save_xsch: no name for signal\n");
         exit(1);
      }
      signame=losig->NAMECHAIN->DATA;
      
      if (isvdd(signame) || isvss(signame)) continue;
      
      if (losig->TYPE==EXTERNAL) {
         /*search external output*/
         ptype=getptype(losig->USER,LOFIGCHAIN);
         for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
            locon=lofigchain->DATA;
            if (locon->TYPE==EXTERNAL && locon->DIRECTION!=IN) break;
         }
         if (lofigchain) delay=getdelay(output_name(signame));
         else delay=getdelay(signame);
      }   
      else delay=getdelay(signame);
      
      switch (color_mode) {
      case XSCH_GRADIENT: color=gradient_color(delay,gradient); break;
      case XSCH_CRITICAL_PATH: default: color=XSCH_NEUTRAL_COLOR; break;
      }
      
      flush_losig(xsch_stream, signame, color, delay, losig->TYPE);
      
   }
   
   
   /*color for instances*/
   for (loins=lofig->LOINS; loins; loins=loins->NEXT) {
      /*search signal output*/
      for (locon=loins->LOCON; locon; locon=locon->NEXT) {
         if (locon->DIRECTION==UNKNOWN) {
            fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
            locon->NAME,loins->INSNAME);
            exit(1);
         }
         if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT 
           || locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) break;
      }
      if (!locon) {
         fprintf(stderr,"save_xsch: no output found for '%s'\n",loins->INSNAME);
         exit(1);
      }
      losig=locon->SIG;
      signame=losig->NAMECHAIN->DATA;
      
      delay=getdelay(loins->INSNAME);
     
      switch (color_mode) {
      case XSCH_GRADIENT: color=gradient_color(delay,gradient); break;
      case XSCH_CRITICAL_PATH: default:
         /*is instance in critical path?*/
         for (ptype=long_path; ptype; ptype=ptype->NEXT) {
            if ((char*)ptype->DATA!=signame) continue;
          /*if output and input signals belong to critical path, then instance belongs*/
            for (locon=loins->LOCON; locon; locon=locon->NEXT) {
               if (locon->DIRECTION==OUT || locon->DIRECTION==TRISTATE) continue;
               losig_aux=locon->SIG;
               /*is signal in critical path?*/
               for (ptype2=long_path; ptype2; ptype2=ptype2->NEXT) {
                  if ((char*)ptype2->DATA==losig_aux->NAMECHAIN->DATA) break;
               }
               if (ptype2) break;
            }
            ptype=ptype2;  /*found?*/
            break;
         }
         
         /*build critical path list*/
         if (ptype) loinschain=addchain(loinschain,loins);
     
         if (ptype) color=XSCH_RED_COLOR;
         else color=XSCH_NEUTRAL_COLOR;
      }
      flush_loins(xsch_stream, loins->INSNAME, color, delay);
      
   }
   

   /*color for connectors*/
   for (locon=lofig->LOCON; locon; locon=locon->NEXT) {

      if (isvdd(locon->NAME) || isvss(locon->NAME)) continue;
      
      switch (locon->DIRECTION) {
      case IN: 
         delay_out=getdelay(locon->NAME);
         sprintf(mes, "%d ps",(int)delay_out);
         break;
      case OUT: case TRISTATE: 
         delay_out=getdelay(output_name(locon->NAME));
         sprintf(mes, "%d ps",(int)delay_out);
         break;
      case INOUT: case TRANSCV: 
         delay=getdelay(locon->NAME);
         delay_out=getdelay(output_name(locon->NAME));
         sprintf(mes, "%d ps on input; %d ps on output",(int)delay,(int)delay_out);
         break;
      }

      switch (color_mode) {
      case XSCH_GRADIENT: color=gradient_color(delay_out,gradient); break;
      case XSCH_CRITICAL_PATH: default:
         /* seek if signal is in a long path*/
         for (ptype=long_path; ptype; ptype=ptype->NEXT) {
            if ((char*)ptype->DATA==locon->NAME) break;
         }
   
         if (ptype) color=XSCH_RED_COLOR;
         else color=XSCH_NEUTRAL_COLOR;
      }
      flush_stream_special(xsch_stream, locon->NAME, color, mes);
   }  


   /*critical path*/
   if (loinschain && long_path && color_mode==XSCH_CRITICAL_PATH) {
      source=NULL;
      last_sig=NULL;
      for (ptype=long_path; ptype; ptype=ptype->NEXT) {
         signame=ptype->DATA;
         for (chain=loinschain; chain; chain=chain->NEXT) {
            loins=chain->DATA;
            /*search signal output*/
            for (locon=loins->LOCON; locon; locon=locon->NEXT) {
               if (locon->DIRECTION==OUT || locon->DIRECTION==INOUT 
                || locon->DIRECTION==TRISTATE || locon->DIRECTION==TRANSCV) {
                  losig=locon->SIG;
                  if (losig->NAMECHAIN->DATA==signame) {
                     dest=loins->INSNAME;
                     break;
                  }
               }   
            }
            if (locon) break;
         }  
         /*if no instance found it is external connector. it has the same name than signal*/
         if (!locon) dest=signame;
      
         if (source)
            flush_path(xsch_stream, source, last_sig, dest, XSCH_RED_COLOR, delay, INTERNAL);
      
         source=dest;
         last_sig=signame;
      }
      
      /*for last signal search output*/
      if (losig) {
         ptype=getptype(losig->USER,LOFIGCHAIN);
         for (chain=ptype->DATA; chain; chain=chain->NEXT) {
            locon=chain->DATA;
            /*port of circuit*/
            if (locon->TYPE==EXTERNAL) {dest=locon->NAME; break;}
            loins=locon->ROOT;
            /*register input if no error*/
            if (locon->DIRECTION==IN || locon->DIRECTION==INOUT || locon->DIRECTION==TRANSCV)
            {dest=loins->INSNAME; break;}
         }
         flush_path(xsch_stream, source, signame, dest, XSCH_RED_COLOR, delay, losig->TYPE);
      }
      
   }

   freechain(loinschain);
}
Пример #9
0
static void chainFree(void)
{
  (void )freechain(allocthings.orig_base);
}
Пример #10
0
static int insert_buffer(losig_list* losig, lofig_list* lofig, int optim_level, long index)
{
   double capa, init_capa;
   cell_list* buffer;
   chain_list* namechain, *sigchain=NULL;
   char* signame;
   lofig_list* model;
   losig_list* losig_buf;
   loins_list* loins_buf;
   locon_list* locon;
   losig_list* losig_vdd=NULL, *losig_vss=NULL, *losig_aux;
   ptype_list* ptype, *buffer_ptype;
   double delay, best_delay, init_delay;
   loins_list* loins;
   chain_list* lofigchain,*newlofigchain=NULL;
   int buffer_is_better=0, change=1;    /*flags*/
   chain_list* pred;
   chain_list* temp;


   buffer=getCellbuffer();
   /*no buffer in library*/
   if (!buffer) return 0;
   
   if (!losig->NAMECHAIN) {
      fprintf(stderr,"insert_buffer: no name on signal\n");
      autexit(1);
   }

   best_delay=critical_delay(lofig);
   init_capa=getcapacitance(losig->NAMECHAIN->DATA);

   /*add buffer to netlist*/
   signame=getautoname(losig->NAMECHAIN->DATA);
   namechain=addchain(NULL,signame);
   losig_buf=addlosig(lofig,index,namechain,INTERNAL);
   putcapacitance(signame,0);
   putdelay(signame,0);
   model=getlofig(buffer->BEFIG->NAME,'A');
   
   /*search vdd and vss*/
   for (locon=lofig->LOCON; locon; locon=locon->NEXT) {
      if (isvdd(locon->NAME)) losig_vdd=locon->SIG;
      if (isvss(locon->NAME)) losig_vss=locon->SIG;
   }
   
   /*build list of signal*/
   for (locon=model->LOCON;locon; locon=locon->NEXT) {
      if (locon->DIRECTION==UNKNOWN) {
         fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
         locon->NAME,model->NAME);
         autexit(1);
      }
      if (isvdd(locon->NAME)) losig_aux=losig_vdd;
      else if (isvss(locon->NAME)) losig_aux=losig_vss;
      else if (locon->DIRECTION==OUT) losig_aux=losig_buf;
      else if (locon->DIRECTION==IN) losig_aux=losig;
      else {
         fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME);
         autexit(1);
      }
      sigchain=addchain(sigchain,losig_aux);
   }

   
   sigchain=reverse(sigchain);
   loins_buf=addloins(lofig,signame,model,sigchain);
   freechain(sigchain);
   /*to check changes*/
   init_delay=getdelay(losig->NAMECHAIN->DATA);
   init_capa=getcapacitance(losig->NAMECHAIN->DATA);
   loins_capacitance(loins_buf,1/*add capa*/);
  
   /*lofigchain*/
   for (locon=loins_buf->LOCON;locon; locon=locon->NEXT) {
      if (locon->DIRECTION==UNKNOWN) {
         fprintf(stderr,"BEH: 'linkage %s' in figure '%s' isn't accepted\n",
         locon->NAME,loins_buf->INSNAME);
         autexit(1);
      }
      if (isvdd(locon->NAME)) losig_aux=losig_vdd;
      else if (isvss(locon->NAME)) losig_aux=losig_vss;
      else if (locon->DIRECTION==OUT) losig_aux=losig_buf;
      else if (locon->DIRECTION==IN) losig_aux=losig;
      else {
         fprintf(stderr,"insert_buffer: buffer port '%s' unknown\n",locon->NAME);
         autexit(1);
      }
      ptype=getptype(losig_aux->USER,LOFIGCHAIN);
      if (!ptype) losig_aux->USER=addptype(losig_aux->USER,LOFIGCHAIN,addchain(NULL,locon));
      else ptype->DATA=addchain(ptype->DATA,locon);
   }
   
   /*move all instance after buffer*/
   ptype=getptype(losig->USER,LOFIGCHAIN);
   buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN);
   if (!ptype || !buffer_ptype) {
      fprintf(stderr,"insert_buffer: LOFIGCHAIN not found\n");
      autexit(1);
   }
   
   for (lofigchain=((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/;
        lofigchain; lofigchain=lofigchain->NEXT) {
      locon=(locon_list*) lofigchain->DATA;
      if (locon->DIRECTION==UNKNOWN) {
         fprintf(stderr,"BEH: 'linkage %s' isn't accepted\n",
         locon->NAME);
         autexit(1);
      }
      /*do not move drivers and port of circuit*/
      if (locon->TYPE==EXTERNAL || locon->DIRECTION!=IN) {
         newlofigchain=addchain(newlofigchain,locon);
         continue;
      }
      
      loins=locon->ROOT;
      /*change capacitance*/
      loins_capacitance(loins,0/*remove  capa*/);
      /*change netlist*/
      locon->SIG=losig_buf;
      buffer_ptype->DATA=addchain(buffer_ptype->DATA,locon);
      loins_capacitance(loins,1/*add capa*/);
   }
   
   /*put back drivers*/
   freechain(((chain_list*)ptype->DATA)->NEXT/*first is entry of buffer*/);
   ((chain_list*)ptype->DATA)->NEXT=newlofigchain;
   
   /*eval all changes*/
   propagate_loins_delay(loins_buf);

   /*relaxation algorithm*/
   while (change) {
      change=0;
      pred=NULL;
      buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN);
      ptype=getptype(losig->USER,LOFIGCHAIN);
      if (!buffer_ptype || !buffer_ptype->DATA) {
         fprintf(stderr,"insert_buffer: LOFIGCHAIN is empty\n");
         autexit(1);
      }
      
      /*put critical path before buffer*/
      for (lofigchain=buffer_ptype->DATA; lofigchain->NEXT/*last is buffer output*/;
           lofigchain=lofigchain->NEXT) {
         locon=lofigchain->DATA;
         loins=locon->ROOT;
      
         /*change capacitance*/
         loins_capacitance(loins,0/*remove capa*/);
         /*change netlist*/
         locon->SIG=losig;
         ptype->DATA=addchain(ptype->DATA,locon);
         loins_capacitance(loins,1/*add capa*/);

         /*put over*/
         if (pred) pred->NEXT=lofigchain->NEXT;
         else buffer_ptype->DATA=lofigchain->NEXT;
      
         /*eval all changes*/
         propagate_loins_delay(loins);
         propagate_loins_delay(loins_buf);
         delay=critical_delay(lofig);
      
         if (delay<best_delay) {
            /*finish change*/
            best_delay=delay; 
            change=1;   /*flag of change*/
            buffer_is_better=1;
            lofigchain->NEXT=NULL;
            freechain(lofigchain);
            break;
         }
         else {
            /*remove change*/
            if (pred) pred->NEXT=lofigchain;
            else buffer_ptype->DATA=lofigchain;
            
            /*unchange capacitance*/
            loins_capacitance(loins,0/*remove capa*/);
            /*unchange netlist*/
            locon->SIG=losig_buf;
            temp=ptype->DATA;
            ptype->DATA=temp->NEXT;
            temp->NEXT=NULL;
            freechain(temp);
            loins_capacitance(loins,1/*add capa*/);
            /*avoid change*/
            propagate_loins_delay(loins_buf);
            propagate_loins_delay(loins);
            
            /*for next loop*/
            pred=lofigchain;
         }
      }
      
   }/*end of while*/
   
   if (buffer_is_better) {
      /*chose the best buffer*/
      change_instance(loins_buf, losig_buf, lofig, optim_level);
   }   
   else {  /*if insert buffer is worst than before, remove it*/
      /*remove all references of buffer in lofigchain*/
      for (locon=loins_buf->LOCON; locon; locon=locon->NEXT) {
         losig_aux=locon->SIG;
         ptype=getptype(losig_aux->USER,LOFIGCHAIN);
         if (!ptype) break;
         pred=NULL;
         for (lofigchain=ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
            if (lofigchain->DATA==locon) {
               if (pred) pred->NEXT=lofigchain->NEXT;
               else ptype->DATA=lofigchain->NEXT;
               lofigchain->NEXT=NULL;
               freechain(lofigchain);
               break;
            }
            pred=lofigchain;
         }
      }
      
      buffer_ptype=getptype(losig_buf->USER,LOFIGCHAIN);
      ptype=getptype(losig->USER,LOFIGCHAIN);
      if (buffer_ptype) {
       for (lofigchain=buffer_ptype->DATA; lofigchain; lofigchain=lofigchain->NEXT) {
         locon=lofigchain->DATA;
         loins=locon->ROOT;
         /*change capacitance*/
         loins_capacitance(loins,0/*remove capa*/);
         /*change netlist*/
         locon->SIG=losig;
         ptype->DATA=addchain(ptype->DATA,locon);
         loins_capacitance(loins,1/*add capa*/);
         propagate_loins_delay(loins);
       }
      
       freechain(buffer_ptype->DATA);
       buffer_ptype->DATA=NULL;
      }
      
      loins_capacitance(loins_buf,0/*remove capa*/);
      dellosig(lofig,index);
      delloins(lofig,loins_buf->INSNAME);
      propagate_losig_delay(losig);
   
      /*verify no change on timing*/
      delay=critical_delay(lofig);
      capa=getcapacitance(losig->NAMECHAIN->DATA);
      //01/09/2004 xtof's modification: rounding problem
      if ((int)(capa + 0.5)!=(int)(init_capa + 0.5) || (int)(delay + 0.5)!=(int)(best_delay + 0.5) 
       || (int)(init_delay + 0.5)!=(int)(getdelay(losig->NAMECHAIN->DATA) + 0.5)) {
         fprintf(stderr,
         "insert_buffer: compute error %e!=%e fF   %f!=%f ps    %f!=%f ps\n",
         capa,init_capa,delay,best_delay, init_delay, getdelay(losig->NAMECHAIN->DATA));
         autexit(1);
      }   
   
   }
      
   return buffer_is_better;
}