[gnumeric] Calculation: support volatile functions.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Calculation: support volatile functions.
- Date: Wed, 5 Mar 2014 19:46:46 +0000 (UTC)
commit c4c01aa9b2c9830d068060c44ce560a9e98c22aa
Author: Morten Welinder <terra gnome org>
Date: Wed Mar 5 14:45:28 2014 -0500
Calculation: support volatile functions.
This comes down to recomputing RAND, TODAY, etc. on load, even from formats
that contain computed values.
ChangeLog | 8 ++++++++
NEWS | 3 +++
src/dependent.c | 18 ++++++++++++++++++
src/dependent.h | 3 +++
src/expr.c | 29 +++++++++++++++++++++++++++++
src/expr.h | 1 +
src/workbook-view.c | 1 +
7 files changed, 63 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a306228..7aefad0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
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.
diff --git a/NEWS b/NEWS
index ef8ca16..e166d8e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
Gnumeric 1.12.13
+Morten:
+ * Support volatile functions. [#305798]
+
--------------------------------------------------------------------------
Gnumeric 1.12.12
diff --git a/src/dependent.c b/src/dependent.c
index ab9b974..e89971f 100644
--- a/src/dependent.c
+++ b/src/dependent.c
@@ -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
diff --git a/src/dependent.h b/src/dependent.h
index aedfcee..a4b8b68 100644
--- a/src/dependent.h
+++ b/src/dependent.h
@@ -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,
diff --git a/src/expr.c b/src/expr.c
index e6395a3..0e9bef8 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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,
diff --git a/src/expr.h b/src/expr.h
index 610339a..9846298 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -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);
diff --git a/src/workbook-view.c b/src/workbook-view.c
index bb315cf..3dc4de1 100644
--- a/src/workbook-view.c
+++ b/src/workbook-view.c
@@ -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))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]