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; ---