[gnumeric] R.QBINOM(c, a, b) --> BINOM.INV(a, b, c) translation and function renaming in xlsx export



commit ef62d530384478fb8ca8f0c0e5b26c9600cd113a
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Fri Jun 21 16:58:21 2013 -0600

    R.QBINOM(c,a,b) --> BINOM.INV(a,b,c) translation and function renaming in xlsx export
    
    2013-06-21  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        * xlsx-utils.h: remove duplicates
        (xlsx_conventions_new): add argument
        * xlsx-read.c (xlsx_file_open): add argument to
        xlsx_conventions_new
        * xlsx-write.c (xlsx_write_workbook): ditto
        * xlsx-utils.c (xlsx_func_map_in): recognize our own functions
        (xlsx_func_map_out): new
        (xlsx_func_binominv_output_handler): new
        (xlsx_conventions_new): add argument and initialize
        output hashes and function translator

 plugins/excel/ChangeLog    |   13 ++++
 plugins/excel/xlsx-read.c  |    2 +-
 plugins/excel/xlsx-utils.c |  161 +++++++++++++++++++++++++++++++++-----------
 plugins/excel/xlsx-utils.h |    7 +--
 plugins/excel/xlsx-write.c |    2 +-
 5 files changed, 139 insertions(+), 46 deletions(-)
---
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 4f29ea0..5853d7b 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,16 @@
+2013-06-21  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+       * xlsx-utils.h: remove duplicates
+       (xlsx_conventions_new): add argument
+       * xlsx-read.c (xlsx_file_open): add argument to
+       xlsx_conventions_new
+       * xlsx-write.c (xlsx_write_workbook): ditto
+       * xlsx-utils.c (xlsx_func_map_in): recognize our own functions
+       (xlsx_func_map_out): new
+       (xlsx_func_binominv_output_handler): new
+       (xlsx_conventions_new): add argument and initialize
+       output hashes and function translator
+
 2013-06-21  Morten Welinder  <terra gnome org>
 
        * ms-formula-read.c (make_function): Eliminate typo.  Fixes
diff --git a/plugins/excel/xlsx-read.c b/plugins/excel/xlsx-read.c
index 74d17b4..47c5aec 100644
--- a/plugins/excel/xlsx-read.c
+++ b/plugins/excel/xlsx-read.c
@@ -4762,7 +4762,7 @@ xlsx_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *context,
        state.num_fmts = g_hash_table_new_full (g_str_hash, g_str_equal,
                (GDestroyNotify)g_free, (GDestroyNotify) go_format_unref);
        state.date_fmt = xlsx_pivot_date_fmt ();
-       state.convs = xlsx_conventions_new ();
+       state.convs = xlsx_conventions_new (FALSE);
        state.theme_colors_by_name = g_hash_table_new_full (g_str_hash, g_str_equal,
                (GDestroyNotify)g_free, NULL);
        /* fill in some default colors (when theme is absent */
diff --git a/plugins/excel/xlsx-utils.c b/plugins/excel/xlsx-utils.c
index 50534e2..58a8293 100644
--- a/plugins/excel/xlsx-utils.c
+++ b/plugins/excel/xlsx-utils.c
@@ -32,6 +32,7 @@
 #include "workbook.h"
 #include "sheet.h"
 #include "func.h"
+#include <expr-impl.h>
 #include "gnm-format.h"
 #include <goffice/goffice.h>
 #include <glib-object.h>
@@ -151,12 +152,49 @@ xlsx_func_map_in (GnmConventions const *convs,
                /* This should at most happen for ODF functions incorporated */
                /* in an xlsx file, we should perform the appropriate translation! */
                name = name + 9;
+       else if (0 == g_ascii_strncasecmp (name, "_xlfngnumeric.", 9))
+               /* These are Gnumeric's own functions */
+               name = name + 14;
 
        f = gnm_func_lookup_or_add_placeholder (name);
 
        return gnm_expr_new_funcall (f, args);  
 }
 
+static void
+xlsx_func_map_out (GnmConventionsOut *out, GnmExprFunction const *func)
+{
+       XLSXExprConventions const *xconv = (XLSXExprConventions const *)(out->convs);
+       char const *name = gnm_func_get_name (func->func, FALSE);
+       gboolean (*handler) (GnmConventionsOut *out, GnmExprFunction const *func);
+
+       handler = g_hash_table_lookup (xconv->xlfn_handler_map, name);
+
+       if (handler == NULL || !handler (out, func)) {
+               char const *new_name = g_hash_table_lookup (xconv->xlfn_map, name);
+               GString *target = out->accum;
+
+               if (new_name == NULL) {
+                               char *new_u_name;
+                               new_u_name = g_ascii_strup (name, -1);
+                               if (func->func->impl_status == 
+                                   GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC)
+                                       g_string_append (target, "_xlfngnumeric.");
+                               /* LO & friends use _xlfnodf */
+                               g_string_append (target, new_u_name);
+                               g_free (new_u_name);
+               }
+               else {
+                       g_string_append (target, "_xlfn.");
+                       g_string_append (target, new_name);
+               }
+
+               gnm_expr_list_as_string (func->argc, func->argv, out);
+       }
+       return;
+}
+
+
 static GnmExpr const *
 xlsx_func_binominv_handler (G_GNUC_UNUSED GnmConventions const *convs, G_GNUC_UNUSED Workbook *scope, 
GnmExprList *args)
 /* BINOM.INV(a,b,c) --> R.QBINOM(c,a,b) */
