diff options
author | mongo <mongo@iomega> | 2017-01-28 12:45:58 -0300 |
---|---|---|
committer | mongo <mongo@iomega> | 2017-01-28 12:45:58 -0300 |
commit | 6056193ce452e2bc4640442cc05df45a90bfdd20 (patch) | |
tree | cd324dc7ba8579a0adfe7e0e74902979284ecb88 | |
parent | 757b8e08c7aedf84fad95f6bb2e9354a9592bf64 (diff) |
Changes when an ent is removed:
When one or more ents are removed by dr dc sk sh commands, is_deleted flag is set.
That makes REF appears in formulas of ents that depend on the deleted ents.
When one or more ents are removed by 'x' command, is_deleted flag is not set.
That preserves references in other ents that depend on the deleted ents, returning zero as
evaluation result.
-rw-r--r-- | src/cmds.c | 146 | ||||
-rw-r--r-- | src/cmds.h | 2 | ||||
-rw-r--r-- | src/cmds_normal.c | 44 | ||||
-rw-r--r-- | src/gram.y | 3 | ||||
-rw-r--r-- | src/interp.c | 239 | ||||
-rw-r--r-- | src/sc.h | 9 | ||||
-rw-r--r-- | src/undo.c | 40 | ||||
-rw-r--r-- | src/yank.c | 2 |
8 files changed, 162 insertions, 323 deletions
@@ -28,11 +28,10 @@ wchar_t interp_line[BUFFERSIZE]; extern graphADT graph; -// mark_ent_as_deleted (free_ents en sc original): +// mark_ent_as_deleted - this sets is_deleted flag of an ent. // This structure is used to keep ent structs around before they // are actualy deleted (memory freed) to allow the sync_refs routine a chance to fix the // variable references. -// it sets is_deleted flag of an ent. void mark_ent_as_deleted(register struct ent * p) { if (p == NULL) return; //p->flags |= iscleared; @@ -83,8 +82,11 @@ void sync_refs() { } void syncref(register struct enode * e) { - //sc_debug("syncref"); - if ( e == NULL || e->op == ERR_ ) { + //if (e == (struct enode *)0) { + if ( e == NULL || e->op == REF_ || e->op == ERR_ ) { + e->op = REF_; + e->e.o.left = NULL; + e->e.o.right = NULL; return; } else if (e->op & REDUCE) { e->e.r.right.vp = lookat(e->e.r.right.vp->row, e->e.r.right.vp->col); @@ -94,16 +96,12 @@ void syncref(register struct enode * e) { case 'v': //if (e->e.v.vp->flags & iscleared) { if (e->e.v.vp->flags & is_deleted) { - //sc_debug("syncref is deleted"); - //FIXME - //break; - //sc_info("%d %d", e->e.v.vp->row, e->e.v.vp->col); -// e->op = ERR_; -// e->e.o.left = NULL; -// e->e.o.right = NULL; - } else - if (e->e.v.vp->flags & may_sync) - e->e.v.vp = lookat(e->e.v.vp->row, e->e.v.vp->col); + //e->op = ERR_; + //e->e.o.left = NULL; + //e->e.o.right = NULL; + break; + } else if (e->e.v.vp->flags & may_sync) + e->e.v.vp = lookat(e->e.v.vp->row, e->e.v.vp->col); break; case 'k': break; @@ -128,7 +126,7 @@ void deletecol() { return; } - // mark ent of column to erase with isdeleted flag + // mark ent of column to erase with is_deleted flag for (r = 0; r <= maxrow; r++) { pp = ATBL(tbl, r, curcol); if ( *pp != NULL ) { @@ -190,7 +188,10 @@ void copyent(register struct ent * n, register struct ent * p, int dr, int dc, return; } - //n->flags = may_sync; + n->flags = may_sync; + if (p->flags & is_deleted) + n->flags |= is_deleted; + if (special != 'f') { if (p->flags & is_valid) { n->v = p->v; @@ -284,7 +285,7 @@ int etype(register struct enode *e) { } // ignorelock is used when sorting so that locked cells can still be sorted -void erase_area(int sr, int sc, int er, int ec, int ignorelock) { +void erase_area(int sr, int sc, int er, int ec, int ignorelock, int mark_as_deleted) { int r, c; struct ent **pp; @@ -297,12 +298,12 @@ void erase_area(int sr, int sc, int er, int ec, int ignorelock) { } if (sr < 0) - sr = 0; + sr = 0; if (sc < 0) sc = 0; checkbounds(&er, &ec); - // mark the ent as delete + // mark the ent as deleted // Do a lookat() for the upper left and lower right cells of the range // being erased to make sure they are included in the delete buffer so // that pulling cells always works correctly even if the cells at one @@ -319,7 +320,12 @@ void erase_area(int sr, int sc, int er, int ec, int ignorelock) { vertexT * v = getVertex(graph, *pp, 0); if (v != NULL && v->back_edges == NULL ) destroy_vertex(*pp); - mark_ent_as_deleted(*pp); + if (mark_as_deleted) { + mark_ent_as_deleted(*pp); + } else { + clearent(*pp);// free memory + cleanent(*pp); + } *pp = NULL; } } @@ -636,7 +642,6 @@ void insert_col(int after) { void deleterow() { register struct ent ** pp; int r, c; - //struct ent ** tmprow; if (any_locked_cells(currow, 0, currow, maxcol)) { sc_info("Locked cells encountered. Nothing changed"); @@ -656,35 +661,9 @@ void deleterow() { #endif //flush_saved(); - erase_area(currow, 0, currow, maxcol, 0); + erase_area(currow, 0, currow, maxcol, 0, 1); if (currow > maxrow) return; - // Rows are dealt with in numrow groups, each group of rows spaced numrow rows apart. - // save the first row of the group and empty it out - //r = currow; - //tmprow = tbl[r]; - //pp = ATBL(tbl, r, 0); - //for (c = maxcol + 1; --c >= 0; pp++) { - // if (*pp != NULL) { - // sc_debug("is null"); - // mark_ent_as_deleted(*pp); - // *pp = NULL; - // //clearent(*pp); - // //free(*pp); - // // *pp = NULL; - // } - //} - // move the rows, put the deleted, but now empty, row at the end - //for (; r + 1 < maxrows - 1; r++) { - // row_hidden[r] = row_hidden[r+1]; - // tbl[r] = tbl[r + 1]; - // pp = ATBL(tbl, r, 0); - // for (c = 0; c < maxcols; c++, pp++) - // if (*pp) (*pp)->row = r; - //} - //tbl[r] = tmprow; - - //sc_debug("maxrow:%d maxrows:%d", maxrow, maxrows); for (r = currow; r < maxrows - 1; r++) { for (c = 0; c < maxcols; c++) { if (r <= maxrow - 1) { @@ -696,7 +675,6 @@ void deleterow() { } maxrow--; - // sync_refs(); //flush_saved(); // we have to flush only at exit. this is in case we want to UNDO modflg++; @@ -801,54 +779,6 @@ void center(int sr, int sc, int er, int ec) { return; } -/* -void move_area(int dr, int dc, int sr, int sc, int er, int ec) { - struct ent *p; - struct ent **pp; - int deltar, deltac; - int r, c; - - if (sr > er) r = sr; - sr = er; - er = r; - if (sc > ec) - c = sc; - sc = ec; - ec = c; - if (sr < 0) sr = 0; - if (sc < 0) sc = 0; - checkbounds(&er, &ec); - - r = currow; - currow = sr; - c = curcol; - curcol = sc; - - // First we erase the source range, which puts the cells on the delete - // buffer stack. - erase_area(sr, sc, er, ec, 0); - - currow = r; - curcol = c; - deltar = dr - sr; - deltac = dc - sc; - - // Now we erase the destination range, which adds it to the delete buffer - // stack, but then we flush it off. We then move the original source - // range from the stack to the destination range, adjusting the addresses - // as we go, leaving the stack in its original state. - erase_area(dr, dc, er + deltar, ec + deltac, 0); - //flush_saved(); - for (p = delbuf[dbidx]; p; p = p->next) { - pp = ATBL(tbl, p->row + deltar, p->col + deltac); - *pp = p; - p->row += deltar; - p->col += deltac; - p->flags &= ~is_deleted; - } -} -*/ - void chg_mode(char strcmd){ switch (strcmd) { case '=': @@ -925,11 +855,14 @@ void del_selected_cells() { } #endif - erase_area(tlrow, tlcol, brrow, brcol, 0); + //erase_area(tlrow, tlcol, brrow, brcol, 0, 0); + erase_area(tlrow, tlcol, brrow, brcol, 0, 0); modflg++; sync_refs(); //flush_saved(); DO NOT UNCOMMENT! flush_saved shall not be called other than at exit. + EvalAll(); + #ifdef UNDO // here we save in undostruct, all the ents that depends on the deleted one (after the change) for (i = 0; i < n; i++) @@ -939,7 +872,6 @@ void del_selected_cells() { deps = NULL; #endif - EvalAll(); #ifdef UNDO copy_to_undostruct(tlrow, tlcol, brrow, brcol, 'a'); @@ -1032,9 +964,15 @@ struct ent * lookat(int row, int col) { checkbounds(&row, &col); pp = ATBL(tbl, row, col); - if ( *pp == NULL ) { - //*pp = (struct ent *) scxmalloc( (unsigned) sizeof(struct ent) ); - *pp = (struct ent *) malloc( (unsigned) sizeof(struct ent) ); + if ( *pp == NULL) { + //if (freeents == NULL) { + //*pp = (struct ent *) scxmalloc( (unsigned) sizeof(struct ent) ); + *pp = (struct ent *) malloc( (unsigned) sizeof(struct ent) ); + //} else { + // sc_debug("lookat. reuse of deleted ent row:%d col:%d", row, col); + // *pp = freeents; + // freeents = freeents->next; + //} (*pp)->label = (char *) 0; (*pp)->flags = may_sync; (*pp)->expr = (struct enode *) 0; @@ -1056,8 +994,8 @@ struct ent * lookat(int row, int col) { void cleanent(struct ent * p) { if (!p) return; p->label = (char *) 0; - p->row = 0; - p->col = 0; + //p->row = 0; + //p->col = 0; p->flags = may_sync; p->expr = (struct enode *) 0; p->v = (double) 0.0; @@ -59,7 +59,7 @@ void center(int sr, int sc, int er, int ec); void doformat(int c1, int c2, int w, int p, int r); struct enode; int etype(register struct enode *e); -void erase_area(int sr, int sc, int er, int ec, int ignorelock); +void erase_area(int sr, int sc, int er, int ec, int ignorelock, int mark_ent_as_deleted); void auto_justify(int ci, int cf, int min); void valueize_area(int sr, int sc, int er, int ec); void sync_refs(); diff --git a/src/cmds_normal.c b/src/cmds_normal.c index 57b9050..ed45208 100644 --- a/src/cmds_normal.c +++ b/src/cmds_normal.c @@ -677,6 +677,7 @@ void do_normalmode(struct block * buf) { if (bs != 2) return; int ic = cmd_multiplier; // orig + // deleterow if (buf->pnext->value == L'r') { if (any_locked_cells(currow, 0, currow + cmd_multiplier, maxcol)) { sc_error("Locked cells encountered. Nothing changed"); @@ -690,13 +691,16 @@ void do_normalmode(struct block * buf) { fix_marks(-ic, 0, currow + ic - 1, maxrow, 0, maxcol); yank_area(currow, 0, currow - 1 + cmd_multiplier, maxcol, 'r', ic); while (ic--) deleterow(); - EvalAll(); + if (atoi(get_conf_value("autocalc")) && ! loading) EvalAll(); #ifdef UNDO copy_to_undostruct(currow, 0, currow - 1 + cmd_multiplier, maxcol, 'a'); end_undo_action(); #endif if (cmd_multiplier > 0) cmd_multiplier = 0; + + + // deletecol } else if (buf->pnext->value == L'c') { if (any_locked_cells(0, curcol, maxrow, curcol + cmd_multiplier)) { sc_error("Locked cells encountered. Nothing changed"); @@ -709,22 +713,58 @@ void do_normalmode(struct block * buf) { #endif fix_marks(0, -ic, 0, maxrow, curcol - 1 + ic, maxcol); // FIXME yank_area(0, curcol, maxrow, curcol + cmd_multiplier - 1, 'c', ic); + +#ifdef UNDO + // here we save in undostruct, all the ents that depends on the deleted one (before change) + extern struct ent_ptr * deps; + int i, n = 0, w=ic; + ents_that_depends_on_range(0, curcol, maxrow, curcol - 1 + ic); + if (deps != NULL) { + n = deps->vf; + for (i = 0; i < n; i++) + copy_to_undostruct(deps[i].vp->row, deps[i].vp->col, deps[i].vp->row, deps[i].vp->col, 'd'); + } +#endif + while (ic--) { #ifdef UNDO add_undo_col_format(curcol-ic+1, 'R', fwidth[curcol], precision[curcol], realfmt[curcol]); #endif deletecol(); } + + // Eval entire graph + // TODO it should eval only necessary ents + if (atoi(get_conf_value("autocalc")) && ! loading) EvalAll(); + #ifdef UNDO + while (w--) { + // here we save in undostruct, all the ents that depends on the deleted one (after change) + if (deps != NULL) { + n = deps->vf; + for (i = 0; i < n; i++) { + if (deps[i].vp->col >= curcol) + copy_to_undostruct(deps[i].vp->row, deps[i].vp->col+1, deps[i].vp->row, deps[i].vp->col+1, 'a'); + else + copy_to_undostruct(deps[i].vp->row, deps[i].vp->col, deps[i].vp->row, deps[i].vp->col, 'a'); + } + free(deps); + deps = NULL; + } + } copy_to_undostruct(0, curcol, maxrow, curcol + cmd_multiplier - 1, 'a'); end_undo_action(); #endif if (cmd_multiplier > 0) cmd_multiplier = 0; + + + } else if (buf->pnext->value == L'd') { del_selected_cells(); + if (atoi(get_conf_value("autocalc")) && ! loading) EvalAll(); } - if (atoi(get_conf_value("autocalc")) && ! loading) EvalAll(); + update(TRUE); break; } @@ -347,6 +347,7 @@ token K_WHITE token K_NUMITER */ %token K_ERR +%token K_REF %token K_LOCALE %token K_SET8BIT %token K_ASCII @@ -841,6 +842,8 @@ term: var { $$ = new_var(O_VAR, $1); } | '@' K_CHR '(' e ')' { $$ = new(CHR, $4, ENULL);} | '@' K_ERR { $$ = new(ERR_, ENULL, ENULL); } | K_ERR { $$ = new(ERR_, ENULL, ENULL); } + | '@' K_REF { $$ = new(REF_, ENULL, ENULL); } + | K_REF { $$ = new(REF_, ENULL, ENULL); } /* | '@' K_NUMITER { $$ = new(NUMITER, ENULL, ENULL);} | '@' K_BLACK { $$ = new(BLACK, ENULL, ENULL); } diff --git a/src/interp.c b/src/interp.c index 606f466..4fc4867 100644 --- a/src/interp.c +++ b/src/interp.c @@ -684,8 +684,9 @@ double dolmin(struct enode * ep) { } double eval(register struct ent * ent, register struct enode * e) { - if (cellerror == CELLERROR || (ent && ent->cellerror == CELLERROR)) + if (cellerror == CELLERROR || (ent && ent->cellerror == CELLERROR)) { return (double) 0; + } if (e == (struct enode *) 0) { cellerror = CELLINVALID; @@ -773,8 +774,8 @@ double eval(register struct ent * ent, register struct enode * e) { ent->cellerror = CELLERROR; return (double) 0; } - int row, col; + int row, col; if (vp && (rowoffset || coloffset)) { row = e->e.v.vf & FIX_ROW ? vp->row : vp->row + rowoffset; col = e->e.v.vf & FIX_COL ? vp->col : vp->col + coloffset; @@ -782,29 +783,41 @@ double eval(register struct ent * ent, register struct enode * e) { vp = *ATBL(tbl, row, col); } - if (! vp || vp->flags & is_deleted) { - //sc_debug("eval O_VAR - ent referenced in enode was deleted"); - // FIXME if ent is removed, it should not put zero - // as a result of every cell that references it. - // just return zero to the removed oned. + if (vp && vp->flags & iscleared) { + e->op = ERR_; + return (double) 0; + } + + if (!vp) { + e->op = REF_; + e->e.o.left = NULL; + e->e.o.right = NULL; + return (double) 0; + } + + if (!vp || vp->flags & is_deleted) { + + e->op = REF_; + e->e.o.left = NULL; + e->e.o.right = NULL; + + if (getVertex(graph, vp, 0) != NULL) destroy_vertex(vp); //cellerror = CELLERROR; return (double) 0; } // here we store the dependences in a graph - if (ent && vp) { + if (ent && vp) GraphAddEdge( getVertex(graph, lookat(ent->row, ent->col), 1), getVertex(graph, lookat(vp->row, vp->col), 1) ) ; - //sc_debug("sc_eval added ent in graph: %d %d %d %d repct:%d ", ent->row, ent->col, vp->row, vp->col, repct); - } if (vp->cellerror) { cellerror = CELLINVALID; } - if (vp->cellerror == CELLERROR) + if (vp->cellerror == CELLERROR) { return (double) 0; - + } return (vp->v); } case SUM: @@ -831,7 +844,6 @@ double eval(register struct ent * ent, register struct enode * e) { for (row=minr; row <= maxr; row++) { for (col=minc; col <= maxc; col++) { if (ent == NULL) continue; - //sc_debug("r:%d c:%d %d %d", row, col, ent->row, ent->col); GraphAddEdge(getVertex(graph, lookat(ent->row, ent->col), 1), getVertex(graph, lookat(row, col), 1)); } } @@ -965,8 +977,10 @@ double eval(register struct ent * ent, register struct enode * e) { case LASTROW: return ((double) maxrow); case LASTCOL: return ((double) maxcol); //case NUMITER: return ((double) repct); - case ERR_: cellerror = CELLERROR; + case ERR_: + cellerror = CELLERROR; return ((double) 0); + case REF_: return ((double) 0); case PI_: return ((double) M_PI); case BLACK: return ((double) COLOR_BLACK); case RED: return ((double) COLOR_RED); @@ -1430,196 +1444,6 @@ struct enode * new_str(char * s) { return (p); } -/* -void copy(struct ent *dv1, struct ent *dv2, struct ent *v1, struct ent *v2) { - struct ent *p; -// struct ent *n; - static int minsr = -1, minsc = -1; - static int maxsr = -1, maxsc = -1; - int mindr, mindc; - int maxdr, maxdc; -// int vr, vc; - int r, c; - int deltar, deltac; - - if (dv1) { - mindr = dv1->row; - mindc = dv1->col; - maxdr = dv2->row; - maxdc = dv2->col; - if (mindr > maxdr) r = maxdr, maxdr = mindr, mindr = r; - if (mindc > maxdc) c = maxdc, maxdc = mindc, mindc = c; - } else { - //if (showrange) { - // showrange = 0; - mindr = showsr < currow ? showsr : currow; - mindc = showsc < curcol ? showsc : curcol; - maxdr = showsr > currow ? showsr : currow; - maxdc = showsc > curcol ? showsc : curcol; - } else if (v1) { - // Set up the default source range for the "c." command. - minsr = maxsr = v1->row; - minsc = maxsc = v1->col; - return; - } else { - mindr = maxdr = currow; - mindc = maxdc = curcol; - } - } - - if (v1) { - minsr = v1->row; - minsc = v1->col; - maxsr = v2->row; - maxsc = v2->col; - if (minsr > maxsr) r = maxsr, maxsr = minsr, minsr = r; - if (minsc > maxsc) c = maxsc, maxsc = minsc, minsc = c; - } else if (dv1 == NULL || v2 != NULL) { -// if (qbuf && delbuf[qbuf]) { -// delbuf[++dbidx] = delbuf[qbuf]; -// delbuffmt[dbidx] = delbuffmt[qbuf]; -// } else if (dbidx < 0) return; -// minsr = maxrow; -// minsc = maxcol; -// maxsr = 0; -// maxsc = 0; -// for (p = delbuf[dbidx]; p; p = p->next) { -// if (p->row < minsr) minsr = p->row; -// if (p->row > maxsr) maxsr = p->row; -// if (p->col < minsc) minsc = p->col; -// if (p->col > maxsc) maxsc = p->col; -// } - //} else if (showrange && !(showsr == currow && showsc == curcol && - mindr == currow && mindc == curcol && - maxdr == currow && maxdc == curcol)) { - minsr = showsr < currow ? showsr : currow; - minsc = showsc < curcol ? showsc : curcol; - maxsr = showsr > currow ? showsr : currow; - maxsc = showsc > curcol ? showsc : curcol; - } else - if (minsr == -1) return; - - checkbounds(&maxdr, &maxdc); - - if (maxdr - mindr < maxsr - minsr) maxdr = mindr + (maxsr - minsr); - if (maxdc - mindc < maxsc - minsc) maxdc = mindc + (maxsc - minsc); - if (dv1 && (v1 || !v2)) - yank_area(minsr, minsc, maxsr, maxsc); - erase_area(mindr, mindc, maxdr, maxdc, 0); - sync_refs(); - flush_saved(); - - sc_error("Copying..."); - if (!loading) - refresh(); -// p = delbuf[dbidx]; -// if (minsr == maxsr && minsc == maxsc) { -// // Source is a single cell -// for (deltar = mindr - p->row; deltar <= maxdr - p->row; deltar++) -// for (deltac = mindc - p->col; deltac <= maxdc - p->col; deltac++) -// copydbuf(deltar, deltac); -// } else if (minsr == maxsr) { -// // Source is a single row -// deltac = mindc - p->col; -// for (deltar = mindr - p->row; deltar <= maxdr - p->row; deltar++) -// copydbuf(deltar, deltac); -// } else if (minsc == maxsc) { -// // Source is a single column -// deltar = mindr - p->row; -// for (deltac = mindc - p->col; deltac <= maxdc - p->col; deltac++) -// copydbuf(deltar, deltac); -// } else { -// // Everything else -// deltar = mindr - p->row; -// deltac = mindc - p->col; -// copydbuf(deltar, deltac); -// } - - if (dv1 && (v1 || !v2)) { - sync_refs(); - flush_saved(); - } - - if (dv1 == NULL) { -// if (qbuf && delbuf[qbuf]) { -// delbuf[dbidx] = NULL; -// delbuffmt[dbidx--] = NULL; -// } - qbuf = 0; - } - sc_error("Copy done."); -} - -void copydbuf(int deltar, int deltac) { - int vr, vc; - struct ent *p = delbuf[dbidx]; - struct ent *n; - - while (p) { - vr = p->row + deltar; - vc = p->col + deltac; - n = lookat(vr, vc); - if (n->flags&is_locked) continue; - copyent(n, p, deltar, deltac, 0, 0, maxrow, maxcol, 0); - p = p->next; - } -} - -// ERASE a Range of cells -// this function should not be used -void eraser(struct ent *v1, struct ent *v2) { - flush_saved(); - erase_area(v1->row, v1->col, v2->row, v2->col, 0); - sync_refs(); - modflg++; -} - -// YANK a Range of cells -void yankr(struct ent *v1, struct ent *v2) { - int i, qtmp; - struct ent *obuf = NULL; - - if (dbidx < 0) dbidx++; - delbuf[dbidx] = delbuf[DELBUFSIZE - 10]; - delbuf[DELBUFSIZE - 10] = NULL; - delbuffmt[dbidx] = delbuffmt[DELBUFSIZE - 10]; - delbuffmt[DELBUFSIZE - 10] = NULL; - for (i = dbidx + 1; i < DELBUFSIZE; i++) { - if (delbuf[i] == delbuf[dbidx]) { - delbuf[dbidx] = NULL; - delbuffmt[dbidx] = NULL; - break; - } - } - flush_saved(); - if (qbuf) { - if (dbidx < 0) dbidx++; - delbuf[dbidx] = delbuf[qbuf]; - delbuffmt[dbidx] = delbuffmt[qbuf]; - flush_saved(); - obuf = delbuf[qbuf]; // orig. contents of the del. buffer - } - qtmp = qbuf; - qbuf = 0; - yank_area(v1->row, v1->col, v2->row, v2->col); - qbuf = qtmp; - for (i = 0; i < DELBUFSIZE; i++) - if ((obuf && delbuf[i] == obuf) || (qbuf && i == qbuf)) { - delbuf[i] = delbuf[dbidx]; - delbuffmt[i] = delbuffmt[dbidx]; - } - qbuf = 0; - delbuf[DELBUFSIZE - 10] = delbuf[dbidx]; - delbuffmt[DELBUFSIZE - 10] = delbuffmt[dbidx]; -} - -// MOVE a Range of cells -void mover(struct ent *d, struct ent *v1, struct ent *v2) { - move_area(d->row, d->col, v1->row, v1->col, v2->row, v2->col); - sync_refs(); -} -*/ - // Goto subroutines */ void g_free() { switch (gs.g_type) { @@ -2137,7 +1961,9 @@ void let(struct ent * v, struct enode * e) { if (locked_cell(v->row, v->col)) return; + //if (getVertex(graph, v, 0) != NULL) destroy_vertex(v); + if (v->row == currow && v->col == curcol) cellassign = 1; if (loading && ! isconstant) @@ -2184,7 +2010,7 @@ void let(struct ent * v, struct enode * e) { v->expr = e; v->flags &= ~is_strexpr; - eval(v, e); // ADDED - TODO here we store the cell dependences in a graph + eval(v, e); // ADDED - here we store the cell dependences in a graph } changed++; @@ -2527,6 +2353,9 @@ void decompile(register struct enode *e, int priority) { case ERR_: for (s = "@err"; (line[linelim++] = *s++); ); linelim--; break; + case REF_: for (s = "@ref"; (line[linelim++] = *s++); ); + linelim--; + break; case PI_: for (s = "@pi"; (line[linelim++] = *s++); ); linelim--; break; @@ -221,14 +221,7 @@ struct go_save { #define NUMITER (OP_BASE + 66) #define ERR_ (OP_BASE + 67) #define PI_ (OP_BASE + 68) -//#define SC_BLACK (OP_BASE + 69) -//#define SC_RED (OP_BASE + 70) -//#define SC_GREEN (OP_BASE + 71) -//#define SC_YELLOW (OP_BASE + 72) -//#define SC_BLUE (OP_BASE + 73) -//#define SC_MAGENTA (OP_BASE + 74) -//#define SC_CYAN (OP_BASE + 75) -//#define SC_WHITE (OP_BASE + 76) +#define REF_ (OP_BASE + 69) #define SLEN (OP_BASE + 77) #define ASCII (OP_BASE + 78) #define CHR (OP_BASE + 79) @@ -80,6 +80,7 @@ NOT implemented: #include "color.h" // for set_ucolor #include "marks.h" #include "shift.h" +#include "dep_graph.h" // undolist static struct undo * undo_list = NULL; @@ -435,6 +436,7 @@ void do_undo() { i = i->next; } + // Change cursor position //if (ul->removed != NULL) { // currow = ul->removed->row; @@ -447,7 +449,6 @@ void do_undo() { struct ent * e_now = lookat(j->row, j->col); //(void) copyent(e_now, j, 0, 0, 0, 0, j->row, j->col, 0); (void) copyent(e_now, j, 0, 0, 0, 0, 0, 0, 0); - e_now->flags &= ~is_deleted; j = j->next; } @@ -497,6 +498,23 @@ void do_undo() { } } + // for every ent in added and removed, we reeval expression to update graph + struct ent * ie = ul->added; + while (ie != NULL) { + struct ent * p; + if ((p = *ATBL(tbl, ie->row, ie->col)) && p->expr) + EvalJustOneVertex(p, ie->row, ie->col, 1); + ie = ie->next; + } + ie = ul->removed; + while (ie != NULL) { + struct ent * p; + if ((p = *ATBL(tbl, ie->row, ie->col)) && p->expr) + EvalJustOneVertex(p, ie->row, ie->col, 1); + ie = ie->next; + } + + // Restores cursor position currow = ori_currow; curcol = ori_curcol; @@ -566,6 +584,7 @@ void do_redo() { // Remove 'ent' elements struct ent * i = ul->removed; while (i != NULL) { + //sc_debug("redo removed: %d %d", i->row, i->col); struct ent * pp = *ATBL(tbl, i->row, i->col); clearent(pp); cleanent(pp); @@ -582,9 +601,9 @@ void do_redo() { struct ent * j = ul->added; while (j != NULL) { struct ent * e_now = lookat(j->row, j->col); + //sc_debug("redo added: %d %d", j->row, j->col); //(void) copyent(e_now, j, 0, 0, 0, 0, j->row, j->col, 0); (void) copyent(e_now, j, 0, 0, 0, 0, 0, 0, 0); - e_now->flags &= ~is_deleted; j = j->next; } @@ -634,6 +653,23 @@ void do_redo() { } } + // for every ent in added and removed, we reeval expression to update graph + struct ent * ie = ul->added; + while (ie != NULL) { + struct ent * p; + if ((p = *ATBL(tbl, ie->row, ie->col)) && p->expr) + EvalJustOneVertex(p, ie->row, ie->col, 1); + ie = ie->next; + } + ie = ul->removed; + while (ie != NULL) { + struct ent * p; + if ((p = *ATBL(tbl, ie->row, ie->col)) && p->expr) + EvalJustOneVertex(p, ie->row, ie->col, 1); + ie = ie->next; + } + + // Restores cursor position currow = ori_currow; curcol = ori_curcol; @@ -213,7 +213,7 @@ int paste_yanked_ents(int above, int type_paste) { // here we delete current content of "destino" ent if (type_paste == 'a' || type_paste == 's') - erase_area(yl->row + diffr, yl->col + diffc, yl->row + diffr, yl->col + diffc, ignorelock); + erase_area(yl->row + diffr, yl->col + diffc, yl->row + diffr, yl->col + diffc, ignorelock, 0); /*struct ent **pp = ATBL(tbl, yl->row + diffr, yl->col + diffc); if (*pp && ( ! ((*pp)->flags & is_locked) )) { |