Commit 460d3cbc authored by Morten Welinder's avatar Morten Welinder

Improve do_expr_tree_relocate.

parent 760eec88
1999-05-16 Morten Welinder <terra@diku.dk>
* src/expr.c (do_expr_tree_relocate): Change to use lazy copying
scheme -- this should improve sharing. (Until someone saves and
reloads, of course. More about that at a later time.)
(expr_tree_invalidate_references): Quiet.
(expr_tree_fixup_references): Quiet.
* src/cell.c (cell_relocate): Only update if changed.
* src/expr.c (evaluate_level): Deleted.
(bigger_prec): Deleted.
(do_expr_decode_tree): Handle left/right associativity.
......
1999-05-16 Morten Welinder <terra@diku.dk>
* src/expr.c (do_expr_tree_relocate): Change to use lazy copying
scheme -- this should improve sharing. (Until someone saves and
reloads, of course. More about that at a later time.)
(expr_tree_invalidate_references): Quiet.
(expr_tree_fixup_references): Quiet.
* src/cell.c (cell_relocate): Only update if changed.
* src/expr.c (evaluate_level): Deleted.
(bigger_prec): Deleted.
(do_expr_decode_tree): Handle left/right associativity.
......
1999-05-16 Morten Welinder <terra@diku.dk>
* src/expr.c (do_expr_tree_relocate): Change to use lazy copying
scheme -- this should improve sharing. (Until someone saves and
reloads, of course. More about that at a later time.)
(expr_tree_invalidate_references): Quiet.
(expr_tree_fixup_references): Quiet.
* src/cell.c (cell_relocate): Only update if changed.
* src/expr.c (evaluate_level): Deleted.
(bigger_prec): Deleted.
(do_expr_decode_tree): Handle left/right associativity.
......
1999-05-16 Morten Welinder <terra@diku.dk>
* src/expr.c (do_expr_tree_relocate): Change to use lazy copying
scheme -- this should improve sharing. (Until someone saves and
reloads, of course. More about that at a later time.)
(expr_tree_invalidate_references): Quiet.
(expr_tree_fixup_references): Quiet.
* src/cell.c (cell_relocate): Only update if changed.
* src/expr.c (evaluate_level): Deleted.
(bigger_prec): Deleted.
(do_expr_decode_tree): Handle left/right associativity.
......
......@@ -1026,8 +1026,10 @@ cell_relocate (Cell *cell, int col_diff, int row_diff)
new_tree = expr_tree_relocate (cell->parsed_node, col_diff, row_diff);
expr_tree_unref (cell->parsed_node);
cell->parsed_node = new_tree;
if (new_tree) {
expr_tree_unref (cell->parsed_node);
cell->parsed_node = new_tree;
}
}
/* The following call also relinks the cell. */
cell_formula_changed (cell);
......
......@@ -1453,56 +1453,95 @@ expr_decode_tree (ExprTree *tree, Sheet *sheet, int col, int row)
static ExprTree *
do_expr_tree_relocate (ExprTree *tree, int coldiff, int rowdiff)
{
ExprTree *new_tree;
switch (tree->oper){
case OPER_ANY_BINARY: {
ExprTree *a, *b, *new_tree;
new_tree = g_new (ExprTree, 1);
*new_tree = *tree;
a = do_expr_tree_relocate (tree->u.binary.value_a, coldiff, rowdiff);
b = do_expr_tree_relocate (tree->u.binary.value_b, coldiff, rowdiff);
if (!a && !b) return NULL;
new_tree->ref_count = 1;
if (!a)
expr_tree_ref ((a = tree->u.binary.value_a));
if (!b)
expr_tree_ref ((b = tree->u.binary.value_b));
new_tree = g_new (ExprTree, 1);
new_tree->oper = tree->oper;
new_tree->ref_count = 1;
new_tree->u.binary.value_a = a;
new_tree->u.binary.value_b = b;
return new_tree;
}
switch (tree->oper){
case OPER_ANY_BINARY:
new_tree->u.binary.value_a =
do_expr_tree_relocate (tree->u.binary.value_a, coldiff, rowdiff);
new_tree->u.binary.value_b =
do_expr_tree_relocate (tree->u.binary.value_b, coldiff, rowdiff);
break;
case OPER_ANY_UNARY: {
ExprTree *a, *new_tree;
case OPER_ANY_UNARY:
new_tree->u.value = do_expr_tree_relocate (tree->u.value, coldiff, rowdiff);
break;
a = do_expr_tree_relocate (tree->u.value, coldiff, rowdiff);
if (!a) return NULL;
new_tree = g_new (ExprTree, 1);
new_tree->oper = tree->oper;
new_tree->ref_count = 1;
new_tree->u.value = a;
return new_tree;
}
case OPER_FUNCALL: {
GList *l, *arg_list;
gboolean any = FALSE;
GList *new_args = NULL;
GList *l;
symbol_ref (tree->u.function.symbol);
new_tree->u.function.arg_list = NULL;
for (l = tree->u.function.arg_list; l; l = l->next) {
ExprTree *arg = do_expr_tree_relocate (l->data, coldiff, rowdiff);
new_args = g_list_append (new_args, arg);
if (arg) any = TRUE;
}
for (l = tree->u.function.arg_list; l; l = l->next){
ExprTree *tree = l->data;
if (any) {
ExprTree *new_tree;
GList *m;
new_tree->u.function.arg_list =
g_list_append (new_tree->u.function.arg_list,
do_expr_tree_relocate (tree, coldiff, rowdiff));
for (l = tree->u.function.arg_list, m = new_args; l; l = l->next, m = m->next) {
if (m->data == NULL)
expr_tree_ref ((m->data = l->data));
}
new_tree = g_new (ExprTree, 1);
new_tree->oper = OPER_FUNCALL;
new_tree->ref_count = 1;
symbol_ref ((new_tree->u.function.symbol = tree->u.function.symbol));
new_tree->u.function.arg_list = new_args;
return new_tree;
} else {
g_list_free (new_args);
return NULL;
}
break;
}
case OPER_VAR: {
CellRef *ref;
ref = &new_tree->u.ref;
ref->col -= coldiff;
ref->row -= rowdiff;
break;
ExprTree *new_tree;
new_tree = g_new (ExprTree, 1);
new_tree->oper = tree->oper;
new_tree->ref_count = 1;
new_tree->u.ref = tree->u.ref;
new_tree->u.ref.col -= coldiff;
new_tree->u.ref.row -= rowdiff;
return new_tree;
}
case OPER_CONSTANT:
new_tree->u.constant = value_duplicate (tree->u.constant);
if (new_tree->u.constant->type == VALUE_CELLRANGE){
case OPER_CONSTANT: {
if (tree->u.constant->type == VALUE_CELLRANGE) {
ExprTree *new_tree;
CellRef *ref;
new_tree = g_new (ExprTree, 1);
new_tree->oper = tree->oper;
new_tree->ref_count = 1;
new_tree->u.constant = value_duplicate (tree->u.constant);
ref = &new_tree->u.constant->v.cell_range.cell_a;
ref->col -= coldiff;
ref->row -= rowdiff;
......@@ -1510,14 +1549,25 @@ do_expr_tree_relocate (ExprTree *tree, int coldiff, int rowdiff)
ref = &new_tree->u.constant->v.cell_range.cell_b;
ref->col -= coldiff;
ref->row -= rowdiff;
break;
}
break;
return new_tree;
} else
return NULL;
}
}
return new_tree;
g_assert_not_reached ();
return NULL;
}
/*
* Create a copy of an expression they way it should look after being
* moved (coldiff,rowdiff) with a sheet.
*
* A return value of NULL means "no change necessary". If a copy really
* is desired in that case, a simple expr_tree_ref should do.
*/
ExprTree *
expr_tree_relocate (ExprTree *tree, int coldiff, int rowdiff)
{
......@@ -1749,7 +1799,7 @@ expr_tree_invalidate_references (ExprTree *src, Sheet *src_sheet,
info.row = row;
info.rowcount = rowcount;
{
if (0) {
char *str;
str = expr_decode_tree (src, src_sheet, src_col, src_row);
printf ("Invalidate: %s: [%s]\n", cell_name (src_col, src_row), str);
......@@ -1758,7 +1808,7 @@ expr_tree_invalidate_references (ExprTree *src, Sheet *src_sheet,
dst = do_expr_tree_invalidate_references (src, &info);
{
if (0) {
char *str;
str = dst ? expr_decode_tree (dst, src_sheet, src_col, src_row) : g_strdup ("*");
printf ("Invalidate: %s: [%s]\n\n", cell_name (src_col, src_row), str);
......@@ -1982,7 +2032,7 @@ expr_tree_fixup_references (ExprTree *src, Sheet *src_sheet,
info.colcount = (coldelta < 0) ? -coldelta : coldelta;
info.rowcount = (rowdelta < 0) ? -rowdelta : rowdelta;
{
if (0) {
char *str;
str = expr_decode_tree (src, src_sheet, src_col, src_row);
printf ("Fixup: %s: [%s]\n", cell_name (src_col, src_row), str);
......@@ -1991,7 +2041,7 @@ expr_tree_fixup_references (ExprTree *src, Sheet *src_sheet,
dst = do_expr_tree_fixup_references (src, &info);
{
if (0) {
char *str;
str = dst ? expr_decode_tree (dst, src_sheet, src_col, src_row) : g_strdup ("*");
printf ("Fixup: %s: [%s]\n\n", cell_name (src_col, src_row), str);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment