Commit c4c01aa9 authored by Morten Welinder's avatar Morten Welinder

Calculation: support volatile functions.

This comes down to recomputing RAND, TODAY, etc. on load, even from formats
that contain computed values.
parent 3166f0dd
2014-03-05 Morten Welinder <terra@gnome.org>
* src/expr.c (gnm_expr_top_is_volatile): New function.
* src/workbook-view.c (workbook_view_new_from_input): Queue all
volatile expressions.
* src/dependent.c (workbook_queue_volatile_recalc): New function.
(dependent_is_volatile): New function.
* src/sheet.c (sheet_range_set_expr_cb, sheet_range_set_text):
Don't set the initial range here.
......
Gnumeric 1.12.13
Morten:
* Support volatile functions. [#305798]
--------------------------------------------------------------------------
Gnumeric 1.12.12
......
......@@ -2814,6 +2814,16 @@ workbook_queue_all_recalc (Workbook *wb)
WORKBOOK_FOREACH_DEPENDENT (wb, dep, dependent_flag_recalc (dep););
}
void
workbook_queue_volatile_recalc (Workbook *wb)
{
WORKBOOK_FOREACH_DEPENDENT (wb, dep, {
if (dependent_is_volatile (dep))
dependent_flag_recalc (dep);
});
}
/**
* workbook_recalc :
* @wb:
......@@ -2905,6 +2915,14 @@ dynamic_dep_free (DynamicDep *dyn)
g_free (dyn);
}
gboolean
dependent_is_volatile (GnmDependent *dep)
{
/* This might need to be a virtual call. */
return dep->texpr && gnm_expr_top_is_volatile (dep->texpr);
}
/**
* gnm_dep_container_new: (skip)
* @sheet: #Sheet
......
......@@ -96,6 +96,8 @@ void dependent_unlink (GnmDependent *dep);
void dependent_queue_recalc (GnmDependent *dep);
void dependent_add_dynamic_dep (GnmDependent *dep, GnmRangeRef const *rr);
gboolean dependent_is_volatile (GnmDependent *dep);
GnmCellPos const *dependent_pos (GnmDependent const *dep);
GOUndo *dependents_relocate (GnmExprRelocateInfo const *info);
......@@ -110,6 +112,7 @@ void dependents_invalidate_sheet (Sheet *sheet, gboolean destroy);
void dependents_workbook_destroy (Workbook *wb);
void dependents_revive_sheet (Sheet *sheet);
void workbook_queue_all_recalc (Workbook *wb);
void workbook_queue_volatile_recalc (Workbook *wb);
void gnm_dep_style_dependency (Sheet *sheet,
GnmExprTop const *texpr,
......
......@@ -3059,6 +3059,35 @@ gnm_expr_top_contains_subtotal (GnmExprTop const *texpr)
return gnm_expr_contains_subtotal (texpr->expr);
}
static GnmExpr const *
cb_is_volatile (GnmExpr const *expr, GnmExprWalk *data)
{
gboolean *res = data->user;
if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL &&
(expr->func.func->flags & GNM_FUNC_VOLATILE)) {
*res = TRUE;
data->stop = TRUE;
}
return NULL;
}
gboolean
gnm_expr_top_is_volatile (GnmExprTop const *texpr)
{
gboolean res = FALSE;
/*
* An expression is volatile if it contains a call to a volatile
* function, even in cases like IF(TRUE,12,RAND()) where the
* volatile function won't even be reached.
*/
g_return_val_if_fail (IS_GNM_EXPR_TOP (texpr), FALSE);
gnm_expr_walk (texpr->expr, cb_is_volatile, &res);
return res;
}
GnmValue *
gnm_expr_top_eval (GnmExprTop const *texpr,
GnmEvalPos const *pos,
......
......@@ -166,6 +166,7 @@ void gnm_expr_top_get_boundingbox (GnmExprTop const *texpr,
Sheet const *sheet,
GnmRange *bound);
gboolean gnm_expr_top_contains_subtotal (GnmExprTop const *texpr);
gboolean gnm_expr_top_is_volatile (GnmExprTop const *texpr);
GSList *gnm_expr_top_referenced_sheets (GnmExprTop const *texpr);
GnmExpr const *gnm_expr_top_first_funcall (GnmExprTop const *texpr);
GnmExprTop const *gnm_expr_top_transpose (GnmExprTop const *texpr);
......
......@@ -1293,6 +1293,7 @@ workbook_view_new_from_input (GsfInput *input,
} else {
workbook_share_expressions (new_wb, TRUE);
workbook_optimize_style (new_wb);
workbook_queue_volatile_recalc (new_wb);
workbook_recalc (new_wb);
go_doc_set_dirty (GO_DOC (new_wb), FALSE);
if (optional_uri && workbook_get_file_exporter (new_wb))
......
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