Commit 1dde747a authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

it is ok to not rewrite the expression here. (cb_name_invalidate_sheet) :

2001-12-25  Jody Goldberg <jody@gnome.org>

	* src/eval.c (invalidate_refs) : it is ok to not rewrite the
	  expression here.
	(cb_name_invalidate_sheet) : new.
	(do_deps_destroy) : use here.

	* src/expr-name.c (expr_name_invalidate_refs_sheet) : delete.
	(expr_name_invalidate_refs_wb) : delete.
	(expr_name_handle_references) : new.
	(expr_name_set_expr) : use it here.
	(expr_name_add) : Use expr_name_set_expr.
	(expr_name_unref) : and here.
	(expr_name_link_deps) : if the dependent being updated is going to be
	  deleted do not relink or queue for recalc.
parent e46eeafc
......@@ -7,8 +7,6 @@ release, and longer term bugs.
Release Critical
----------------
- name refering to deleted sheet
- names refereing to other names
- research reports graph data guru crash
Pending Patches
......
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/eval.c (invalidate_refs) : it is ok to not rewrite the
expression here.
(cb_name_invalidate_sheet) : new.
(do_deps_destroy) : use here.
* src/expr-name.c (expr_name_invalidate_refs_sheet) : delete.
(expr_name_invalidate_refs_wb) : delete.
(expr_name_handle_references) : new.
(expr_name_set_expr) : use it here.
(expr_name_add) : Use expr_name_set_expr.
(expr_name_unref) : and here.
(expr_name_link_deps) : if the dependent being updated is going to be
deleted do not relink or queue for recalc.
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/expr-name.c (expr_name_invalidate_refs_wb) : Implement in terms
......
......@@ -32,6 +32,7 @@ Jody:
* Fix format leak (thanks Morten)
* Fix data validation.
* Dirty workbook when modifying summary info.
* Invalidate names refering to deleted expressions.
Morten:
* Fix DATE.
......
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/eval.c (invalidate_refs) : it is ok to not rewrite the
expression here.
(cb_name_invalidate_sheet) : new.
(do_deps_destroy) : use here.
* src/expr-name.c (expr_name_invalidate_refs_sheet) : delete.
(expr_name_invalidate_refs_wb) : delete.
(expr_name_handle_references) : new.
(expr_name_set_expr) : use it here.
(expr_name_add) : Use expr_name_set_expr.
(expr_name_unref) : and here.
(expr_name_link_deps) : if the dependent being updated is going to be
deleted do not relink or queue for recalc.
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/expr-name.c (expr_name_invalidate_refs_wb) : Implement in terms
......
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/eval.c (invalidate_refs) : it is ok to not rewrite the
expression here.
(cb_name_invalidate_sheet) : new.
(do_deps_destroy) : use here.
* src/expr-name.c (expr_name_invalidate_refs_sheet) : delete.
(expr_name_invalidate_refs_wb) : delete.
(expr_name_handle_references) : new.
(expr_name_set_expr) : use it here.
(expr_name_add) : Use expr_name_set_expr.
(expr_name_unref) : and here.
(expr_name_link_deps) : if the dependent being updated is going to be
deleted do not relink or queue for recalc.
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/expr-name.c (expr_name_invalidate_refs_wb) : Implement in terms
......
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/eval.c (invalidate_refs) : it is ok to not rewrite the
expression here.
(cb_name_invalidate_sheet) : new.
(do_deps_destroy) : use here.
* src/expr-name.c (expr_name_invalidate_refs_sheet) : delete.
(expr_name_invalidate_refs_wb) : delete.
(expr_name_handle_references) : new.
(expr_name_set_expr) : use it here.
(expr_name_add) : Use expr_name_set_expr.
(expr_name_unref) : and here.
(expr_name_link_deps) : if the dependent being updated is going to be
deleted do not relink or queue for recalc.
2001-12-25 Jody Goldberg <jody@gnome.org>
* src/expr-name.c (expr_name_invalidate_refs_wb) : Implement in terms
......
......@@ -988,21 +988,19 @@ sheet_region_queue_recalc (Sheet const *sheet, Range const *r)
/*******************************************************************/
static void
inline static void
invalidate_refs (Dependent *dep, ExprRewriteInfo const *rwinfo)
{
ExprTree *newtree;
newtree = expr_rewrite (dep->expression, rwinfo);
ExprTree *newtree = expr_rewrite (dep->expression, rwinfo);
/*
* We are told this dependent depends on this region, hence if newtree
* is null then either we did not depend on it ( ie. serious breakage )
* or we had a duplicate reference and we have already removed it.
/* We are told this dependent depends on this region, hence if newtree
* is null then either
* 1) we did not depend on it ( ie. serious breakage )
* 2j we had a duplicate reference and we have already removed it.
* 3) We depended on things via a name which will be invalidated elsewhere
*/
g_return_if_fail (newtree != NULL);
dependent_set_expr (dep, newtree);
if (newtree != NULL)
dependent_set_expr (dep, newtree);
}
/*
......@@ -1041,6 +1039,15 @@ cb_dep_hash_invalidate (gpointer key, gpointer value, gpointer closure)
g_free (depany);
}
static void
cb_name_invalidate_sheet (gpointer key, gpointer value, gpointer rwinfo)
{
NamedExpression *nexpr = key;
ExprTree *new_expr = expr_rewrite (nexpr->t.expr_tree, rwinfo);
g_return_if_fail (new_expr != NULL);
expr_name_set_expr (nexpr, new_expr);
}
/*
* do_deps_destroy :
* Invalidate references of all kinds to the target region described by
......@@ -1086,6 +1093,8 @@ do_deps_destroy (Sheet *sheet, ExprRewriteInfo const *rwinfo)
}
if (deps->names) {
g_hash_table_foreach (deps->names,
cb_name_invalidate_sheet, (gpointer)rwinfo);
g_hash_table_destroy (deps->names);
deps->names = NULL;
}
......
......@@ -304,14 +304,14 @@ name_guru_populate_list (NameGuruState *state)
}
/**
* cb_name_guru_remove:
* name_guru_remove:
* @ignored:
* @state:
*
* Remove the state->cur_name
**/
static void
cb_name_guru_remove (GtkWidget *ignored, NameGuruState *state)
name_guru_remove (GtkWidget *ignored, NameGuruState *state)
{
g_return_if_fail (state != NULL);
g_return_if_fail (state->cur_name != NULL);
......@@ -327,7 +327,7 @@ cb_name_guru_remove (GtkWidget *ignored, NameGuruState *state)
}
/**
* cb_name_guru_add:
* name_guru_add:
* @state:
*
* Update or add a NamedExpression from the values in the gtkentries.
......@@ -335,7 +335,7 @@ cb_name_guru_remove (GtkWidget *ignored, NameGuruState *state)
* Return Value: FALSE if the expression was invalid, TRUE otherwise
**/
static gboolean
cb_name_guru_add (NameGuruState *state)
name_guru_add (NameGuruState *state)
{
NamedExpression *expr_name;
ParseError perr;
......@@ -418,7 +418,7 @@ cb_name_guru_clicked (GtkWidget *button, NameGuruState *state)
wbcg_set_entry (state->wbcg, NULL);
if (button == state->delete_button) {
cb_name_guru_remove (NULL, state);
name_guru_remove (NULL, state);
return;
}
......@@ -426,7 +426,7 @@ cb_name_guru_clicked (GtkWidget *button, NameGuruState *state)
button == state->update_button ||
button == state->ok_button) {
/* If adding the name failed, do not exit */
if (!cb_name_guru_add (state)) {
if (!name_guru_add (state)) {
return;
}
}
......
......@@ -988,21 +988,19 @@ sheet_region_queue_recalc (Sheet const *sheet, Range const *r)
/*******************************************************************/
static void
inline static void
invalidate_refs (Dependent *dep, ExprRewriteInfo const *rwinfo)
{
ExprTree *newtree;
newtree = expr_rewrite (dep->expression, rwinfo);
ExprTree *newtree = expr_rewrite (dep->expression, rwinfo);
/*
* We are told this dependent depends on this region, hence if newtree
* is null then either we did not depend on it ( ie. serious breakage )
* or we had a duplicate reference and we have already removed it.
/* We are told this dependent depends on this region, hence if newtree
* is null then either
* 1) we did not depend on it ( ie. serious breakage )
* 2j we had a duplicate reference and we have already removed it.
* 3) We depended on things via a name which will be invalidated elsewhere
*/
g_return_if_fail (newtree != NULL);
dependent_set_expr (dep, newtree);
if (newtree != NULL)
dependent_set_expr (dep, newtree);
}
/*
......@@ -1041,6 +1039,15 @@ cb_dep_hash_invalidate (gpointer key, gpointer value, gpointer closure)
g_free (depany);
}
static void
cb_name_invalidate_sheet (gpointer key, gpointer value, gpointer rwinfo)
{
NamedExpression *nexpr = key;
ExprTree *new_expr = expr_rewrite (nexpr->t.expr_tree, rwinfo);
g_return_if_fail (new_expr != NULL);
expr_name_set_expr (nexpr, new_expr);
}
/*
* do_deps_destroy :
* Invalidate references of all kinds to the target region described by
......@@ -1086,6 +1093,8 @@ do_deps_destroy (Sheet *sheet, ExprRewriteInfo const *rwinfo)
}
if (deps->names) {
g_hash_table_foreach (deps->names,
cb_name_invalidate_sheet, (gpointer)rwinfo);
g_hash_table_destroy (deps->names);
deps->names = NULL;
}
......
......@@ -26,21 +26,6 @@
/* We don't expect that many global names ! */
static GList *global_names = NULL;
void
expr_name_invalidate_refs_sheet (Sheet const *sheet)
{
static gboolean warned = FALSE;
if (!warned)
g_warning ("Implement Me !. expr_name_invalidate_refs_sheet\n");
warned = TRUE;
}
void
expr_name_invalidate_refs_wb (Workbook const *wb)
{
WORKBOOK_FOREACH_SHEET(wb, sheet, expr_name_invalidate_refs_sheet (sheet););
}
static void
cb_collect_name_deps (gpointer key, gpointer value, gpointer user_data)
{
......@@ -74,7 +59,7 @@ expr_name_link_deps (GSList *deps)
/* put them back */
for (; ptr != NULL ; ptr = ptr->next) {
Dependent *dep = ptr->data;
if (!dependent_is_linked (dep)) {
if (dep->sheet->deps != NULL && !dependent_is_linked (dep)) {
CellPos *pos = dependent_is_cell (dep)
? &(DEP_TO_CELL (dep)->pos) : NULL;
dependent_link (dep, pos);
......@@ -85,16 +70,53 @@ expr_name_link_deps (GSList *deps)
g_slist_free (deps);
}
/**
* expr_name_handle_references : register or unregister a name with
* all of the sheets it explicitly references. This is necessary
* beacuse names are not dependents, and if they reference a deleted
* sheet we will not notice.
*/
static void
expr_name_handle_references (NamedExpression *nexpr, gboolean add)
{
GSList *sheets, *ptr;
sheets = expr_tree_referenced_sheets (nexpr->t.expr_tree);
for (ptr = sheets ; ptr != NULL ; ptr = ptr->next) {
Sheet *sheet = ptr->data;
NamedExpression *found;
/* No need to do anything during destruction */
if (sheet->deps == NULL)
continue;
found = g_hash_table_lookup (sheet->deps->names, nexpr);
if (add) {
if (found == NULL) {
g_hash_table_insert (sheet->deps->names, nexpr, nexpr);
} else {
g_warning ("Name being registered multiple times ?");
}
} else {
if (found == NULL) {
g_warning ("Unregistered name being being removed ?");
} else {
g_hash_table_remove (sheet->deps->names, nexpr);
}
}
}
g_slist_free (sheets);
}
static NamedExpression *
expr_name_lookup_list (GList *p, char const *name)
{
while (p) {
for (; p ; p = p->next) {
NamedExpression *nexpr = p->data;
g_return_val_if_fail (nexpr != NULL, 0);
if (g_strcasecmp (nexpr->name->str, name) == 0)
return nexpr;
p = g_list_next (p);
}
return NULL;
}
......@@ -237,9 +259,9 @@ expr_name_add (ParsePos const *pp, char const *name,
*error_msg = NULL;
nexpr = named_expr_new (name, FALSE);
nexpr->t.expr_tree = expr;
parse_pos_init (&nexpr->pos,
pp->wb, pp->sheet, pp->eval.col, pp->eval.row);
expr_name_set_expr (nexpr, expr);
*scope = g_list_append (*scope, nexpr);
......@@ -302,10 +324,8 @@ expr_name_unref (NamedExpression *nexpr)
nexpr->name = NULL;
}
if (!nexpr->builtin && nexpr->t.expr_tree) {
expr_tree_unref (nexpr->t.expr_tree);
nexpr->t.expr_tree = NULL;
}
if (!nexpr->builtin && nexpr->t.expr_tree != NULL)
expr_name_set_expr (nexpr, NULL);
if (nexpr->dependents != NULL) {
g_hash_table_destroy (nexpr->dependents);
......@@ -318,30 +338,31 @@ expr_name_unref (NamedExpression *nexpr)
g_free (nexpr);
}
/**
* expr_name_unlink :
*
* Linked names can be looked up and used. It is possible to have a non-zero
* ref count and be unlinked.
*/
static void
expr_name_unlink (NamedExpression *nexpr)
{
Workbook *wb = NULL;
Sheet *sheet = NULL;
g_return_if_fail (nexpr->active);
/* printf ("Removing : '%s'\n", nexpr->name->str);*/
if (nexpr->pos.sheet) {
sheet = nexpr->pos.sheet;
Sheet *sheet = nexpr->pos.sheet;
g_return_if_fail (g_list_find (sheet->names, nexpr) != NULL);
sheet->names = g_list_remove (sheet->names, nexpr);
} else if (nexpr->pos.wb) {
wb = nexpr->pos.wb;
Workbook *wb = nexpr->pos.wb;
g_return_if_fail (g_list_find (wb->names, nexpr) != NULL);
wb->names = g_list_remove (wb->names, nexpr);
} else {
g_return_if_fail (g_list_find (global_names, nexpr) != NULL);
global_names = g_list_remove (global_names, nexpr);
}
}
static void
expr_name_invalidate_refs (NamedExpression *nexpr)
{
expr_name_unref (nexpr);
nexpr->active = FALSE;
}
void
......@@ -351,9 +372,7 @@ expr_name_remove (NamedExpression *nexpr)
g_return_if_fail (nexpr->active);
expr_name_unlink (nexpr);
expr_name_invalidate_refs (nexpr);
nexpr->active = FALSE;
expr_name_unref (nexpr);
expr_name_set_expr (nexpr, NULL);
}
/**
......@@ -425,26 +444,26 @@ expr_name_eval (NamedExpression const *nexpr,
*/
/**
* expr_name_set_scope:
* @expression:
* @nexpr:
* @sheet:
*
* Return Value: FALSE or error, TRUE otherwise
**/
gboolean
expr_name_set_scope (NamedExpression *expression, Sheet *sheet)
expr_name_set_scope (NamedExpression *nexpr, Sheet *sheet)
{
Workbook *wb;
g_return_val_if_fail (IS_SHEET (expression->pos.sheet), FALSE);
g_return_val_if_fail (IS_SHEET (nexpr->pos.sheet), FALSE);
sheet = expression->pos.sheet;
sheet = nexpr->pos.sheet;
wb = sheet->workbook;
expression->pos.sheet = NULL;
expression->pos.wb = wb;
nexpr->pos.sheet = NULL;
nexpr->pos.wb = wb;
wb->names = g_list_prepend (wb->names, expression);
sheet->names = g_list_remove (sheet->names, expression);
wb->names = g_list_prepend (wb->names, nexpr);
sheet->names = g_list_remove (sheet->names, nexpr);
sheet_set_dirty (sheet, TRUE);
......@@ -459,11 +478,19 @@ expr_name_set_expr (NamedExpression *nexpr, ExprTree *new_expr)
g_return_if_fail (nexpr != NULL);
g_return_if_fail (!nexpr->builtin);
deps = expr_name_unlink_deps (nexpr);
expr_tree_ref (new_expr);
expr_tree_unref (nexpr->t.expr_tree);
if (new_expr != NULL)
expr_tree_ref (new_expr);
if (nexpr->t.expr_tree != NULL) {
deps = expr_name_unlink_deps (nexpr);
expr_name_handle_references (nexpr, FALSE);
expr_tree_unref (nexpr->t.expr_tree);
}
nexpr->t.expr_tree = new_expr;
expr_name_link_deps (deps);
if (new_expr != NULL) {
expr_name_link_deps (deps);
expr_name_handle_references (nexpr, TRUE);
}
}
void
......
......@@ -10,7 +10,7 @@ struct _NamedExpression {
String *name;
ParsePos pos;
GHashTable *dependents;
gboolean active : 1;
gboolean active : 1;
gboolean builtin : 1;
union {
ExprTree *expr_tree;
......@@ -36,8 +36,6 @@ void expr_name_add_dep (NamedExpression *ne, Dependent *dep);
void expr_name_remove_dep (NamedExpression *ne, Dependent *dep);
GList *expr_name_list_destroy (GList *names);
void expr_name_invalidate_refs_sheet (Sheet const *sheet);
void expr_name_invalidate_refs_wb (Workbook const *wb);
void expr_name_init (void);
......
......@@ -1485,7 +1485,6 @@ expr_rewrite (ExprTree const *expr, ExprRewriteInfo const *rwinfo)
* flag the name as inactive and remove the reference here.
*/
if (!nexpr->active ||
(rwinfo->type == EXPR_REWRITE_NAME && rwinfo->u.name == nexpr) ||
(rwinfo->type == EXPR_REWRITE_SHEET && rwinfo->u.sheet == nexpr->pos.sheet) ||
(rwinfo->type == EXPR_REWRITE_WORKBOOK && rwinfo->u.workbook == nexpr->pos.wb))
return expr_tree_new_constant (value_new_error (NULL, gnumeric_err_REF));
......@@ -1541,9 +1540,6 @@ expr_rewrite (ExprTree const *expr, ExprRewriteInfo const *rwinfo)
return expr_tree_new_constant (value_new_error (NULL, gnumeric_err_REF));
return NULL;
case EXPR_REWRITE_NAME :
return NULL;
case EXPR_REWRITE_RELOCATE : {
CellRef res = expr->var.ref; /* Copy */
......
......@@ -177,12 +177,10 @@ struct _ExprRelocateInfo {
struct _ExprRewriteInfo {
enum { EXPR_REWRITE_SHEET,
EXPR_REWRITE_WORKBOOK,
EXPR_REWRITE_NAME,
EXPR_REWRITE_RELOCATE } type;
union {
Sheet *sheet;
Workbook *workbook;
NamedExpression *name;
Sheet const *sheet;
Workbook const *workbook;
ExprRelocateInfo relocate;
} u;
};
......
......@@ -2896,7 +2896,6 @@ sheet_destroy (Sheet *sheet)
g_free (sheet->solver_parameters.input_entry_str);
sheet_deps_destroy (sheet);
expr_name_invalidate_refs_sheet (sheet);
sheet_destroy_contents (sheet);
sheet->names = expr_name_list_destroy (sheet->names);
......
......@@ -142,7 +142,6 @@ workbook_destroy (GtkObject *wb_object)
wb->redo_commands = NULL;
workbook_deps_destroy (wb);
expr_name_invalidate_refs_wb (wb);
/* Copy the set of sheets, the list changes under us. */
sheets = workbook_sheets (wb);
......@@ -1105,7 +1104,6 @@ workbook_sheet_delete (Sheet *sheet)
/* Important to do these BEFORE detaching the sheet */
sheet_deps_destroy (sheet);
expr_name_invalidate_refs_sheet (sheet);
/* All is fine, remove the sheet */
workbook_sheet_detach (wb, sheet);
......
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