[gnumeric] Expr: localize the code to simplify "if".



commit 61786551e57f0b997874519753e911af8b07c9c8
Author: Morten Welinder <terra gnome org>
Date:   Sun Mar 25 21:13:23 2012 -0400

    Expr: localize the code to simplify "if".
    
    Prepare for more expression rewrites for import/export.

 ChangeLog                            |    2 +
 plugins/openoffice/ChangeLog         |    6 ++++
 plugins/openoffice/openoffice-read.c |   50 ++++++++++++++++++---------------
 src/expr.c                           |   41 +++++++++++++++++++++++++++
 src/expr.h                           |    2 +
 5 files changed, 78 insertions(+), 23 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5143eae..4c5a342 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2012-03-25  Morten Welinder  <terra gnome org>
 
+	* src/expr.c (gnm_expr_simplify_if): New function.
+
 	* src/rangefunc.c (gnm_range_covar_pop): Rename from
 	gnm_range_covar.
 	(gnm_range_covar_est): New function.
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index e026d84..d7d746a 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-25  Morten Welinder  <terra gnome org>
+
+	* openoffice-read.c (odf_func_chisqdist_handler): Simplify (at the
+	expense of speed).  If we need a pile of these, they need to be
+	simple.
+
 2012-03-25  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-read.c (odf_adjust_offsets_col): new
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 3c75c0c..d6b7325 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -10267,37 +10267,41 @@ odf_func_chisqdist_handler (G_GNUC_UNUSED GnmConventions const *convs, Workbook
 		return gnm_expr_new_funcall (f, args);
 	}
 	case 3: {
-		GSList * link = g_slist_nth ((GSList *) args, 2);
-		GnmExpr const *expr = link->data;
+		GnmExpr const *arg0 = args->data;
+		GnmExpr const *arg1 = args->next->data;
+		GnmExpr const *arg2 = args->next->next->data;
 		GnmFunc  *fd_if;
 		GnmFunc  *fd_pchisq;
 		GnmFunc  *fd_dchisq;
-		GnmExpr  const *expr_pchisq;
-		GnmExpr  const *expr_dchisq;
+		GnmExpr const *expr_pchisq;
+		GnmExpr const *expr_dchisq;
+		GnmExpr const *res, *simp;
 
-		args = (GnmExprList *) g_slist_remove_link ((GSList *) args, link);
-		g_slist_free (link);
-
-		if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL) {
-			if (go_ascii_strcase_equal (expr->func.func->name, "TRUE")) {
-				fd_pchisq = gnm_func_lookup_or_add_placeholder ("R.PCHISQ", scope, FALSE);
-				gnm_expr_free (expr);
-				return gnm_expr_new_funcall (fd_pchisq, args);
-			}
-			if (go_ascii_strcase_equal (expr->func.func->name, "FALSE")) {
-				fd_dchisq = gnm_func_lookup_or_add_placeholder ("R.DCHISQ", scope, FALSE);
-				gnm_expr_free (expr);
-				return gnm_expr_new_funcall (fd_dchisq, args);
-			}
-		}
 		fd_if = gnm_func_lookup_or_add_placeholder ("IF", scope, FALSE);
 		fd_pchisq = gnm_func_lookup_or_add_placeholder ("R.PCHISQ", scope, FALSE);
 		fd_dchisq = gnm_func_lookup_or_add_placeholder ("R.DCHISQ", scope, FALSE);
 		expr_pchisq = gnm_expr_new_funcall2
-			(fd_pchisq, gnm_expr_copy (g_slist_nth_data ((GSList *) args, 0)),
-			 gnm_expr_copy (g_slist_nth_data ((GSList *) args, 1)));
-		expr_dchisq = gnm_expr_new_funcall (fd_dchisq, args);
-		return gnm_expr_new_funcall3 (fd_if, expr, expr_pchisq, expr_dchisq);
+			(fd_pchisq,
+			 gnm_expr_copy (arg0),
+			 gnm_expr_copy (arg1));
+		expr_dchisq = gnm_expr_new_funcall2
+			(fd_dchisq,
+			 arg0,
+			 arg1);
+		res = gnm_expr_new_funcall3
+			(fd_if,
+			 arg2,
+			 expr_pchisq,
+			 expr_dchisq);
+
+		simp = gnm_expr_simplify_if (res);
+		if (simp) {
+			gnm_expr_free (res);
+			res = simp;
+		}
+
+		g_slist_free (args);
+		return res;
 	}
 	default:
 		break;
diff --git a/src/expr.c b/src/expr.c
index 13488bf..7b02652 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1560,6 +1560,47 @@ gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
 	return value_new_error (pos, _("Unknown evaluation error"));
 }
 
+
+GnmExpr const *
+gnm_expr_simplify_if (GnmExpr const *expr)
+{
+	static GnmFunc *f_if = NULL;
+	GnmExpr const *cond;
+	gboolean c;
+
+	g_return_val_if_fail (expr != NULL, NULL);
+
+	if (GNM_EXPR_GET_OPER (expr) != GNM_EXPR_OP_FUNCALL)
+		return NULL;
+
+	if (!f_if)
+		f_if = gnm_func_lookup ("if", NULL);
+
+	if (expr->func.func != f_if || expr->func.argc != 3)
+		return NULL;
+
+	cond = expr->func.argv[0];	
+	if (GNM_EXPR_GET_OPER (cond) == GNM_EXPR_OP_CONSTANT) {
+		GnmValue const *condval = cond->constant.value;
+		gboolean err;
+		c = value_get_as_bool (condval, &err);
+		if (err)
+			return NULL;
+	} else if (GNM_EXPR_GET_OPER (cond) == GNM_EXPR_OP_FUNCALL) {
+		if (cond->func.func != gnm_func_lookup ("true", NULL))
+			c = TRUE;
+		else if (cond->func.func != gnm_func_lookup ("false", NULL))
+			c = FALSE;
+		else
+			return NULL;
+	} else
+		return NULL;
+
+	return gnm_expr_copy (expr->func.argv[c ? 1 : 2]);
+}
+
+
+
 /*
  * Converts a parsed tree into its string representation
  * assuming that we are evaluating at col, row
diff --git a/src/expr.h b/src/expr.h
index bc1b164..8ca0edf 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -101,6 +101,8 @@ gboolean  gnm_expr_contains_subtotal (GnmExpr const *expr);
 GnmValue *gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
 			 GnmExprEvalFlags flags);
 
+GnmExpr const *gnm_expr_simplify_if  (GnmExpr const *expr);
+
 /*****************************************************************************/
 
 #define gnm_expr_list_append(l,e)  g_slist_append ((l), (gpointer)(e))



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]