[net.sources.bugs] Fix for vc ^J bug

wmb@sun.uucp (Mitch Bradley) (01/19/85)

> There seems to be an important bug in vc, which makes it much
> less useful.  Attempts to copy a row (using the ^j command),
> where the row contains an expression using the +/ operator,
> fail to work correctly.  The cells for the operands of the +/
> in the expression tree apparently do not get initialized.
> The result, in any case, is usually a reference to r0c0
> instead of a reference to the cell mentioned in the copied
> expression.  Occasionally I have seen, instead of r0c0,
> a row number with seven digits.  This looks like pre-existing,
> nonconforming garbage.  This means that a row including
> a cross-wise summation cannot be copied (generally if the
> copied row is copied again the program dies with a segmentation
> fault).
> 
> Does anyone have a fix for this?
> 
> scott preece
> ihnp4!uiucdcs!ccvaxa!preece

Here's a contextual diff listing for the fix.  The file is interp.c
This fix also includes code to make the times-reduce (*/)
feature work.

*** interp.c.orig	Fri Jan 18 19:17:50 1985
--- interp.c	Fri Jan 18 19:13:41 1985
***************
*** 35,40
  	case 'v':	return (e->e.v->v);
  	case 'p':	return (executeprogram(e));
  	case O_REDUCE('+'):
  	    {	register r,c;
  		register struct ent *p;
  		register double v = 0;

--- 35,41 -----
  	case 'v':	return (e->e.v->v);
  	case 'p':	return (executeprogram(e));
  	case O_REDUCE('+'):
+ 	case O_REDUCE('*'):
  	    {	register r,c;
  		register struct ent *p;
  		register double v;
***************
*** 37,43
  	case O_REDUCE('+'):
  	    {	register r,c;
  		register struct ent *p;
! 		register double v = 0;
  		register maxr, maxc;
  		register minr, minc;
  		maxr = ((struct ent *) e->e.o.right) -> row;

--- 38,44 -----
  	case O_REDUCE('*'):
  	    {	register r,c;
  		register struct ent *p;
! 		register double v;
  		register maxr, maxc;
  		register minr, minc;
  		maxr = ((struct ent *) e->e.o.right) -> row;
***************
*** 46,55
  		minc = ((struct ent *) e->e.o.left) -> col;
  		if (minr>maxr) r = maxr, maxr = minr, minr = r;
  		if (minc>maxc) c = maxc, maxc = minc, minc = c;
! 		for (r = minr; r<=maxr; r++)
! 		    for (c = minc; c<=maxc; c++)
! 			if ((p = tbl[r][c]) && p->flags&is_valid)
! 			    v += p->v;
  		return v;
  	    }
      }

--- 47,65 -----
  		minc = ((struct ent *) e->e.o.left) -> col;
  		if (minr>maxr) r = maxr, maxr = minr, minr = r;
  		if (minc>maxc) c = maxc, maxc = minc, minc = c;
! 		if (e->op == O_REDUCE('+')) {
! 		    v = 0;
! 		    for (r = minr; r<=maxr; r++)
! 			for (c = minc; c<=maxc; c++)
! 			    if ((p = tbl[r][c]) && p->flags&is_valid)
! 				v += p->v;
! 		} else {
! 		    v = 1;
! 		    for (r = minr; r<=maxr; r++)
! 			for (c = minc; c<=maxc; c++)
! 			    if ((p = tbl[r][c]) && p->flags&is_valid)
! 				v *= p->v;
! 		}
  		return v;
  	    }
      }
***************
*** 366,371
  	switch (ret->op) {
  	case 'v':
  		ret->e.v = lookat (ret->e.v->row+Rdelta, ret->e.v->col+Cdelta);
  		break;
  	case 'k':
  		break;

--- 376,401 -----
  	switch (ret->op) {
  	case 'v':
  		ret->e.v = lookat (ret->e.v->row+Rdelta, ret->e.v->col+Cdelta);
+ 		break;
+ 	case O_REDUCE('+'):
+ 	case O_REDUCE('*'):
+ 		/*    wmb, 18 Jan 1985
+ 		 * For reduce operators, the enode structure actually
+ 		 * contains a pair of ent pointers instead of a pair
+ 		 * of enode pointers.  The correct way to have done this
+ 		 * would have been to include an arm in the o union
+ 		 * with pointers to upper-left and lower-right ents.
+ 		 */
+ 		(struct ent *) ret->e.o.right =
+ 		   lookat (
+ 		          ((struct ent *)ret->e.o.right)->row+Rdelta,
+ 		          ((struct ent *)ret->e.o.right)->col+Cdelta
+ 		   );
+ 		(struct ent *) ret->e.o.left =
+ 		   lookat (
+ 		          ((struct ent *)ret->e.o.left)->row+Rdelta,
+ 		          ((struct ent *)ret->e.o.left)->col+Cdelta
+ 		   );
  		break;
  	case 'k':
  		break;
---