[gnumeric] GnmFunc: further cleanups.



commit f0514e58f6dde275b4ef2071b8c421ad71ac32bd
Author: Morten Welinder <terra gnome org>
Date:   Fri May 25 10:51:41 2018 -0400

    GnmFunc: further cleanups.

 plugins/excel/ms-formula-write.c     |  27 +++---
 plugins/perl-loader/perl-cc-wrapper  |   4 +-
 plugins/perl-loader/perl-gnumeric.c  |   7 +-
 plugins/perl-loader/perl-gnumeric.h  |   2 +
 plugins/perl-loader/perl-loader.c    |  29 +++---
 src/dependent.c                      |   3 +-
 src/dialogs/dialog-function-select.c |  12 +--
 src/func.c                           | 166 +++++++++++++++++++++++------------
 src/func.h                           |  26 +++---
 src/gnm-plugin.c                     |  30 +++++--
 src/ssgrep.c                         |   4 +-
 src/sstest.c                         |  64 ++++++--------
 12 files changed, 217 insertions(+), 157 deletions(-)
---
diff --git a/plugins/excel/ms-formula-write.c b/plugins/excel/ms-formula-write.c
index 67c7587f5..0249e908c 100644
--- a/plugins/excel/ms-formula-write.c
+++ b/plugins/excel/ms-formula-write.c
@@ -501,24 +501,25 @@ excel_formula_write_AREA (PolishData *pd, GnmCellRef const *a, GnmCellRef const
 }
 
 static char *
