It's 3.30.1 release day, upload a tarball and enjoy the fixes of those pesky bugs 🐛

Commit f0514e58 authored by Morten Welinder's avatar Morten Welinder

GnmFunc: further cleanups.

parent 8dd9f9c4
......@@ -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
......
......@@ -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).
......
......@@ -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
......@@ -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 */
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......
......@@ -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) {