Commit 592cd1c3 authored by Morten Welinder's avatar Morten Welinder

GnmFunc: fix life cycle of help texts too.

parent e83e7946
...@@ -464,7 +464,7 @@ call_python_function_args (GnmFuncEvalInfo *ei, GnmValue const * const *args) ...@@ -464,7 +464,7 @@ call_python_function_args (GnmFuncEvalInfo *ei, GnmValue const * const *args)
ServiceLoaderDataFunctionGroup *loader_data; ServiceLoaderDataFunctionGroup *loader_data;
PyObject *fn_info_tuple; PyObject *fn_info_tuple;
PyObject *python_fn; PyObject *python_fn;
GnmFunc const * fndef; GnmFunc *fndef;
gint min_n_args, max_n_args, n_args; gint min_n_args, max_n_args, n_args;
...@@ -675,9 +675,10 @@ gplp_func_load_stub (GOPluginService *service, ...@@ -675,9 +675,10 @@ gplp_func_load_stub (GOPluginService *service,
PyString_Check (python_args) && PyString_Check (python_args) &&
(python_fn = PyTuple_GetItem (fn_info_obj, 2)) != NULL && (python_fn = PyTuple_GetItem (fn_info_obj, 2)) != NULL &&
PyCallable_Check (python_fn)) { PyCallable_Check (python_fn)) {
GnmFuncHelp const *help = python_function_get_gnumeric_help
(loader_data->python_fn_info_dict, python_fn, name);
gnm_func_set_fixargs (func, call_python_function_args, PyString_AsString (python_args)); gnm_func_set_fixargs (func, call_python_function_args, PyString_AsString (python_args));
func->help = python_function_get_gnumeric_help ( gnm_func_set_help (func, help, -1);
loader_data->python_fn_info_dict, python_fn, name);
gnm_func_set_impl_status (func, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC); gnm_func_set_impl_status (func, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC);
g_object_set_data (G_OBJECT (func), SERVICE_KEY, service); g_object_set_data (G_OBJECT (func), SERVICE_KEY, service);
return; return;
...@@ -688,9 +689,10 @@ gplp_func_load_stub (GOPluginService *service, ...@@ -688,9 +689,10 @@ gplp_func_load_stub (GOPluginService *service,
} }
if (PyCallable_Check (fn_info_obj)) { if (PyCallable_Check (fn_info_obj)) {
gnm_func_set_varargs (func, call_python_function_nodes); GnmFuncHelp const *help = python_function_get_gnumeric_help
func->help = python_function_get_gnumeric_help ( (loader_data->python_fn_info_dict, fn_info_obj, name);
loader_data->python_fn_info_dict, fn_info_obj, name); gnm_func_set_varargs (func, call_python_function_nodes, NULL);
gnm_func_set_help (func, help, -1);
gnm_func_set_impl_status (func, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC); gnm_func_set_impl_status (func, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC);
g_object_set_data (G_OBJECT (func), SERVICE_KEY, service); g_object_set_data (G_OBJECT (func), SERVICE_KEY, service);
return; return;
......
...@@ -739,10 +739,13 @@ describe_new_style (GtkTextBuffer *description, ...@@ -739,10 +739,13 @@ describe_new_style (GtkTextBuffer *description,
gboolean seen_extref = FALSE; gboolean seen_extref = FALSE;
gboolean is_TEXT = gboolean is_TEXT =
g_ascii_strcasecmp (gnm_func_get_name (func, FALSE), "TEXT") == 0; g_ascii_strcasecmp (gnm_func_get_name (func, FALSE), "TEXT") == 0;
int n;
gtk_text_buffer_get_end_iter (description, &ti); gtk_text_buffer_get_end_iter (description, &ti);
for (help = func->help; 1; help++) { help = gnm_func_get_help (func, &n);
for (; n-- > 0; help++) {
switch (help->type) { switch (help->type) {
case GNM_FUNC_HELP_NAME: { case GNM_FUNC_HELP_NAME: {
const char *text = gnm_func_gettext (func, help->text); const char *text = gnm_func_gettext (func, help->text);
...@@ -839,9 +842,6 @@ describe_new_style (GtkTextBuffer *description, ...@@ -839,9 +842,6 @@ describe_new_style (GtkTextBuffer *description,
ADD_TEXT ("\n"); ADD_TEXT ("\n");
break; break;
} }
case GNM_FUNC_HELP_END:
FINISH_ARGS;
return;
case GNM_FUNC_HELP_EXTREF: { case GNM_FUNC_HELP_EXTREF: {
GtkTextTag *link; GtkTextTag *link;
char *uri, *tagname; char *uri, *tagname;
...@@ -899,6 +899,7 @@ describe_new_style (GtkTextBuffer *description, ...@@ -899,6 +899,7 @@ describe_new_style (GtkTextBuffer *description,
break; break;
} }
} }
FINISH_ARGS;
} }
#undef ADD_TEXT_WITH_ARGS #undef ADD_TEXT_WITH_ARGS
...@@ -1063,7 +1064,7 @@ cb_dialog_function_select_fun_selection_changed (GtkTreeSelection *selection, ...@@ -1063,7 +1064,7 @@ cb_dialog_function_select_fun_selection_changed (GtkTreeSelection *selection,
gnm_func_load_if_stub (func); gnm_func_load_if_stub (func);
if (func->help == NULL) if (gnm_func_get_help (func, NULL) == NULL)
gtk_text_buffer_set_text (description, "?", -1); gtk_text_buffer_set_text (description, "?", -1);
else else
describe_new_style (description, describe_new_style (description,
...@@ -1084,14 +1085,15 @@ static const gchar * ...@@ -1084,14 +1085,15 @@ static const gchar *
dialog_function_select_peek_description (GnmFunc *func) dialog_function_select_peek_description (GnmFunc *func)
{ {
GnmFuncHelp const *help; GnmFuncHelp const *help;
int n;
gnm_func_load_if_stub (func); gnm_func_load_if_stub (func);
help = func->help;
help = gnm_func_get_help (func, &n);
if (help == NULL) if (help == NULL)
return ""; return "";
for (; TRUE; help++) { for (; n-- > 0; help++) {
switch (help->type) { switch (help->type) {
case GNM_FUNC_HELP_ARG: case GNM_FUNC_HELP_ARG:
case GNM_FUNC_HELP_NOTE: case GNM_FUNC_HELP_NOTE:
...@@ -1108,10 +1110,9 @@ dialog_function_select_peek_description (GnmFunc *func) ...@@ -1108,10 +1110,9 @@ dialog_function_select_peek_description (GnmFunc *func)
const char *colon = strchr (text, ':'); const char *colon = strchr (text, ':');
return (colon ? colon + 1 : text); return (colon ? colon + 1 : text);
} }
case GNM_FUNC_HELP_END:
return "";
} }
} }
return "";
} }
......
...@@ -510,7 +510,7 @@ static GnmFuncDescriptor const builtins [] = { ...@@ -510,7 +510,7 @@ static GnmFuncDescriptor const builtins [] = {
GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
GNM_FUNC_TEST_STATUS_EXHAUSTIVE GNM_FUNC_TEST_STATUS_EXHAUSTIVE
}, },
{ "table", "", { "table", NULL,
help_table, NULL, gnumeric_table, help_table, NULL, gnumeric_table,
GNM_FUNC_SIMPLE + GNM_FUNC_INTERNAL, GNM_FUNC_SIMPLE + GNM_FUNC_INTERNAL,
GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
......
...@@ -134,9 +134,8 @@ gnm_func_load_stub (GnmFunc *func) ...@@ -134,9 +134,8 @@ gnm_func_load_stub (GnmFunc *func)
g_signal_emit (G_OBJECT (func), signals[SIG_LOAD_STUB], 0); g_signal_emit (G_OBJECT (func), signals[SIG_LOAD_STUB], 0);
if (func->fn_type == GNM_FUNC_TYPE_STUB) { if (func->fn_type == GNM_FUNC_TYPE_STUB) {
static GnmFuncHelp const no_help[] = { { GNM_FUNC_HELP_END } }; gnm_func_set_varargs (func, error_function_no_full_info, NULL);
gnm_func_set_varargs (func, error_function_no_full_info); gnm_func_set_help (func, NULL, 0);
func->help = no_help;
} }
} }
...@@ -256,21 +255,21 @@ gnm_func_group_get_nth (int n) ...@@ -256,21 +255,21 @@ gnm_func_group_get_nth (int n)
} }
static void static void
gnm_func_group_add_func (GnmFuncGroup *fn_group, GnmFunc *fn_def) gnm_func_group_add_func (GnmFuncGroup *fn_group, GnmFunc *func)
{ {
g_return_if_fail (fn_group != NULL); g_return_if_fail (fn_group != NULL);
g_return_if_fail (fn_def != NULL); g_return_if_fail (func != NULL);
fn_group->functions = g_slist_prepend (fn_group->functions, fn_def); fn_group->functions = g_slist_prepend (fn_group->functions, func);
} }
static void static void
gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *fn_def) gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *func)
{ {
g_return_if_fail (fn_group != NULL); g_return_if_fail (fn_group != NULL);
g_return_if_fail (fn_def != NULL); g_return_if_fail (func != NULL);
fn_group->functions = g_slist_remove (fn_group->functions, fn_def); fn_group->functions = g_slist_remove (fn_group->functions, func);
if (fn_group->functions == NULL) { if (fn_group->functions == NULL) {
categories = g_list_remove (categories, fn_group); categories = g_list_remove (categories, fn_group);
if (unknown_cat == fn_group) if (unknown_cat == fn_group)
...@@ -282,26 +281,24 @@ gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *fn_def) ...@@ -282,26 +281,24 @@ gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *fn_def)
/******************************************************************************/ /******************************************************************************/
static void static void
gnm_func_create_arg_names (GnmFunc *fn_def) gnm_func_create_arg_names (GnmFunc *func)
{ {
int i; int i;
GPtrArray *ptr; GPtrArray *ptr;
g_return_if_fail (fn_def != NULL); g_return_if_fail (func != NULL);
ptr = g_ptr_array_new (); ptr = g_ptr_array_new ();
for (i = 0; for (i = 0; i < func->help_count; i++) {
fn_def->help && fn_def->help[i].type != GNM_FUNC_HELP_END;
i++) {
const char *s; const char *s;
if (fn_def->help[i].type != GNM_FUNC_HELP_ARG) if (func->help[i].type != GNM_FUNC_HELP_ARG)
continue; continue;
s = gnm_func_gettext (fn_def, fn_def->help[i].text); s = gnm_func_gettext (func, func->help[i].text);
g_ptr_array_add (ptr, split_at_colon (s, NULL)); g_ptr_array_add (ptr, split_at_colon (s, NULL));
} }
fn_def->arg_names = ptr; func->arg_names = ptr;
} }
gboolean gboolean
...@@ -339,15 +336,18 @@ gnm_func_set_stub (GnmFunc *func) ...@@ -339,15 +336,18 @@ gnm_func_set_stub (GnmFunc *func)
func->nodes_func = NULL; func->nodes_func = NULL;
func->args_func = NULL; func->args_func = NULL;
gnm_func_set_help (func, NULL, 0);
} }
/** /**
* gnm_func_set_varargs: (skip) * gnm_func_set_varargs: (skip)
* @func: #GnmFunc * @func: #GnmFunc
* @fn: evaluation function * @fn: evaluation function
* @spec: (optional): argument type specification
*/ */
void void
gnm_func_set_varargs (GnmFunc *func, GnmFuncNodes fn) gnm_func_set_varargs (GnmFunc *func, GnmFuncNodes fn, const char *spec)
{ {
g_return_if_fail (GNM_IS_FUNC (func)); g_return_if_fail (GNM_IS_FUNC (func));
g_return_if_fail (fn != NULL); g_return_if_fail (fn != NULL);
...@@ -356,8 +356,16 @@ gnm_func_set_varargs (GnmFunc *func, GnmFuncNodes fn) ...@@ -356,8 +356,16 @@ gnm_func_set_varargs (GnmFunc *func, GnmFuncNodes fn)
func->fn_type = GNM_FUNC_TYPE_NODES; func->fn_type = GNM_FUNC_TYPE_NODES;
func->nodes_func = fn; func->nodes_func = fn;
func->arg_spec = g_strdup (spec);
func->min_args = 0; func->min_args = 0;
func->min_args = G_MAXINT; func->min_args = G_MAXINT;
if (spec) {
const char *p = strchr (spec, '|');
const char *q = strchr (spec, '.'); // "..."
if (p) func->min_args = p - spec;
if (!q) func->min_args = strlen (spec) - (p != NULL);
}
} }
/** /**
...@@ -393,6 +401,61 @@ gnm_func_set_fixargs (GnmFunc *func, GnmFuncArgs fn, const char *spec) ...@@ -393,6 +401,61 @@ gnm_func_set_fixargs (GnmFunc *func, GnmFuncArgs fn, const char *spec)
gnm_func_create_arg_names (func); gnm_func_create_arg_names (func);
} }
/**
* gnm_func_get_help:
* @func: #GnmFunc
* @n: (out) (optional): number of help items, not counting the end item
*
* Returns: (transfer none) (array length=n) (nullable): @func's help items.
*/
GnmFuncHelp const *
gnm_func_get_help (GnmFunc *func, int *n)
{
if (n) *n = 0;
g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
g_return_val_if_fail (func->help, NULL);
if (n) *n = func->help_count;
return func->help;
}
void
gnm_func_set_help (GnmFunc *func, GnmFuncHelp const *help, int n)
{
g_return_if_fail (GNM_IS_FUNC (func));
g_return_if_fail (n <= 0 || help != NULL);
if (n < 0) {
for (n = 0; help && help[n].type != GNM_FUNC_HELP_END; )
n++;
}
if (func->help) {
int i;
for (i = 0; i <= func->help_count; i++)
g_free ((char *)(func->help[i].text));
g_free (func->help);
func->help = NULL;
}
if (help) {
int i;
func->help = g_new (GnmFuncHelp, n + 1);
for (i = 0; i < n; i++) {
func->help[i].type = help[i].type;
func->help[i].text = g_strdup (help[i].text);
}
func->help[n].type = GNM_FUNC_HELP_END;
func->help[n].text = NULL;
}
func->help_count = n;
}
static void static void
gnm_func_set_localized_name (GnmFunc *fd, const char *lname) gnm_func_set_localized_name (GnmFunc *fd, const char *lname)
{ {
...@@ -580,7 +643,7 @@ gnm_func_set_translation_domain (GnmFunc *func, const char *tdomain) ...@@ -580,7 +643,7 @@ gnm_func_set_translation_domain (GnmFunc *func, const char *tdomain)
* @func: #GnmFunc * @func: #GnmFunc
* @str: string to translate * @str: string to translate
* *
* Returns: (transfer none): @str translated in the relevant translation * Returns: (transfer none): @str translated in @func's translation
* domain. * domain.
*/ */
char const * char const *
...@@ -589,7 +652,7 @@ gnm_func_gettext (GnmFunc *func, const char *str) ...@@ -589,7 +652,7 @@ gnm_func_gettext (GnmFunc *func, const char *str)
g_return_val_if_fail (GNM_IS_FUNC (func), NULL); g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
g_return_val_if_fail (str != NULL, NULL); g_return_val_if_fail (str != NULL, NULL);
return dgettext ((func)->tdomain->str, str); return dgettext (func->tdomain->str, str);
} }
...@@ -674,6 +737,8 @@ gnm_func_set_function_group (GnmFunc *func, GnmFuncGroup *group) ...@@ -674,6 +737,8 @@ gnm_func_set_function_group (GnmFunc *func, GnmFuncGroup *group)
void void
gnm_func_set_from_desc (GnmFunc *func, GnmFuncDescriptor const *desc) gnm_func_set_from_desc (GnmFunc *func, GnmFuncDescriptor const *desc)
{ {
//static char const valid_tokens[] = "fsbraAES?|";
g_return_if_fail (GNM_IS_FUNC (func)); g_return_if_fail (GNM_IS_FUNC (func));
g_return_if_fail (desc != NULL); g_return_if_fail (desc != NULL);
...@@ -683,15 +748,13 @@ gnm_func_set_from_desc (GnmFunc *func, GnmFuncDescriptor const *desc) ...@@ -683,15 +748,13 @@ gnm_func_set_from_desc (GnmFunc *func, GnmFuncDescriptor const *desc)
if (desc->fn_args != NULL) { if (desc->fn_args != NULL) {
gnm_func_set_fixargs (func, desc->fn_args, desc->arg_spec); gnm_func_set_fixargs (func, desc->fn_args, desc->arg_spec);
} else if (desc->fn_nodes != NULL) { } else if (desc->fn_nodes != NULL) {
if (desc->arg_spec && *desc->arg_spec) gnm_func_set_varargs (func, desc->fn_nodes, desc->arg_spec);
g_warning ("Arg spec for node function -- why?");
gnm_func_set_varargs (func, desc->fn_nodes);
} else { } else {
gnm_func_set_stub (func); gnm_func_set_stub (func);
return; return;
} }
func->help = desc->help ? desc->help : NULL; gnm_func_set_help (func, desc->help, -1);
func->flags = desc->flags; func->flags = desc->flags;
func->impl_status = desc->impl_status; func->impl_status = desc->impl_status;
func->test_status = desc->test_status; func->test_status = desc->test_status;
...@@ -711,7 +774,6 @@ gnm_func_add (GnmFuncGroup *fn_group, ...@@ -711,7 +774,6 @@ gnm_func_add (GnmFuncGroup *fn_group,
GnmFuncDescriptor const *desc, GnmFuncDescriptor const *desc,
const char *tdomain) const char *tdomain)
{ {
//static char const valid_tokens[] = "fsbraAES?|";
GnmFunc *func; GnmFunc *func;
g_return_val_if_fail (fn_group != NULL, NULL); g_return_val_if_fail (fn_group != NULL, NULL);
...@@ -916,11 +978,7 @@ gnm_func_get_name (GnmFunc const *func, gboolean localized) ...@@ -916,11 +978,7 @@ gnm_func_get_name (GnmFunc const *func, gboolean localized)
gnm_func_load_if_stub (fd); gnm_func_load_if_stub (fd);
for (i = 0; for (i = 0; func->localized_name == NULL && i < func->help_count; i++) {
(func->localized_name == NULL &&
func->help &&
func->help[i].type != GNM_FUNC_HELP_END);
i++) {
const char *s, *sl; const char *s, *sl;
char *U; char *U;
if (func->help[i].type != GNM_FUNC_HELP_NAME) if (func->help[i].type != GNM_FUNC_HELP_NAME)
...@@ -960,9 +1018,7 @@ gnm_func_get_description (GnmFunc *func) ...@@ -960,9 +1018,7 @@ gnm_func_get_description (GnmFunc *func)
gnm_func_load_if_stub (func); gnm_func_load_if_stub (func);
for (i = 0; for (i = 0; i < func->help_count; i++) {
func->help && func->help[i].type != GNM_FUNC_HELP_END;
i++) {
const char *desc; const char *desc;
if (func->help[i].type != GNM_FUNC_HELP_NAME) if (func->help[i].type != GNM_FUNC_HELP_NAME)
...@@ -976,7 +1032,7 @@ gnm_func_get_description (GnmFunc *func) ...@@ -976,7 +1032,7 @@ gnm_func_get_description (GnmFunc *func)
/** /**
* gnm_func_count_args: * gnm_func_count_args:
* @fn_def: pointer to function definition * @func: pointer to function definition
* @min: (out): location for mininum args * @min: (out): location for mininum args
* @max: (out): location for mininum args * @max: (out): location for mininum args
* *
...@@ -984,49 +1040,48 @@ gnm_func_get_description (GnmFunc *func) ...@@ -984,49 +1040,48 @@ gnm_func_get_description (GnmFunc *func)
* For a vararg function, the maximum will be set to G_MAXINT. * For a vararg function, the maximum will be set to G_MAXINT.
**/ **/
void void
gnm_func_count_args (GnmFunc const *fn_def, int *min, int *max) gnm_func_count_args (GnmFunc *func, int *min, int *max)
{ {
g_return_if_fail (min != NULL); g_return_if_fail (min != NULL);
g_return_if_fail (max != NULL); g_return_if_fail (max != NULL);
g_return_if_fail (fn_def != NULL); g_return_if_fail (func != NULL);
gnm_func_load_if_stub ((GnmFunc *)fn_def); gnm_func_load_if_stub (func);
*min = fn_def->min_args; *min = func->min_args;
*max = fn_def->max_args; *max = func->max_args;
} }
/** /**
* gnm_func_get_arg_type: * gnm_func_get_arg_type:
* @fn_def: the fn defintion * @func: the fn defintion
* @arg_idx: zero-based argument offset * @arg_idx: zero-based argument offset
* *
* Returns: the type of the argument * Returns: the type of the argument
**/ **/
char char
gnm_func_get_arg_type (GnmFunc const *fn_def, int arg_idx) gnm_func_get_arg_type (GnmFunc *func, int arg_idx)
{ {
g_return_val_if_fail (fn_def != NULL, '?'); g_return_val_if_fail (func != NULL, '?');
gnm_func_load_if_stub ((GnmFunc *)fn_def); gnm_func_load_if_stub (func);
g_return_val_if_fail (arg_idx >= 0 && arg_idx < fn_def->max_args, '?'); g_return_val_if_fail (arg_idx >= 0 && arg_idx < func->max_args, '?');
return fn_def->arg_types ? fn_def->arg_types[arg_idx] : '?'; return func->arg_types ? func->arg_types[arg_idx] : '?';
} }
/** /**
* gnm_func_get_arg_type_string: * gnm_func_get_arg_type_string:
* @fn_def: the fn defintion * @func: the fn defintion
* @arg_idx: zero-based argument offset * @arg_idx: zero-based argument offset
* *
* Return value: (transfer none): the type of the argument as a string * Return value: (transfer none): the type of the argument as a string
**/ **/
char const * char const *
gnm_func_get_arg_type_string (GnmFunc const *fn_def, gnm_func_get_arg_type_string (GnmFunc *func, int arg_idx)
int arg_idx)
{ {
switch (gnm_func_get_arg_type (fn_def, arg_idx)) { switch (gnm_func_get_arg_type (func, arg_idx)) {
case 'f': case 'f':
return _("Number"); return _("Number");
case 's': case 's':
...@@ -1085,9 +1140,7 @@ gnm_func_get_arg_description (GnmFunc *func, guint arg_idx) ...@@ -1085,9 +1140,7 @@ gnm_func_get_arg_description (GnmFunc *func, guint arg_idx)
gnm_func_load_if_stub (func); gnm_func_load_if_stub (func);
for (i = 0; for (i = 0; i < func->help_count; i++) {
func->help && func->help[i].type != GNM_FUNC_HELP_END;
i++) {
gchar const *desc; gchar const *desc;
if (func->help[i].type != GNM_FUNC_HELP_ARG) if (func->help[i].type != GNM_FUNC_HELP_ARG)
......
...@@ -76,13 +76,6 @@ typedef enum { ...@@ -76,13 +76,6 @@ typedef enum {
GNM_FUNC_VOLATILE = 1 << 0, /* eg now(), today() */ GNM_FUNC_VOLATILE = 1 << 0, /* eg now(), today() */
GNM_FUNC_RETURNS_NON_SCALAR = 1 << 1, /* eg transpose(), mmult() */ GNM_FUNC_RETURNS_NON_SCALAR = 1 << 1, /* eg transpose(), mmult() */
/* For functions that are not exactly compatible with various import
* formats. We need to recalc their results to avoid changing values
* unexpectedly when we recalc later. This probably needs to be done
* on a per import format basis. It may not belong here.
*/
/* GNM_FUNC_RECALC_ONLOAD = 1 << 2, */
/* an unknown function that will hopefully be defined later */ /* an unknown function that will hopefully be defined later */
GNM_FUNC_IS_PLACEHOLDER = 1 << 3, GNM_FUNC_IS_PLACEHOLDER = 1 << 3,
GNM_FUNC_IS_WORKBOOK_LOCAL = 1 << 5, GNM_FUNC_IS_WORKBOOK_LOCAL = 1 << 5,
...@@ -184,7 +177,7 @@ struct GnmFunc_ { ...@@ -184,7 +177,7 @@ struct GnmFunc_ {
GObject base; GObject base;
char const *name; char const *name;
GnmFuncHelp const *help; GnmFuncHelp *help;
/* <private> */ /* <private> */
GnmFuncType fn_type; GnmFuncType fn_type;
...@@ -209,6 +202,7 @@ struct GnmFunc_ { ...@@ -209,6 +202,7 @@ struct GnmFunc_ {
GPtrArray *arg_names; GPtrArray *arg_names;
int min_args, max_args; int min_args, max_args;
char *arg_types; char *arg_types;
int help_count;
}; };
#define GNM_FUNC_TYPE (gnm_func_get_type ()) #define GNM_FUNC_TYPE (gnm_func_get_type ())
...@@ -245,10 +239,14 @@ gboolean gnm_func_is_varargs (GnmFunc *func); ...@@ -245,10 +239,14 @@ gboolean gnm_func_is_varargs (GnmFunc *func);
gboolean gnm_func_is_fixargs (GnmFunc *func); gboolean gnm_func_is_fixargs (GnmFunc *func);
void gnm_func_set_stub (GnmFunc *func); void gnm_func_set_stub (GnmFunc *func);
void gnm_func_set_varargs (GnmFunc *func, GnmFuncNodes fn); void gnm_func_set_varargs (GnmFunc *func, GnmFuncNodes fn,
const char *spec);
void gnm_func_set_fixargs (GnmFunc *func, GnmFuncArgs fn, void gnm_func_set_fixargs (GnmFunc *func, GnmFuncArgs fn,
const char *spec); const char *spec);
GnmFuncHelp const *gnm_func_get_help (GnmFunc *func, int *n);
void gnm_func_set_help (GnmFunc *func, GnmFuncHelp const *help, int n);
GnmDependentFlags gnm_func_link_dep (GnmFunc *func, GnmFuncEvalInfo *ei, gboolean qlink); GnmDependentFlags gnm_func_link_dep (GnmFunc *func, GnmFuncEvalInfo *ei, gboolean qlink);
char const *gnm_func_get_name (GnmFunc const *func, char const *gnm_func_get_name (GnmFunc const *func,
...@@ -270,12 +268,9 @@ GnmFunc *gnm_func_lookup_or_add_placeholder (char const *name); ...@@ -270,12 +268,9 @@ GnmFunc *gnm_func_lookup_or_add_placeholder (char const *name);
/* TODO */ /* TODO */
char const *gnm_func_get_description (GnmFunc *func); char const *gnm_func_get_description (GnmFunc *func);
void gnm_func_count_args (GnmFunc const *fn_def, void gnm_func_count_args (GnmFunc *func, gint *min, int *max);
gint *min, int *max); char gnm_func_get_arg_type (GnmFunc *func, gint arg_idx);
char gnm_func_get_arg_type (GnmFunc const *fn_def, char const *gnm_func_get_arg_type_string (GnmFunc *func, gint arg_idx);
gint arg_idx);
char const *gnm_func_get_arg_type_string (GnmFunc const *fn_def,
gint arg_idx);
char *gnm_func_get_arg_name (GnmFunc const *func, guint arg_idx); char *gnm_func_get_arg_name (GnmFunc const *func, guint arg_idx);
char const *gnm_func_get_arg_description (GnmFunc *func, guint arg_idx); char const *gnm_func_get_arg_description (GnmFunc *func, guint arg_idx);
char *gnm_func_convert_markup_to_pango (char const *desc, char *gnm_func_convert_markup_to_pango (char const *desc,
......
...@@ -125,12 +125,13 @@ dump_externals (GPtrArray *defs, FILE *out) ...@@ -125,12 +125,13 @@ dump_externals (GPtrArray *defs, FILE *out)
for (ui = 0; ui < defs->len; ui++) { for (ui = 0; ui < defs->len; ui++) {
GnmFunc *fd = g_ptr_array_index (defs, ui); GnmFunc *fd = g_ptr_array_index (defs, ui);
gboolean any = FALSE; gboolean any = FALSE;
int j; int j, n;
GnmFuncHelp const *help = gnm_func_get_help (fd, &n);
for (j = 0; fd->help[j].type != GNM_FUNC_HELP_END; j++) { for (j = 0; j < n; j++) {
const char *s = gnm_func_gettext (fd, fd->help[j].text); const char *s = gnm_func_gettext (fd, help[j].text);
switch (fd->help[j].type) { switch (help[j].type) {
case GNM_FUNC_HELP_EXTREF: case GNM_FUNC_HELP_EXTREF:
if (!any) { if (!any) {
any = TRUE; any = TRUE;
...@@ -201,9 +202,10 @@ dump_samples (GPtrArray *defs, FILE *out) ...@@ -201,9 +202,10 @@ dump_samples (GPtrArray *defs, FILE *out)
for (ui = 0; ui < defs->len; ui++) { for (ui = 0; ui < defs->len; ui++) {
GnmFunc *fd = g_ptr_array_index (defs, ui); GnmFunc *fd = g_ptr_array_index (defs, ui);
int j; int j, n;
const char *last = NULL; const char *last = NULL;
gboolean has_sample = FALSE; gboolean has_sample = FALSE;
GnmFuncHelp const *help = gnm_func_get_help (fd, &n);
if (last_group != gnm_func_get_function_group (fd)) { if (last_group != gnm_func_get_function_group (fd)) {
last_group = gnm_func_get_function_group (fd); last_group = gnm_func_get_function_group (fd);
...@@ -211,10 +213,10 @@ dump_samples (GPtrArray *defs, FILE *out) ...@@ -211,10 +213,10 @@ dump_samples (GPtrArray *defs, FILE *out)
fputc ('\n', out); fputc ('\n', out);
}