-guess_arg_types (const GnmFunc *func)
+guess_arg_types (GnmFunc *func)
 {
-       char *res, *p;
+       char *res;
+       int i, min, max;
 
-       if (func->fn_type != GNM_FUNC_TYPE_ARGS)
+       if (!gnm_func_is_fixarg (func))
                return NULL;
 
-       res = g_strdup (func->fn.args.arg_types);
+       gnm_func_count_args (func, &min, &max);
 
-       for (p = res; *p; p++) {
-               switch (*p) {
-               case 'r':
-               case 'A':
-                       *p = 'A';
-                       break;
-               default:
-                       *p = 'V';
-               }
+       res = g_new (char, max + 1);
+       res[max] = 0;
+
+       for (i = 0; i < max; i++) {
+               char t = gnm_func_get_arg_type (func, i);
+               if (t == 'r' || t == 'A')
+                       res[i] = 'A';
+               else
+                       res[i] = 'V';
        }
 
 #if FORMULA_DEBUG > 1
diff --git a/plugins/perl-loader/perl-cc-wrapper b/plugins/perl-loader/perl-cc-wrapper
index 4d86b5066..d27edefb2 100644
--- a/plugins/perl-loader/perl-cc-wrapper
+++ b/plugins/perl-loader/perl-cc-wrapper
@@ -15,7 +15,9 @@ while (@ARGV) {
        next;
     }
 
-    if ($sanitize && $arg =~ /^-/ && $arg !~ /^-(threads|-pthread|D|U|I|c|o)/) {
+    if ($sanitize && $arg =~ /^-/ &&
+       ($arg !~ /^-(threads|-pthread|D|U|I|c|o)/ ||
+        $arg =~ /^-DPIC$/)) {
        # Options that get here are not in the desiret set.
        # Notably we drop "-fPIC" (some variant of which should probably
        # also occur in an unsanitized section).
diff --git a/plugins/perl-loader/perl-gnumeric.c b/plugins/perl-loader/perl-gnumeric.c
index b23ddfa45..d307523a4 100644
--- a/plugins/perl-loader/perl-gnumeric.c
+++ b/plugins/perl-loader/perl-gnumeric.c
@@ -48,12 +48,12 @@ perl2value(SV *sv)
     return v;
 }
 
+#if 0
 GnmValue *
 marshal_func (GnmFuncEvalInfo *ei, GnmValue *argv[])
 {
     dSP;
-    GnmFunc const *func =
-       gnm_expr_get_func_def ((GnmExpr const *)ei->func_call);
+    GnmFunc const *func = gnm_eval_info_get_func (ei);
     I32 r;
     int i, min, max;
     SV * result;
@@ -71,6 +71,8 @@ marshal_func (GnmFuncEvalInfo *ei, GnmValue *argv[])
     }
     PUTBACK;
 
+    /* gnm_func_get_user_data doesn't exist anymore and in any case
+       it was never set to a value sane for this. */
     r = perl_call_sv (gnm_func_get_user_data (func), G_SCALAR);
     SPAGAIN;
     if (r != 1)
@@ -85,3 +87,4 @@ marshal_func (GnmFuncEvalInfo *ei, GnmValue *argv[])
 
     return v;
 }
+#endif
diff --git a/plugins/perl-loader/perl-gnumeric.h b/plugins/perl-loader/perl-gnumeric.h
index 0cc198bd6..97f1ab0be 100644
--- a/plugins/perl-loader/perl-gnumeric.h
+++ b/plugins/perl-loader/perl-gnumeric.h
@@ -34,6 +34,8 @@ typedef FILE * OutputStream;
 
 SV* value2perl(const GnmValue *v);
 GnmValue* perl2value(SV *sv);
+#if 0
 GnmValue* marshal_func (GnmFuncEvalInfo *ei, GnmValue *argv[]);
+#endif
 
 #endif /* _PERL_GNUMERIC_H */
diff --git a/plugins/perl-loader/perl-loader.c b/plugins/perl-loader/perl-loader.c
index b0f6fcd47..6078e8593 100644
--- a/plugins/perl-loader/perl-loader.c
+++ b/plugins/perl-loader/perl-loader.c
@@ -199,11 +199,11 @@ make_gnm_help (const char *name, int count, SV **SP)
        return help;
 }
 
-static gboolean
-gplp_func_desc_load (GOPluginService *service,
-                    char const *name,
-                    GnmFuncDescriptor *res)
+static void
+gplp_func_load_stub (GOPluginService *service,
+                    GnmFunc *func)
 {
+       char const *name = gnm_func_get_name (func, FALSE);
        char *args[] = { NULL };
        gchar *help_perl_func = g_strconcat ("help_", name, NULL);
        gchar *desc_perl_func = g_strconcat ("desc_", name, NULL);
@@ -254,18 +254,13 @@ gplp_func_desc_load (GOPluginService *service,
        g_free (help_perl_func);
        g_free (desc_perl_func);
 
-       res->name = g_strdup(name);
-       res->arg_spec = arg_spec;
-
-       res->help = help;
-       res->fn_args = NULL;
-       res->fn_args = &call_perl_function_args;
-       res->fn_nodes = NULL;
-       res->linker = NULL;
-       res->impl_status = GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC;
-       res->test_status = GNM_FUNC_TEST_STATUS_UNKNOWN;
-
-       return TRUE;
+       func->help = help;
+       func->impl_status = GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC;
+       func->test_status = GNM_FUNC_TEST_STATUS_UNKNOWN;
+       func->flags       = GNM_FUNC_SIMPLE;
+       func->fn.args.func      = call_perl_function_args;
+       func->fn.args.arg_spec  = arg_spec;
+       gnm_func_set_function_type (func, GNM_FUNC_TYPE_ARGS);
 }
 
 static void
@@ -328,7 +323,7 @@ gplp_load_service_function_group (GOPluginLoader *loader,
        GO_INIT_RET_ERROR_INFO (ret_error);
 
        cbs = go_plugin_service_get_cbs (service);
-       cbs->func_desc_load = &gplp_func_desc_load;
+       cbs->load_stub = &gplp_func_load_stub;
 }
 
 static gboolean
diff --git a/src/dependent.c b/src/dependent.c
index fad4407d1..10d3d2a9c 100644
--- a/src/dependent.c
+++ b/src/dependent.c
@@ -1114,8 +1114,7 @@ link_unlink_expr_dep (GnmEvalPos *ep, GnmExpr const *tree, gboolean qlink)
                GnmFuncEvalInfo fei;
                GnmDependentFlags flag;
 
-               if (tree->func.func->fn_type == GNM_FUNC_TYPE_STUB)
-                       gnm_func_load_stub (tree->func.func);
+               gnm_func_load_if_stub (tree->func.func);
                fei.pos = ep;
                fei.func_call = &tree->func;
                flag = gnm_func_link_dep (tree->func.func, &fei, qlink);
diff --git a/src/dialogs/dialog-function-select.c b/src/dialogs/dialog-function-select.c
index d03e141db..7429d3798 100644
--- a/src/dialogs/dialog-function-select.c
+++ b/src/dialogs/dialog-function-select.c
@@ -44,7 +44,7 @@
 #include <gsf/gsf-impl-utils.h>
 #include <string.h>
 
-#define F2(func,s) dgettext ((func)->tdomain->str, (s))
+#define F2(func,s) dgettext (gnm_func_get_translation_domain(func), (s))
 
 #define FUNCTION_SELECT_KEY "function-selector-dialog"
 #define FUNCTION_SELECT_HELP_KEY "function-selector-dialog-help-mode"
@@ -726,7 +726,7 @@ make_expr_example (Sheet *sheet, const char *text,
 static void
 describe_new_style (GtkTextBuffer *description,
                    GtkWidget *target,
-                   GnmFunc const *func, Sheet *sheet)
+                   GnmFunc *func, Sheet *sheet)
 {
        GnmFuncHelp const *help;
        GtkTextIter ti;
@@ -1046,7 +1046,7 @@ cb_dialog_function_select_fun_selection_changed (GtkTreeSelection *selection,
 {
        GtkTreeIter  iter;
        GtkTreeModel *model;
-       GnmFunc const *func;
+       GnmFunc *func;
        GtkTextBuffer *description;
        GtkTextMark *mark;
        gboolean active = FALSE;
@@ -1063,7 +1063,7 @@ cb_dialog_function_select_fun_selection_changed (GtkTreeSelection *selection,
                                    FUNCTION, &func,
                                    -1);
 
-               gnm_func_load_if_stub ((GnmFunc *)func);
+               gnm_func_load_if_stub (func);
 
                if (func->help == NULL)
                        gtk_text_buffer_set_text (description, "?", -1);
@@ -1190,10 +1190,10 @@ dialog_function_select_load_tree (FunctionSelectState *state)
                                 FUNCTION, func,
                                 FUNCTION_DESC, desc,
                                 FUNCTION_PAL, pal,
-                                FUNCTION_CAT, func->fn_group,
+                                FUNCTION_CAT, gnm_func_get_function_group (func),
                                 FUNCTION_VISIBLE, TRUE,
                                 FUNCTION_RECENT, FALSE,
-                                FUNCTION_USED, (func->usage_count > 1),
+                                FUNCTION_USED, gnm_func_get_in_use (func),
                                 -1);
                        g_free (desc);
                        pango_attr_list_unref (pal);
diff --git a/src/func.c b/src/func.c
index 0700471a0..2883a18e8 100644
--- a/src/func.c
+++ b/src/func.c
@@ -7,6 +7,18 @@
  *  Morten Welinder (terra gnome org)
  *  Jody Goldberg   (jody gnome org)
  */
+
+// Temporary while cleaning out direct access to GnmFunc
+#define XXXusage_count usage_count
+#define XXXlocalized_name localized_name
+#define XXXtdomain tdomain
+#define XXXarg_names_p arg_names_p
+#define XXXfn_group fn_group
+#define XXXmin_args min_args
+#define XXXmax_args max_args
+#define XXXarg_types arg_types
+#define XXXfn_type fn_type
+
 #include <gnumeric-config.h>
 #include <glib/gi18n-lib.h>
 #include <glib/gstdio.h>
@@ -119,6 +131,30 @@ gnm_func_enumerate (void)
        return res;
 }
 
+static GnmValue *
+error_function_no_full_info (GnmFuncEvalInfo *ei,
+                            int argc,
+                            GnmExprConstPtr const *argv)
+{
+       return value_new_error (ei->pos, _("Function implementation not available."));
+}
+
+static void
+gnm_func_load_stub (GnmFunc *func)
+{
+       g_return_if_fail (func->fn_type == GNM_FUNC_TYPE_STUB);
+
+       g_signal_emit (G_OBJECT (func), signals[SIG_LOAD_STUB], 0);
+
+       if (func->fn_type == GNM_FUNC_TYPE_STUB) {
+               static GnmFuncHelp const no_help[] = { { GNM_FUNC_HELP_END } };
+
+               func->help = no_help;
+               func->fn.nodes = &error_function_no_full_info;
+               gnm_func_set_function_type (func, GNM_FUNC_TYPE_NODES);
+       }
+}
+
 inline void
 gnm_func_load_if_stub (GnmFunc *func)
 {
@@ -261,25 +297,22 @@ gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *fn_def)
 /******************************************************************************/
 
 static void
-extract_arg_types (GnmFunc *def)
+extract_arg_types (GnmFunc *func)
 {
        int i;
 
-       gnm_func_count_args (def,
-                            &def->fn.args.min_args,
-                            &def->fn.args.max_args);
-       def->fn.args.arg_types = g_malloc (def->fn.args.max_args + 1);
-       for (i = 0; i < def->fn.args.max_args; i++)
-               def->fn.args.arg_types[i] = gnm_func_get_arg_type (def, i);
-       def->fn.args.arg_types[i] = 0;
-}
-
-static GnmValue *
-error_function_no_full_info (GnmFuncEvalInfo *ei,
-                            int argc,
-                            GnmExprConstPtr const *argv)
-{
-       return value_new_error (ei->pos, _("Function implementation not available."));
+       gnm_func_count_args (func,
+                            &func->min_args,
+                            &func->max_args);
+       g_free (func->arg_types);
+       func->arg_types = NULL;
+
+       if (func->fn_type == GNM_FUNC_TYPE_ARGS) {
+               func->arg_types = g_malloc (func->max_args + 1);
+               for (i = 0; i < func->max_args; i++)
+                       func->arg_types[i] = gnm_func_get_arg_type (func, i);
+               func->arg_types[i] = 0;
+       }
 }
 
 static void
@@ -316,21 +349,18 @@ gnm_func_create_arg_names (GnmFunc *fn_def)
        fn_def->arg_names_p = ptr;
 }
 
-
-void
-gnm_func_load_stub (GnmFunc *func)
+gboolean
+gnm_func_is_vararg (GnmFunc *func)
 {
-       g_return_if_fail (func->fn_type == GNM_FUNC_TYPE_STUB);
-
-       g_signal_emit (G_OBJECT (func), signals[SIG_LOAD_STUB], 0);
-
-       if (func->fn_type == GNM_FUNC_TYPE_STUB) {
-               static GnmFuncHelp const no_help[] = { { GNM_FUNC_HELP_END } };
+       gnm_func_load_stub (func);
+       return func->fn_type == GNM_FUNC_TYPE_NODES;
+}
 
-               func->help = no_help;
-               func->fn.nodes = &error_function_no_full_info;
-               gnm_func_set_function_type (func, GNM_FUNC_TYPE_NODES);
-       }
+gboolean
+gnm_func_is_fixarg (GnmFunc *func)
+{
+       gnm_func_load_stub (func);
+       return func->fn_type == GNM_FUNC_TYPE_ARGS;
 }
 
 void
@@ -339,17 +369,11 @@ gnm_func_set_function_type (GnmFunc *func, GnmFuncType typ)
        g_return_if_fail (GNM_IS_FUNC (func));
 
        func->fn_type = typ;
-       switch (typ) {
-       case GNM_FUNC_TYPE_ARGS:
-               extract_arg_types (func);
-               gnm_func_create_arg_names (func);
-               break;
-       case GNM_FUNC_TYPE_NODES:
-               gnm_func_create_arg_names (func);
-               break;
-       case GNM_FUNC_TYPE_STUB:
-               break;
-       }
+       if (typ == GNM_FUNC_TYPE_STUB)
+               return;
+
+       extract_arg_types (func);
+       gnm_func_create_arg_names (func);
 }
 
 
@@ -535,6 +559,20 @@ gnm_func_set_translation_domain (GnmFunc *func, const char *tdomain)
        g_object_notify (G_OBJECT (func), "translation-domain");
 }
 
