[gnumeric] CHISQ.DIST and F.DIST import from xlsx



commit ae0f24aefefcaa5e6d674a261efec197f678b760
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Wed Jun 26 21:10:26 2013 -0600

    CHISQ.DIST and F.DIST import from xlsx
    
    2013-06-26  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        * xlsx-utils.c (lsx_func_binominv_handler): use GnmExprList
        rather than GSList
        (xlsx_func_dist_handler): new
        (xlsx_func_chisqdist_handler): new
        (xlsx_func_fdist_handler): new
        (xlsx_conventions_new): connect the last two
    
    2013-06-26  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        * src/expr.c (gnm_expr_list_copy): new
        * src/expr.h (gnm_expr_list_copy): new

 ChangeLog                  |    5 ++++
 plugins/excel/ChangeLog    |   11 ++++++++-
 plugins/excel/xlsx-utils.c |   55 +++++++++++++++++++++++++++++++++++++++++++-
 src/expr.c                 |   13 ++++++++++
 src/expr.h                 |    1 +
 5 files changed, 83 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a881662..70d09fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-26  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+       * src/expr.c (gnm_expr_list_copy): new
+       * src/expr.h (gnm_expr_list_copy): new
+
 2013-06-26  Morten Welinder  <terra gnome org>
 
        * src/style-conditions.c (gnm_style_cond_is_valid): Check sanity
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 6967278..d1cd2b0 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,7 +1,16 @@
 2013-06-26  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+       * xlsx-utils.c (lsx_func_binominv_handler): use GnmExprList
+       rather than GSList
+       (xlsx_func_dist_handler): new
+       (xlsx_func_chisqdist_handler): new
+       (xlsx_func_fdist_handler): new
+       (xlsx_conventions_new): connect the last two
+
+2013-06-26  Andreas J. Guelzow <aguelzow pyrshep ca>
+
        * xlsx-utils.c (xlsx_func_erf_output_handler): new
-       (xlsx_conventions_new): connect the above and add erf.precise 
+       (xlsx_conventions_new): connect the above and add erf.precise
        translation
 
 2013-06-26  Andreas J. Guelzow <aguelzow pyrshep ca>
diff --git a/plugins/excel/xlsx-utils.c b/plugins/excel/xlsx-utils.c
index a8bea03..22a114b 100644
--- a/plugins/excel/xlsx-utils.c
+++ b/plugins/excel/xlsx-utils.c
@@ -201,7 +201,7 @@ xlsx_func_binominv_handler (G_GNUC_UNUSED GnmConventions const *convs, G_GNUC_UN
 /* BINOM.INV(a,b,c) --> R.QBINOM(c,a,b) */
 {
        GnmFunc  *f = gnm_func_lookup_or_add_placeholder ("r.qbinom");
-       GSList *arg;
+       GnmExprList *arg;
        
        arg = g_slist_nth (args, 2);
        args = g_slist_remove_link (args, arg);
@@ -210,6 +210,57 @@ xlsx_func_binominv_handler (G_GNUC_UNUSED GnmConventions const *convs, G_GNUC_UN
        return gnm_expr_new_funcall (f, args);
 }
 
+static GnmExpr const *
+xlsx_func_dist_handler (GnmExprList *args, guint n_args, char const *name, char const *name_p, char const 
*name_d)
+{
+       if (gnm_expr_list_length (args) != n_args) {
+               GnmFunc  *f = gnm_func_lookup_or_add_placeholder (name);
+               return gnm_expr_new_funcall (f, args);
+       } else {
+               GnmFunc  *f_if = gnm_func_lookup_or_add_placeholder ("if");
+               GnmFunc  *f_p = gnm_func_lookup_or_add_placeholder (name_p);
+               GnmFunc  *f_d = gnm_func_lookup_or_add_placeholder (name_d);
+               GnmExprList *arg_cum, *args_c;
+               GnmExpr const *cum;
+               GnmValue const *constant;
+
+               arg_cum = g_slist_nth (args, n_args - 1);
+               args = g_slist_remove_link (args, arg_cum);
+               cum = arg_cum->data;
+               gnm_expr_list_free (arg_cum);
+
+               constant = gnm_expr_get_constant (cum);
+               
+               if (constant == NULL || !VALUE_IS_NUMBER (constant)) {
+                       args_c = gnm_expr_list_copy (args);
+                       
+                       return gnm_expr_new_funcall3 
+                               (f_if, cum,
+                                gnm_expr_new_funcall (f_p, args),
+                                gnm_expr_new_funcall (f_d, args_c));
+               } else if (value_is_zero (constant)) {
+                       gnm_expr_free (cum);
+                       return gnm_expr_new_funcall (f_d, args);
+               } else {
+                       gnm_expr_free (cum);
+                       return gnm_expr_new_funcall (f_p, args);
+               }
+       }
+}
+
+static GnmExpr const *
+xlsx_func_chisqdist_handler (G_GNUC_UNUSED GnmConventions const *convs, G_GNUC_UNUSED Workbook *scope, 
+                            GnmExprList *args)
+{
+       return xlsx_func_dist_handler (args, 3, "chisq.dist", "r.pchisq", "r.dchisq");
+}
+
+static GnmExpr const *
+xlsx_func_fdist_handler (G_GNUC_UNUSED GnmConventions const *convs, G_GNUC_UNUSED Workbook *scope, 
GnmExprList *args)
+{
+       return xlsx_func_dist_handler (args, 4, "f.dist", "r.pf", "r.df");
+}
+
 
 static void
 xlsx_write_r_q_func (GnmConventionsOut *out, char const *name, char const *name_rt, 
@@ -433,6 +484,8 @@ xlsx_conventions_new (gboolean output)
                gpointer handler;
        } const xlfn_func_handlers[] = {
                {"BINOM.INV", xlsx_func_binominv_handler},
+               {"CHISQ.DIST", xlsx_func_chisqdist_handler},
+               {"F.DIST", xlsx_func_fdist_handler},
                {NULL, NULL}
        };
 
diff --git a/src/expr.c b/src/expr.c
index 9c3e612..a3def77 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2770,6 +2770,19 @@ gnm_expr_list_unref (GnmExprList *list)
        gnm_expr_list_free (list);
 }
 
+GnmExprList *
+gnm_expr_list_copy (GnmExprList *list)
+{
+       GnmExprList *res = g_slist_copy (list); /* shallow */
+       GnmExprList *l;
+
+       for (l = res; l; l = l->next)
+               l->data = (GnmExpr *) gnm_expr_copy (l->data);
+
+       return res;
+}
+
+
 void
 gnm_expr_list_as_string (int argc,
                         GnmExprConstPtr const *argv,
diff --git a/src/expr.h b/src/expr.h
index 57c6ce8..622b7e0 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -114,6 +114,7 @@ GnmExpr const *gnm_expr_simplify_if  (GnmExpr const *expr);
 #define gnm_expr_list_length(l)           g_slist_length((GSList *)(l)) /* const cast */
 #define gnm_expr_list_free        g_slist_free
 void    gnm_expr_list_unref      (GnmExprList *list);
+GnmExprList *gnm_expr_list_copy          (GnmExprList *list);
 
 /*****************************************************************************/
 


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