summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormongo <mongo@iomega>2017-01-28 12:45:58 -0300
committermongo <mongo@iomega>2017-01-28 12:45:58 -0300
commit6056193ce452e2bc4640442cc05df45a90bfdd20 (patch)
treecd324dc7ba8579a0adfe7e0e74902979284ecb88
parent757b8e08c7aedf84fad95f6bb2e9354a9592bf64 (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.c146
-rw-r--r--src/cmds.h2
-rw-r--r--src/cmds_normal.c44
-rw-r--r--src/gram.y3
-rw-r--r--src/interp.c239
-rw-r--r--src/sc.h9
-rw-r--r--src/undo.c40
-rw-r--r--src/yank.c2
8 files changed, 162 insertions, 323 deletions
diff --git a/src/cmds.c b/src/cmds.c
index 1f855a0..a7d2e3c 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -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;
diff --git a/src/cmds.h b/src/cmds.h
index d612cd2..dfd61f8 100644
--- a/src/cmds.h
+++ b/src/cmds.h
@@ -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;
}
diff --git a/src/gram.y b/src/gram.y
index 6529cb3..20b236d 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -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;
diff --git a/src/sc.h b/src/sc.h
index 62e7757..ef5aec5 100644
--- a/src/sc.h
+++ b/src/sc.h
@@ -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)
diff --git a/src/undo.c b/src/undo.c
index 4f96e2e..d40a421 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -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;
diff --git a/src/yank.c b/src/yank.c
index 9fbae97..debda0d 100644
--- a/src/yank.c
+++ b/src/yank.c
@@ -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) )) {