@@ -171,8 +209,27 @@ xlsx_func_binominv_handler (G_GNUC_UNUSED GnmConventions const *convs, G_GNUC_UN
        return gnm_expr_new_funcall (f, args);
 }
 
+static gboolean
+xlsx_func_binominv_output_handler (GnmConventionsOut *out, GnmExprFunction const *func)
+{
+       if (func->argc == 3) {
+               GString *target = out->accum;
+               GnmExprConstPtr const *ptr = func->argv;
+               g_string_append (target, "_xlfn.BINOM.INV(");
+               gnm_expr_as_gstring (ptr[1], out);
+               g_string_append_c (out->accum, ',');
+               gnm_expr_as_gstring (ptr[2], out);
+               g_string_append_c (out->accum, ',');
+               gnm_expr_as_gstring (ptr[0], out);
+               g_string_append (out->accum, ")");
+               return TRUE;
+       }
+       return FALSE;
+}
+
+
 GnmConventions *
-xlsx_conventions_new (void)
+xlsx_conventions_new (gboolean output)
 {
        static struct {
                char const *gnm_name;
@@ -181,35 +238,43 @@ xlsx_conventions_new (void)
                {"BINOM.INV", xlsx_func_binominv_handler},
                {NULL, NULL}
        };
+
+       static struct {
+               char const *gnm_name;
+               gpointer handler;
+       } const xlfn_func_output_handlers[] = {
+               {"R.QBINOM", xlsx_func_binominv_output_handler},
+               {NULL, NULL}
+       };
        
        static struct {
                char const *xlsx_name;
                char const *gnm_name;
        } const xlfn_func_renames[] = {
-               { "beta.inv", "betainv" },
-               { "binom.dist", "binomdist" },
-               { "chisq.dist.rt", "chidist" },
-               { "chisq.inv.rt", "chiinv" },
-               { "chisq.test", "chitest" },
-               { "confidence.norm", "confidence" },
-               { "covariance.p", "covar" },
-               { "expon.dist", "expondist" },
-               { "f.dist.rt", "fdist" },
-               { "f.inv.rt", "finv" },
-               { "f.test", "ftest" },
-               { "gamma.dist", "gammadist" },
-               { "gamma.inv", "gammainv" },
-               { "mode.sngl", "mode" },
-               { "percentile.inc", "percentile" },
-               { "percentrank.inc", "percentrank" },
-               { "quartile.inc", "quartile" },
-               { "rank.eq", "rank" },
-               { "stdev.p", "stdevp" },
-               { "stdev.s", "stdev" },
-               { "t.test", "ttest" },
-               { "var.p", "varp" },
-               { "var.s", "var" },
-               { "z.test", "ztest" },
+               { "BETA.INV", "BETAINV" },
+               { "BINOM.DIST", "BINOMDIST" },
+               { "CHISQ.DIST.RT", "CHIDIST" },
+               { "CHISQ.INV.RT", "CHIINV" },
+               { "CHISQ.TEST", "CHITEST" },
+               { "CONFIDENCE.NORM", "CONFIDENCE" },
+               { "COVARIANCE.P", "COVAR" },
+               { "EXPON.DIST", "EXPONDIST" },
+               { "F.DIST.RT", "FDIST" },
+               { "F.INV.RT", "FINV" },
+               { "F.TEST", "FTEST" },
+               { "GAMMA.DIST", "GAMMADIST" },
+               { "GAMMA.INV", "GAMMAINV" },
+               { "MODE.SNGL", "MODE" },
+               { "PERCENTILE.INC", "PERCENTILE" },
+               { "PERCENTRANK.INC", "PERCENTRANK" },
+               { "QUARTILE.INC", "QUARTILE" },
+               { "RANK.EQ", "RANK" },
+               { "STDEV.P", "STDEVP" },
+               { "STDEV.S", "STDEV" },
+               { "T.TEST", "TTEST" },
+               { "VAR.P", "VARP" },
+               { "VAR.S", "VAR" },
+               { "Z.TEST", "ZTEST" },
                { NULL, NULL }
        };      
        GnmConventions *convs = gnm_conventions_new_full (
@@ -220,7 +285,6 @@ xlsx_conventions_new (void)
        convs->decimal_sep_dot          = TRUE;
        convs->input.range_ref          = rangeref_parse;
        convs->input.external_wb        = xlsx_lookup_external_wb;
-       convs->input.func               = xlsx_func_map_in;
        convs->output.cell_ref          = xlsx_cellref_as_string;
        convs->output.range_ref         = xlsx_rangeref_as_string;
        convs->range_sep_colon          = TRUE;
@@ -228,24 +292,43 @@ xlsx_conventions_new (void)
        convs->arg_sep                  = ',';
        convs->array_col_sep            = ',';
        convs->array_row_sep            = ';';
-       convs->output.translated                = FALSE;
+       convs->output.translated        = FALSE;
        xconv->extern_id_by_wb = g_hash_table_new_full (g_direct_hash, g_direct_equal,
                (GDestroyNotify) g_object_unref, g_free);
        xconv->extern_wb_by_id = g_hash_table_new_full (g_str_hash, g_str_equal,
                g_free, (GDestroyNotify) g_object_unref);
-       xconv->xlfn_map = g_hash_table_new (go_ascii_strcase_hash,
-                                           go_ascii_strcase_equal);
-       for (i = 0; xlfn_func_renames[i].xlsx_name; i++)
-               g_hash_table_insert (xconv->xlfn_map,
-                                    (gchar *) xlfn_func_renames[i].xlsx_name,
-                                    (gchar *) xlfn_func_renames[i].gnm_name);
-       xconv->xlfn_handler_map = g_hash_table_new (go_ascii_strcase_hash,
+
+       if (output) {
+               convs->output.func      = xlsx_func_map_out;
+
+               xconv->xlfn_map = g_hash_table_new (go_ascii_strcase_hash,
                                                    go_ascii_strcase_equal);
-       for (i = 0; xlfn_func_handlers[i].gnm_name; i++)
-               g_hash_table_insert (xconv->xlfn_handler_map,
-                                    (gchar *) xlfn_func_handlers[i].gnm_name,
-                                    xlfn_func_handlers[i].handler);
-       
+               for (i = 0; xlfn_func_renames[i].xlsx_name; i++)
+                       g_hash_table_insert (xconv->xlfn_map,
+                                            (gchar *) xlfn_func_renames[i].gnm_name,
+                                            (gchar *) xlfn_func_renames[i].xlsx_name);
+               xconv->xlfn_handler_map = g_hash_table_new (go_ascii_strcase_hash,
+                                                           go_ascii_strcase_equal);
+               for (i = 0; xlfn_func_output_handlers[i].gnm_name; i++)
+                       g_hash_table_insert (xconv->xlfn_handler_map,
+                                            (gchar *) xlfn_func_output_handlers[i].gnm_name,
+                                            xlfn_func_output_handlers[i].handler);
+       } else {
+               convs->input.func       = xlsx_func_map_in;
+
+               xconv->xlfn_map = g_hash_table_new (go_ascii_strcase_hash,
+                                                   go_ascii_strcase_equal);
+               for (i = 0; xlfn_func_renames[i].xlsx_name; i++)
+                       g_hash_table_insert (xconv->xlfn_map,
+                                            (gchar *) xlfn_func_renames[i].xlsx_name,
+                                            (gchar *) xlfn_func_renames[i].gnm_name);
+               xconv->xlfn_handler_map = g_hash_table_new (go_ascii_strcase_hash,
+                                                           go_ascii_strcase_equal);
+               for (i = 0; xlfn_func_handlers[i].gnm_name; i++)
+                       g_hash_table_insert (xconv->xlfn_handler_map,
+                                            (gchar *) xlfn_func_handlers[i].gnm_name,
+                                            xlfn_func_handlers[i].handler);
+       }
 
        return convs;
 }
diff --git a/plugins/excel/xlsx-utils.h b/plugins/excel/xlsx-utils.h
index 879f0ae..093cff0 100644
--- a/plugins/excel/xlsx-utils.h
+++ b/plugins/excel/xlsx-utils.h
@@ -51,14 +51,11 @@ enum {
 #define XLSX_MaxCol    16384
 #define XLSX_MaxRow    1048576
 
-GnmConventions *xlsx_conventions_new  (void);
+GnmConventions *xlsx_conventions_new  (gboolean output);
 void            xlsx_conventions_free (GnmConventions *conv);
 Workbook       *xlsx_conventions_add_extern_ref (GnmConventions *conv,
                                                  char const *path);
-GnmConventions *xlsx_conventions_new  (void);
-void           xlsx_conventions_free (GnmConventions *conv);
-
-GOFormat       *xlsx_pivot_date_fmt   (void);
+GOFormat        *xlsx_pivot_date_fmt   (void);
 
 GOGradientDirection xlsx_get_gradient_direction (double ang);
 
diff --git a/plugins/excel/xlsx-write.c b/plugins/excel/xlsx-write.c
index 2d8a7b8..5466d0e 100644
--- a/plugins/excel/xlsx-write.c
+++ b/plugins/excel/xlsx-write.c
@@ -2472,7 +2472,7 @@ xlsx_write_workbook (XLSXWriteState *state, GsfOutfile *root_part)
        xlsx_get_style_id (state, style);
        gnm_style_unref (style);
 
-       state->convs     = xlsx_conventions_new ();
+       state->convs     = xlsx_conventions_new (TRUE);
        state->chart.dir   = state->drawing.dir   = NULL;
        state->chart.count = state->drawing.count = 0;
 


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