+/**
+ * gnm_func_get_function_group:
+ * @func: #GnmFunc
+ *
+ * Returns: (transfer none): the function group to which @func belongs.
+ */
+GnmFuncGroup *
+gnm_func_get_function_group (GnmFunc *func)
+{
+       g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
+       return func->fn_group;
+}
+
+
 void
 gnm_func_set_function_group (GnmFunc *func, GnmFuncGroup *group)
 {
@@ -1142,11 +1180,11 @@ function_call_with_exprs (GnmFuncEvalInfo *ei)
                return fn_def->fn.nodes (ei, argc, argv);
 
        /* Functions that take pre-computed Values */
-       if (argc > fn_def->fn.args.max_args ||
-           argc < fn_def->fn.args.min_args)
+       if (argc > fn_def->max_args ||
+           argc < fn_def->min_args)
                return value_new_error_NA (ei->pos);
 
-       args = g_alloca (sizeof (GnmValue *) * fn_def->fn.args.max_args);
+       args = g_alloca (sizeof (GnmValue *) * fn_def->max_args);
        iter_count = (eval_pos_is_array_context (ei->pos) &&
                      (flags & GNM_EXPR_EVAL_PERMIT_NON_SCALAR))
                ? 0 : -1;
@@ -1160,7 +1198,7 @@ function_call_with_exprs (GnmFuncEvalInfo *ei)
                      (GNM_EXPR_EVAL_ARRAY_CONTEXT));
 
        for (i = 0; i < argc; i++) {
-               char arg_type = fn_def->fn.args.arg_types[i];
+               char arg_type = fn_def->arg_types[i];
                /* expr is always non-null, missing args are encoded as
                 * const = empty */
                GnmExpr const *expr = argv[i];
@@ -1204,7 +1242,7 @@ function_call_with_exprs (GnmFuncEvalInfo *ei)
                        continue;
 
                /* optional arguments can be blank */
-               if (i >= fn_def->fn.args.min_args && VALUE_IS_EMPTY (tmp)) {
+               if (i >= fn_def->min_args && VALUE_IS_EMPTY (tmp)) {
                        if (arg_type == 'E' && !gnm_expr_is_empty (expr)) {
                                /* An actual argument produced empty.  Make
                                   sure function sees that.  */
@@ -1295,7 +1333,7 @@ function_call_with_exprs (GnmFuncEvalInfo *ei)
                }
        }
 
-       while (i < fn_def->fn.args.max_args)
+       while (i < fn_def->max_args)
                args [i++] = NULL;
 
        if (iter_item != NULL) {
@@ -1315,7 +1353,7 @@ function_call_with_exprs (GnmFuncEvalInfo *ei)
                                err = NULL;
                                for (i = 0 ; i < iter_count; i++) {
                                        elem = value_area_get_x_y (iter_vals[i], x, y, ei->pos);
-                                       arg_type = fn_def->fn.args.arg_types[iter_item[i]];
+                                       arg_type = fn_def->arg_types[iter_item[i]];
                                        if  (arg_type == 'b' || arg_type == 'f') {
                                                if (VALUE_IS_EMPTY (elem))
                                                        elem = value_zero;
@@ -1359,7 +1397,7 @@ function_call_with_exprs (GnmFuncEvalInfo *ei)
                for (i = 0 ; i < iter_count; i++)
                        args[iter_item[i]] = iter_vals[i];
                tmp = res;
-               i = fn_def->fn.args.max_args;
+               i = fn_def->max_args;
        } else
                tmp = fn_def->fn.args.func (ei, (GnmValue const * const *)args);
 
@@ -1400,7 +1438,7 @@ function_def_call_with_values (GnmEvalPos const *ep, GnmFunc const *fn_def,
        fs.func_call = &ef;
        ef.func = (GnmFunc *)fn_def;
 
-       gnm_func_load_if_stub ((GnmFunc *)fn_def);
+       gnm_func_load_if_stub (ef.func);
 
        if (fn_def->fn_type == GNM_FUNC_TYPE_NODES) {
                /*
@@ -1681,6 +1719,20 @@ gnm_func_finalize (GObject *obj)
 {
        GnmFunc *func = GNM_FUNC (obj);
 
+       g_free (func->arg_types);
+
+       g_free ((char *)func->name);
+
+       go_string_unref (func->tdomain);
+
+       parent_class->finalize (obj);
+}
+
+static void
+gnm_func_real_dispose (GObject *obj)
+{
+       GnmFunc *func = GNM_FUNC (obj);
+
        if (func->usage_count != 0) {
                g_printerr ("Function %s still has a usage count of %d\n",
                            func->name, func->usage_count);
@@ -1697,16 +1749,15 @@ gnm_func_finalize (GObject *obj)
                g_hash_table_remove (functions_by_name, func->name);
        }
 
-       if (func->fn_type == GNM_FUNC_TYPE_ARGS)
-               g_free (func->fn.args.arg_types);
-
-       g_free ((char *)func->name);
-
-       go_string_unref (func->tdomain);
-
        gnm_func_clear_arg_names (func);
 
-       parent_class->finalize (obj);
+       parent_class->dispose (obj);
+}
+
+void
+gnm_func_dispose (GnmFunc *func)
+{
+       g_object_run_dispose (G_OBJECT (func));
 }
 
 static void
@@ -1763,6 +1814,7 @@ gnm_func_class_init (GObjectClass *gobject_class)
        parent_class = g_type_class_peek_parent (gobject_class);
 
        gobject_class->finalize         = gnm_func_finalize;
+       gobject_class->dispose          = gnm_func_real_dispose;
        gobject_class->get_property     = gnm_func_get_property;
        gobject_class->set_property     = gnm_func_set_property;
 
diff --git a/src/func.h b/src/func.h
index 9673e01d5..0bb28ab3b 100644
--- a/src/func.h
+++ b/src/func.h
@@ -184,26 +184,29 @@ struct GnmFunc_ {
        GObject base;
 
        char const *name;
-       GPtrArray *arg_names_p;
        GnmFuncHelp const *help;
-       GOString *tdomain;
-       char *localized_name;
-       GnmFuncType fn_type;
        union {
                GnmFuncNodes nodes;
                struct {
                        char const *arg_spec;
-                       GnmFuncArgs  func;
-                       int min_args, max_args;
-                       char *arg_types;
+                       GnmFuncArgs func;
                } args;
        } fn;
-       GnmFuncGroup            *fn_group; /* most recent it was assigned to */
        GnmFuncImplStatus        impl_status;
        GnmFuncTestStatus        test_status;
        GnmFuncFlags             flags;
 
-       gint                     usage_count;
+       /* <private> */
+       GnmFuncType XXXfn_type;
+       GnmFuncGroup *XXXfn_group;
+       GOString *XXXtdomain;
+       char *XXXlocalized_name;
+       GPtrArray *XXXarg_names_p;
+       gint XXXusage_count;
+       int XXXmin_args, XXXmax_args;
+
+       // Meaningful for ARGS only
+       char *XXXarg_types;
 };
 
 #define GNM_FUNC_TYPE  (gnm_func_get_type ())
@@ -212,7 +215,7 @@ struct GnmFunc_ {
 
 GType       gnm_func_get_type        (void);
 void        gnm_func_load_if_stub    (GnmFunc *func);
-void       gnm_func_load_stub       (GnmFunc *func);
+void        gnm_func_dispose         (GnmFunc *func);
 
 GnmFunc           *gnm_func_inc_usage       (GnmFunc *func);
 void       gnm_func_dec_usage       (GnmFunc *func);
@@ -222,8 +225,11 @@ char const *gnm_func_get_translation_domain (GnmFunc *func);
 void        gnm_func_set_translation_domain (GnmFunc *func,
                                             const char *tdomain);
 
+GnmFuncGroup*gnm_func_get_function_group (GnmFunc *func);
 void        gnm_func_set_function_group (GnmFunc *func, GnmFuncGroup *group);
 
+gboolean    gnm_func_is_vararg         (GnmFunc *func);
+gboolean    gnm_func_is_fixarg         (GnmFunc *func);
 void        gnm_func_set_function_type (GnmFunc *func, GnmFuncType typ);
 
 GnmDependentFlags gnm_func_link_dep (GnmFunc *func, GnmFuncEvalInfo *ei, gboolean qlink);
diff --git a/src/gnm-plugin.c b/src/gnm-plugin.c
index fac15210e..d47c76366 100644
--- a/src/gnm-plugin.c
+++ b/src/gnm-plugin.c
@@ -207,29 +207,29 @@ plugin_service_function_group_activate (GOPluginService *service, GOErrorInfo **
 
        for (l = sfg->function_name_list; l; l = l->next) {
                const char *fname = l->data;
-               GnmFunc *fd = gnm_func_lookup_or_add_placeholder (fname);
+               GnmFunc *func = gnm_func_lookup_or_add_placeholder (fname);
 
-               gnm_func_set_function_type (fd, GNM_FUNC_TYPE_STUB);
-               gnm_func_set_translation_domain (fd, sfg->tdomain);
-               gnm_func_set_function_group (fd, sfg->func_group);
+               gnm_func_set_function_type (func, GNM_FUNC_TYPE_STUB);
+               gnm_func_set_translation_domain (func, sfg->tdomain);
+               gnm_func_set_function_group (func, sfg->func_group);
                // Clear localized_name so we can deduce the proper name.
-               //gnm_func_set_localized_name (fd, NULL);
+               //gnm_func_set_localized_name (func, NULL);
 
                g_signal_connect
-                       (G_OBJECT (fd), "notify::in-use",
+                       (func, "notify::in-use",
                         G_CALLBACK (plugin_service_function_group_func_ref_notify),
                         plugin);
 
                g_signal_connect
-                       (G_OBJECT (fd), "load-stub",
+                       (func, "load-stub",
                         G_CALLBACK (plugin_service_function_group_func_load_stub),
                         service);
 
-               if (fd->usage_count > 0)
+               if (gnm_func_get_in_use (func))
                        g_signal_connect (plugin,
                                          "state_changed",
                                          G_CALLBACK (delayed_ref_notify),
-                                         fd);
+                                         func);
        }
        service->is_active = TRUE;
 }
@@ -238,6 +238,7 @@ static void
 plugin_service_function_group_deactivate (GOPluginService *service, GOErrorInfo **ret_error)
 {
        GnmPluginServiceFunctionGroup *sfg = GNM_PLUGIN_SERVICE_FUNCTION_GROUP (service);
+       GOPlugin *plugin = go_plugin_service_get_plugin (service);
        GSList *l;
 
        if (gnm_debug_flag ("plugin-func"))
@@ -248,6 +249,17 @@ plugin_service_function_group_deactivate (GOPluginService *service, GOErrorInfo
        for (l = sfg->function_name_list; l; l = l->next) {
                const char *fname = l->data;
                GnmFunc *func = gnm_func_lookup (fname, NULL);
+
+               // This should not happen, but if it were to, having a handler
+               // of some other object is not going to be good.
+               if (gnm_func_get_in_use (func))
+                       g_signal_handlers_disconnect_by_func
+                               (plugin, G_CALLBACK (delayed_ref_notify), func);
+
+               // Someone else might hold a ref so make sure the object
+               // becomes inaccessible via gnm_func_lookup
+               gnm_func_dispose (func);
+
                g_object_unref (func);
        }
        service->is_active = FALSE;
diff --git a/src/ssgrep.c b/src/ssgrep.c
index bc90a84a0..5bc325823 100644
--- a/src/ssgrep.c
+++ b/src/ssgrep.c
@@ -213,8 +213,8 @@ cb_check_func (gpointer clean, gpointer orig, gpointer user_data)
 {
        StringTableSearch *state = user_data;
        GnmFunc *func = gnm_func_lookup (clean, state->wb);
-       if (NULL != func)
-               add_result (state, clean, func->usage_count);
+       if (func && gnm_func_get_in_use (func))
+               add_result (state, clean, 1);
 }
 
 static void
diff --git a/src/sstest.c b/src/sstest.c
index 8c1151326..79da7768f 100644
--- a/src/sstest.c
+++ b/src/sstest.c
@@ -92,7 +92,7 @@ static GOptionEntry const sstest_options [] = {
 /* ------------------------------------------------------------------------- */
 
 #define UNICODE_ELLIPSIS "\xe2\x80\xa6"
-#define F2(func,s) dgettext ((func)->tdomain->str, (s))
+#define F2(func,s) dgettext (gnm_func_get_translation_domain(func), (s))
 
 static char *
 split_at_colon (char const *s, char **rest)
@@ -124,7 +124,7 @@ dump_externals (GPtrArray *defs, FILE *out)
        fprintf (out, "<!--\n\n-->");
 
        for (ui = 0; ui < defs->len; ui++) {
-               GnmFunc const *fd = g_ptr_array_index (defs, ui);
+               GnmFunc *fd = g_ptr_array_index (defs, ui);
                gboolean any = FALSE;
                int j;
 
@@ -201,13 +201,13 @@ dump_samples (GPtrArray *defs, FILE *out)
        GnmFuncGroup *last_group = NULL;
 
        for (ui = 0; ui < defs->len; ui++) {
-               GnmFunc const *fd = g_ptr_array_index (defs, ui);
+               GnmFunc *fd = g_ptr_array_index (defs, ui);
                int j;
                const char *last = NULL;
                gboolean has_sample = FALSE;
 
-               if (last_group != fd->fn_group) {
-                       last_group = fd->fn_group;
+               if (last_group != gnm_func_get_function_group (fd)) {
+                       last_group = gnm_func_get_function_group (fd);
                        csv_quoted_print (out, last_group->display_name->str);
                        fputc ('\n', out);
                }
@@ -242,27 +242,21 @@ dump_samples (GPtrArray *defs, FILE *out)
        }
 }
 
-static void
-cb_dump_usage (GnmFunc const *fd, FILE *out)
-{
-       if (fd->usage_count > 0)
-               fprintf (out, "%d,%s\n", fd->usage_count, fd->name);
-}
-
-
-
 static int
 func_def_cmp (gconstpointer a, gconstpointer b)
 {
-       GnmFunc const *fda = *(GnmFunc const **)a ;
-       GnmFunc const *fdb = *(GnmFunc const **)b ;
+       GnmFunc *fda = *(GnmFunc **)a ;
+       GnmFunc *fdb = *(GnmFunc **)b ;
+       GnmFuncGroup *ga, *gb;
 
        g_return_val_if_fail (fda->name != NULL, 0);
        g_return_val_if_fail (fdb->name != NULL, 0);
 
-       if (fda->fn_group != NULL && fdb->fn_group != NULL) {
-               int res = go_string_cmp (fda->fn_group->display_name,
-                                        fdb->fn_group->display_name);
+       ga = gnm_func_get_function_group (fda);
+       gb = gnm_func_get_function_group (fdb);
+
+       if (ga && gb) {
+               int res = go_string_cmp (ga->display_name, gb->display_name);
                if (res != 0)
                        return res;
        }
@@ -310,7 +304,7 @@ enumerate_functions (gboolean filter)
  * 0 : www.gnumeric.org's function.shtml page
  * 1:
  * 2 : (obsolete)
- * 3 : dump function usage count
+ * 3 : (obsolete)
  * 4 : external refs
  * 5 : all sample expressions
  **/
@@ -330,15 +324,7 @@ function_dump_defs (char const *filename, int dump_type)
                exit (1);
        }
 
-       if (dump_type == 3) {
-               GPtrArray *funcs = enumerate_functions (FALSE);
-               g_ptr_array_foreach (funcs, (GFunc)cb_dump_usage, output_file);
-               g_ptr_array_free (funcs, TRUE);
-               fclose (output_file);
-               return;
-       }
-
-       /* TODO : Use the translated names and split by fn_group. */
+       /* TODO : Use the translated names and split by function group. */
        ordered = enumerate_functions (TRUE);
 
        if (dump_type == 4) {
@@ -439,7 +425,7 @@ function_dump_defs (char const *filename, int dump_type)
        }
 
        for (i = 0; i < ordered->len; i++) {
-               GnmFunc const *fd = g_ptr_array_index (ordered, i);
+               GnmFunc *fd = g_ptr_array_index (ordered, i);
 
                // Skip internal-use function
                if (g_ascii_strcasecmp (fd->name, "TABLE") == 0)
@@ -460,9 +446,10 @@ function_dump_defs (char const *filename, int dump_type)
                        GString *note = g_string_new (NULL);
                        GString *seealso = g_string_new (NULL);
                        gint min, max;
+                       GnmFuncGroup *group = gnm_func_get_function_group (fd);
 
                        fprintf (output_file, "@CATEGORY=%s\n",
-                                F2(fd, fd->fn_group->display_name->str));
+                                F2(fd, group->display_name->str));
                        for (i = 0;
                             fd->help[i].type != GNM_FUNC_HELP_END;
                             i++) {
@@ -589,9 +576,9 @@ function_dump_defs (char const *filename, int dump_type)
                                { "Under development",          "imp-devel" },
                                { "Unique to Gnumeric",         "imp-gnumeric" },
                        };
-                       if (group != fd->fn_group) {
+                       if (group != gnm_func_get_function_group (fd)) {
                                if (group) fprintf (output_file, "</table></div>\n");
-                               group = fd->fn_group;
+                               group = gnm_func_get_function_group (fd);
                                fprintf (output_file,
                                         "<h2>%s</h2>\n"
                                         "<div class=\"functiongroup\"><table class=\"functiongroup\">\n"
@@ -944,7 +931,7 @@ check_help_expression (const char *text, GnmFunc const *fd)
 static gboolean
 check_argument_refs (const char *text, GnmFunc const *fd)
 {
-       if (fd->fn_type != GNM_FUNC_TYPE_ARGS)
+       if (!gnm_func_is_fixarg (fd))
                return FALSE;
 
        while (1) {
@@ -1104,12 +1091,13 @@ gnm_func_sanity_check1 (GnmFunc const *fd)
 
        g_hash_table_destroy (allargs);
 
-       if (fd->fn_type == GNM_FUNC_TYPE_ARGS) {
+       if (gnm_func_is_fixarg (fd)) {
                int n = counts[GNM_FUNC_HELP_ARG];
-               if (n != fd->fn.args.max_args) {
+               int min, max;
+               gnm_func_count_args (fd, &min, &max);
+               if (n != max) {
                        g_printerr ("%s: Help for %d args, but takes %d-%d\n",
-                                   fd->name, n,
-                                   fd->fn.args.min_args, fd->fn.args.max_args);
+                                   fd->name, n, min, max);
                        res = 1;
                }
        }


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