Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

That infinite loop in Geoff's second zle_refresh patch



I don't know if this is the same one that Zoltan saw, because when I
got it, it had nothing to do with the history ... the loop happens in
refreshline() when computing whether it's cheaper to insert or delete
a character than it is to reprint.  The first time around the loop,
we call tcdelcost(0) which is always less than any nonzero pfxlen(),
so we delete no characters and then go around the outer loop again,
forever.

The optimization is only attempted if there's no RPS1, which may be
why I couldn't reproduce it when Zoltan first reported it.

The patch below changes starting count from 0 to 1, which stops the
infinite loop, but feels wrong to me.  I can't see any reason to call
tcdelcost(0), but that code was there before either of Geoff's recent
patches; the only nearby difference since pre2 is a change from

	if ((ln || !put_rpmpt || !oput_rpmpt)) {
	    if (tccan(TCDEL) && nl[1] && ol[1] && (ol[1] != nl[1])) {
		/* ... */
	    }
	    if ((vln != lines - 1) &&	/* not on last line */
		tccan(TCINS) && nl[1] && ol[1] && (ol[1] != nl[1])) {
		/* ... */
	    }
	}
To
	if ((ln || !put_rpmpt || !oput_rpmpt) 
	    && (nl[1] && ol[1] && nl[1] != ol[1])) { 
	    if (tccan(TCDEL)) {
		/* ... */
	    }
	    if ((vln != lines - 1) && tccan(TCINS)) {	/* not on last line */
		/* ... */
	    }
	}

which sure looks harmless to me.

I'd think that rather than counting up from zero calling tcdelcost(),
we'd want to start with the largest number of deletable/insertable
characters that we can, then count *down* until tcdelcost(i) < pfxlen().
But maybe I'm just not following this correctly ...

Anyway, here's the patch to prevent the infinite loop.  Geoff, please
throw rocks if this is going to screw up for some other reason.

*** zle_refresh.c.00	Tue Jul 16 21:34:05 1996
--- zle_refresh.c	Tue Jul 16 21:34:54 1996
***************
*** 615,621 ****
  	   eg. oldline: hifoobar } hopefully cheaper here to delete two
  	       newline: foobar	 } characters, then we have six matches */
  	    if (tccan(TCDEL)) {
! 		for (i = 0, p1 = ol; *p1; p1++, i++)
  		    if (tcdelcost(i) < pfxlen(p1, nl)) {
  			tc_delchars(i);
  			SELECT_ADD_COST(i);
--- 615,621 ----
  	   eg. oldline: hifoobar } hopefully cheaper here to delete two
  	       newline: foobar	 } characters, then we have six matches */
  	    if (tccan(TCDEL)) {
! 		for (i = 1, p1 = ol; *p1; p1++, i++)
  		    if (tcdelcost(i) < pfxlen(p1, nl)) {
  			tc_delchars(i);
  			SELECT_ADD_COST(i);
***************
*** 631,637 ****
  	   undesired scrolling occurs due to `illegal' characters on screen */
  
  	    if (tccan(TCINS) && (vln != lines - 1)) {	/* not on last line */
! 		for (i = 0, p1 = nl; *p1; p1++, i++)
  		    if (tcinscost(i) < pfxlen(p1, ol)) {
  			tc_inschars(i);
  			SELECT_ADD_COST(2 * i);
--- 631,637 ----
  	   undesired scrolling occurs due to `illegal' characters on screen */
  
  	    if (tccan(TCINS) && (vln != lines - 1)) {	/* not on last line */
! 		for (i = 1, p1 = nl; *p1; p1++, i++)
  		    if (tcinscost(i) < pfxlen(p1, ol)) {
  			tc_inschars(i);
  			SELECT_ADD_COST(2 * i);




Messages sorted by: Reverse Date, Date, Thread, Author