Move plugin init code
[gnumeric.git] / src / func.c
blob0ec7d7ed86295eb701e12290fa376e0c023269d8
2 /*
3 * func.c: Function management and utility routines.
5 * Author:
6 * Miguel de Icaza (miguel@gnu.org)
7 * Michael Meeks (mmeeks@gnu.org)
8 * Morten Welinder (terra@gnome.org)
9 * Jody Goldberg (jody@gnome.org)
11 #include <gnumeric-config.h>
12 #include <glib/gi18n-lib.h>
13 #include <glib/gstdio.h>
14 #include <gnumeric.h>
15 #include <func.h>
17 #include <parse-util.h>
18 #include <dependent.h>
19 #include <expr.h>
20 #include <expr-impl.h>
21 #include <expr-name.h>
22 #include <cell.h>
23 #include <workbook-priv.h>
24 #include <sheet.h>
25 #include <value.h>
26 #include <number-match.h>
27 #include <func-builtin.h>
28 #include <command-context-stderr.h>
29 #include <gnm-plugin.h>
30 #include <gutils.h>
31 #include <gui-util.h>
33 #include <goffice/goffice.h>
34 #include <glib.h>
35 #include <string.h>
36 #include <stdlib.h>
38 #define F2(func,s) dgettext ((func)->tdomain->str, (s))
40 static GList *categories;
41 static GnmFuncGroup *unknown_cat;
43 static GHashTable *functions_by_name;
44 static GHashTable *functions_by_localized_name;
46 /**
47 * functions_init: (skip)
49 void
50 functions_init (void)
52 functions_by_name =
53 g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal);
55 /* FIXME: ascii??? */
56 functions_by_localized_name =
57 g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal);
59 func_builtin_init ();
62 /**
63 * functions_shutdown: (skip)
65 void
66 functions_shutdown (void)
68 while (unknown_cat != NULL && unknown_cat->functions != NULL) {
69 GnmFunc *func = unknown_cat->functions->data;
70 if (func->usage_count > 0) {
71 g_warning ("Function %s still has %d users.\n",
72 gnm_func_get_name (func, FALSE),
73 func->usage_count);
74 func->usage_count = 0;
76 gnm_func_free (func);
78 func_builtin_shutdown ();
80 g_hash_table_destroy (functions_by_name);
81 functions_by_name = NULL;
83 g_hash_table_destroy (functions_by_localized_name);
84 functions_by_localized_name = NULL;
87 /**
88 * gnm_func_enumerate:
90 * Return value: (element-type GnmFunc) (transfer container):
92 GPtrArray *
93 gnm_func_enumerate (void)
95 GPtrArray *res = g_ptr_array_new ();
96 GHashTableIter hiter;
97 gpointer value;
99 g_hash_table_iter_init (&hiter, functions_by_name);
100 while (g_hash_table_iter_next (&hiter, NULL, &value))
101 g_ptr_array_add (res, value);
103 return res;
106 inline void
107 gnm_func_load_if_stub (GnmFunc *func)
109 if (func->fn_type == GNM_FUNC_TYPE_STUB)
110 gnm_func_load_stub (func);
113 static char *
114 split_at_colon (char const *s, char **rest)
116 char *dup = g_strdup (s);
117 char *colon = strchr (dup, ':');
118 if (colon) {
119 *colon = 0;
120 if (rest) *rest = colon + 1;
121 } else {
122 if (rest) *rest = NULL;
124 return dup;
127 /* ------------------------------------------------------------------------- */
129 static void
130 gnm_func_group_free (GnmFuncGroup *fn_group)
132 g_return_if_fail (fn_group != NULL);
133 g_return_if_fail (fn_group->functions == NULL);
135 if (fn_group->ref_count-- > 1)
136 return;
138 go_string_unref (fn_group->internal_name);
139 go_string_unref (fn_group->display_name);
140 g_free (fn_group);
143 static GnmFuncGroup *
144 gnm_func_group_ref (GnmFuncGroup *fn_group)
146 fn_group->ref_count++;
147 return fn_group;
150 GType
151 gnm_func_group_get_type (void)
153 static GType t = 0;
155 if (t == 0) {
156 t = g_boxed_type_register_static ("GnmFuncGroup",
157 (GBoxedCopyFunc)gnm_func_group_ref,
158 (GBoxedFreeFunc)gnm_func_group_free);
160 return t;
163 static gint
164 function_category_compare (gconstpointer a, gconstpointer b)
166 GnmFuncGroup const *cat_a = a;
167 GnmFuncGroup const *cat_b = b;
169 return go_string_cmp (cat_a->display_name, cat_b->display_name);
172 GnmFuncGroup *
173 gnm_func_group_fetch (char const *name, char const *translation)
175 GnmFuncGroup *cat = NULL;
176 GList *l;
178 g_return_val_if_fail (name != NULL, NULL);
180 for (l = categories; l != NULL; l = l->next) {
181 cat = l->data;
182 if (strcmp (cat->internal_name->str, name) == 0) {
183 break;
187 if (l == NULL) {
188 cat = g_new (GnmFuncGroup, 1);
189 cat->internal_name = go_string_new (name);
190 cat->ref_count = 1;
191 if (translation != NULL) {
192 cat->display_name = go_string_new (translation);
193 cat->has_translation = TRUE;
194 } else {
195 cat->display_name = go_string_new (name);
196 cat->has_translation = FALSE;
198 cat->functions = NULL;
199 categories = g_list_insert_sorted (
200 categories, cat, &function_category_compare);
201 } else if (translation != NULL && translation != name &&
202 !cat->has_translation) {
203 go_string_unref (cat->display_name);
204 cat->display_name = go_string_new (translation);
205 cat->has_translation = TRUE;
206 categories = g_list_remove_link (categories, l);
207 g_list_free_1 (l);
208 categories = g_list_insert_sorted (
209 categories, cat, &function_category_compare);
212 return cat;
215 GnmFuncGroup *
216 gnm_func_group_get_nth (int n)
218 return g_list_nth_data (categories, n);
221 static void
222 gnm_func_group_add_func (GnmFuncGroup *fn_group, GnmFunc *fn_def)
224 g_return_if_fail (fn_group != NULL);
225 g_return_if_fail (fn_def != NULL);
227 fn_group->functions = g_slist_prepend (fn_group->functions, fn_def);
230 static void
231 gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *fn_def)
233 g_return_if_fail (fn_group != NULL);
234 g_return_if_fail (fn_def != NULL);
236 fn_group->functions = g_slist_remove (fn_group->functions, fn_def);
237 if (fn_group->functions == NULL) {
238 categories = g_list_remove (categories, fn_group);
239 if (unknown_cat == fn_group)
240 unknown_cat = NULL;
241 gnm_func_group_free (fn_group);
245 /******************************************************************************/
247 static void
248 extract_arg_types (GnmFunc *def)
250 int i;
252 gnm_func_count_args (def,
253 &def->fn.args.min_args,
254 &def->fn.args.max_args);
255 def->fn.args.arg_types = g_malloc (def->fn.args.max_args + 1);
256 for (i = 0; i < def->fn.args.max_args; i++)
257 def->fn.args.arg_types[i] = gnm_func_get_arg_type (def, i);
258 def->fn.args.arg_types[i] = 0;
261 static GnmValue *
262 error_function_no_full_info (GnmFuncEvalInfo *ei,
263 int argc,
264 GnmExprConstPtr const *argv)
266 return value_new_error (ei->pos, _("Function implementation not available."));
269 static void
270 gnm_func_clear_arg_names (GnmFunc *fd)
272 if (fd->arg_names_p) {
273 g_ptr_array_foreach (fd->arg_names_p, (GFunc) g_free, NULL);
274 g_ptr_array_free (fd->arg_names_p, TRUE);
275 fd->arg_names_p = NULL;
279 static void
280 gnm_func_create_arg_names (GnmFunc *fn_def)
282 int i;
283 GPtrArray *ptr;
285 g_return_if_fail (fn_def != NULL);
287 ptr = g_ptr_array_new ();
288 for (i = 0;
289 fn_def->help && fn_def->help[i].type != GNM_FUNC_HELP_END;
290 i++) {
291 if (fn_def->help[i].type != GNM_FUNC_HELP_ARG)
292 continue;
294 g_ptr_array_add
295 (ptr, split_at_colon
296 (F2(fn_def, fn_def->help[i].text), NULL));
299 gnm_func_clear_arg_names (fn_def);
300 fn_def->arg_names_p = ptr;
304 void
305 gnm_func_load_stub (GnmFunc *func)
307 GnmFuncDescriptor desc;
309 g_return_if_fail (func->fn_type == GNM_FUNC_TYPE_STUB);
311 /* default the content to 0 in case we add new fields
312 * later and the services do not fill them in
314 memset (&desc, 0, sizeof (GnmFuncDescriptor));
316 if (func->fn.load_desc (func, &desc)) {
317 func->help = desc.help ? desc.help : NULL;
318 if (desc.fn_args != NULL) {
319 func->fn_type = GNM_FUNC_TYPE_ARGS;
320 func->fn.args.func = desc.fn_args;
321 func->fn.args.arg_spec = desc.arg_spec;
322 extract_arg_types (func);
323 } else if (desc.fn_nodes != NULL) {
324 func->fn_type = GNM_FUNC_TYPE_NODES;
325 func->fn.nodes = desc.fn_nodes;
326 } else {
327 g_warning ("Invalid function descriptor with no function");
329 func->linker = desc.linker;
330 func->impl_status = desc.impl_status;
331 func->test_status = desc.test_status;
332 func->flags = desc.flags;
333 gnm_func_create_arg_names (func);
334 } else {
335 func->fn_type = GNM_FUNC_TYPE_NODES;
336 func->fn.nodes = &error_function_no_full_info;
337 func->linker = NULL;
341 static void
342 gnm_func_set_localized_name (GnmFunc *fd, const char *lname)
344 gboolean in_hashes = !(fd->flags & GNM_FUNC_IS_WORKBOOK_LOCAL);
346 if (in_hashes && fd->localized_name)
347 g_hash_table_remove (functions_by_localized_name, fd->localized_name);
348 g_free (fd->localized_name);
350 fd->localized_name = g_strdup (lname);
351 if (in_hashes && lname)
352 g_hash_table_insert (functions_by_localized_name,
353 fd->localized_name, fd);
356 void
357 gnm_func_free (GnmFunc *func)
359 GnmFuncGroup *group;
361 g_return_if_fail (func != NULL);
362 g_return_if_fail (func->usage_count == 0);
364 group = func->fn_group;
365 if (group != NULL)
366 gnm_func_group_remove_func (group, func);
368 gnm_func_set_localized_name (func, NULL);
370 if (!(func->flags & GNM_FUNC_IS_WORKBOOK_LOCAL)) {
371 g_hash_table_remove (functions_by_name, func->name);
374 if (func->fn_type == GNM_FUNC_TYPE_ARGS)
375 g_free (func->fn.args.arg_types);
377 g_free ((char *)func->name);
379 go_string_unref (func->tdomain);
381 gnm_func_clear_arg_names (func);
383 g_free (func);
386 GnmFunc *
387 gnm_func_ref (GnmFunc *func)
389 g_return_val_if_fail (func != NULL, NULL);
391 func->usage_count++;
392 if (func->usage_count == 1 && func->usage_notify != NULL)
393 func->usage_notify (func, 1);
394 return func;
397 void
398 gnm_func_unref (GnmFunc *func)
400 g_return_if_fail (func != NULL);
401 g_return_if_fail (func->usage_count > 0);
403 func->usage_count--;
404 if (func->usage_count == 0 && func->usage_notify != NULL)
405 func->usage_notify (func, 0);
408 GType
409 gnm_func_get_type (void)
411 static GType t = 0;
413 if (t == 0) {
414 t = g_boxed_type_register_static ("GnmFunc",
415 (GBoxedCopyFunc)gnm_func_ref,
416 (GBoxedFreeFunc)gnm_func_unref);
418 return t;
421 GnmFunc *
422 gnm_func_lookup (char const *name, Workbook *scope)
424 GnmFunc *fd = g_hash_table_lookup (functions_by_name, name);
425 if (fd != NULL)
426 return fd;
427 if (scope == NULL || scope->sheet_local_functions == NULL)
428 return NULL;
429 return g_hash_table_lookup (scope->sheet_local_functions, (gpointer)name);
432 GnmFunc *
433 gnm_func_lookup_localized (char const *name, Workbook *scope)
435 GnmFunc *fd;
436 GHashTableIter hiter;
437 gpointer value;
439 /* Must localize all function names. */
440 g_hash_table_iter_init (&hiter, functions_by_name);
441 while (g_hash_table_iter_next (&hiter, NULL, &value)) {
442 GnmFunc *fd = value;
443 (void)gnm_func_get_name (fd, TRUE);
446 fd = g_hash_table_lookup (functions_by_localized_name, name);
447 if (fd != NULL)
448 return fd;
449 if (scope == NULL || scope->sheet_local_functions == NULL)
450 return NULL;
451 return g_hash_table_lookup (scope->sheet_local_functions, (gpointer)name);
455 * gnm_func_lookup_prefix:
456 * @prefix: prefix to search for
457 * @scope:
458 * @trans: whether to search translated function names
460 * Returns: (element-type GnmFunc*) (transfer full):
462 GSList *
463 gnm_func_lookup_prefix (char const *prefix, Workbook *scope, gboolean trans)
465 GSList *res = NULL;
466 GHashTableIter hiter;
467 gpointer value;
470 * Always iterate over functions_by_name as the localized name
471 * might not be set yet.
473 g_hash_table_iter_init (&hiter, functions_by_name);
474 while (g_hash_table_iter_next (&hiter, NULL, &value)) {
475 GnmFunc *fd = value;
476 if (!(fd->flags & GNM_FUNC_IS_PLACEHOLDER)) {
477 const char *name = gnm_func_get_name (fd, trans);
478 if (g_str_has_prefix (name, prefix)) {
479 gnm_func_ref (fd);
480 res = g_slist_prepend (res, fd);
485 return res;
488 GnmFunc *
489 gnm_func_add (GnmFuncGroup *fn_group,
490 GnmFuncDescriptor const *desc,
491 const char *tdomain)
493 static char const valid_tokens[] = "fsbraAES?|";
494 GnmFunc *func;
495 char const *ptr;
497 g_return_val_if_fail (fn_group != NULL, NULL);
498 g_return_val_if_fail (desc != NULL, NULL);
500 func = g_new (GnmFunc, 1);
502 if (!tdomain)
503 tdomain = GETTEXT_PACKAGE;
505 func->name = g_strdup (desc->name);
506 func->help = desc->help ? desc->help : NULL;
507 func->tdomain = go_string_new (tdomain);
508 func->linker = desc->linker;
509 func->usage_notify = desc->usage_notify;
510 func->flags = desc->flags;
511 func->impl_status = desc->impl_status;
512 func->test_status = desc->test_status;
513 func->localized_name = NULL;
514 func->arg_names_p = NULL;
516 func->user_data = NULL;
517 func->usage_count = 0;
519 if (desc->fn_args != NULL) {
520 /* Check those arguments */
521 for (ptr = desc->arg_spec ; *ptr ; ptr++) {
522 g_return_val_if_fail (strchr (valid_tokens, *ptr), NULL);
525 func->fn_type = GNM_FUNC_TYPE_ARGS;
526 func->fn.args.func = desc->fn_args;
527 func->fn.args.arg_spec = desc->arg_spec;
528 extract_arg_types (func);
529 } else if (desc->fn_nodes != NULL) {
531 if (desc->arg_spec && *desc->arg_spec) {
532 g_warning ("Arg spec for node function -- why?");
535 func->fn_type = GNM_FUNC_TYPE_NODES;
536 func->fn.nodes = desc->fn_nodes;
537 } else {
538 g_warning ("Invalid function has neither args nor nodes handler");
539 g_free (func);
540 return NULL;
543 func->fn_group = fn_group;
544 if (fn_group != NULL)
545 gnm_func_group_add_func (fn_group, func);
546 if (!(func->flags & GNM_FUNC_IS_WORKBOOK_LOCAL))
547 g_hash_table_insert (functions_by_name,
548 (gpointer)(func->name), func);
550 gnm_func_create_arg_names (func);
552 return func;
555 /* Handle unknown functions on import without losing their names */
556 static GnmValue *
557 unknownFunctionHandler (GnmFuncEvalInfo *ei,
558 G_GNUC_UNUSED int argc,
559 G_GNUC_UNUSED GnmExprConstPtr const *argv)
561 return value_new_error_NAME (ei->pos);
565 * gnm_func_upgrade_placeholder:
566 * @fd:
567 * @fn_group:
568 * @tdomain:
569 * @load_desc: (scope async):
570 * @opt_usage_notify: (scope async):
572 void
573 gnm_func_upgrade_placeholder (GnmFunc *fd,
574 GnmFuncGroup *fn_group,
575 const char *tdomain,
576 GnmFuncLoadDesc load_desc,
577 GnmFuncUsageNotify opt_usage_notify)
579 g_return_if_fail (fd != NULL);
580 g_return_if_fail (fd->flags & GNM_FUNC_IS_PLACEHOLDER);
581 g_return_if_fail (fn_group != NULL);
583 if (!tdomain)
584 tdomain = GETTEXT_PACKAGE;
586 /* Remove from unknown_cat */
587 gnm_func_group_remove_func (fd->fn_group, fd);
589 fd->fn_type = GNM_FUNC_TYPE_STUB;
590 fd->fn.load_desc = load_desc;
591 fd->usage_notify = opt_usage_notify;
593 go_string_unref (fd->tdomain);
594 fd->tdomain = go_string_new (tdomain);
596 /* Clear localized_name so we can deduce the proper name. */
597 gnm_func_set_localized_name (fd, NULL);
599 fd->flags &= ~GNM_FUNC_IS_PLACEHOLDER;
601 fd->fn_group = fn_group;
602 gnm_func_group_add_func (fn_group, fd);
605 static char *
606 invent_name (const char *pref, GHashTable *h, const char *template)
608 static int count = 0;
609 char *name = g_utf8_strdown (pref, -1);
611 while (g_hash_table_lookup (h, name)) {
612 count++;
613 g_free (name);
614 name = g_strdup_printf (template, count);
617 return name;
620 static GnmFunc *
621 gnm_func_add_placeholder_full (Workbook *scope,
622 char const *gname, char const *lname,
623 char const *type)
625 GnmFuncDescriptor desc;
626 GnmFunc *func;
627 char const *unknown_cat_name = N_("Unknown Function");
628 gboolean copy_gname = TRUE;
629 gboolean copy_lname = TRUE;
631 g_return_val_if_fail (gname || lname, NULL);
632 g_return_val_if_fail (gname == NULL || gnm_func_lookup (gname, scope) == NULL, NULL);
633 g_return_val_if_fail (lname == NULL || gnm_func_lookup_localized (lname, scope) == NULL, NULL);
635 if (!unknown_cat)
636 unknown_cat = gnm_func_group_fetch
637 (unknown_cat_name, _(unknown_cat_name));
639 if (!gname) {
641 * This is actually a bit of a problem if we don't end up
642 * with a copy of lname (because there already is a function
643 * with that name). We're likely to save a template name,
644 * but I don't see what else to do.
646 gname = invent_name (lname, functions_by_name, "unknown%d");
647 copy_gname = FALSE;
649 if (!lname) {
650 /* xgettext: This represents a made-up translated function name. */
651 lname = invent_name (gname, functions_by_localized_name, _("unknown%d"));
652 copy_lname = FALSE;
655 if (gnm_debug_flag ("func"))
656 g_printerr ("Adding placeholder for %s (aka %s)\n", gname, lname);
658 memset (&desc, 0, sizeof (GnmFuncDescriptor));
659 desc.name = gname;
660 desc.arg_spec = NULL;
661 desc.help = NULL;
662 desc.fn_args = NULL;
663 desc.fn_nodes = &unknownFunctionHandler;
664 desc.linker = NULL;
665 desc.usage_notify = NULL;
666 desc.flags = GNM_FUNC_IS_PLACEHOLDER;
667 desc.impl_status = GNM_FUNC_IMPL_STATUS_EXISTS;
668 desc.test_status = GNM_FUNC_TEST_STATUS_UNKNOWN;
670 if (scope != NULL)
671 desc.flags |= GNM_FUNC_IS_WORKBOOK_LOCAL;
672 else {
673 #if 0
674 /* WISHLIST : it would be nice to have a log if these. */
675 g_warning ("Unknown %s function : %s", type, desc.name);
676 #endif
679 func = gnm_func_add (unknown_cat, &desc, NULL);
681 if (lname) {
682 gnm_func_set_localized_name (func, lname);
683 if (!copy_lname)
684 g_free ((char *)lname);
687 if (!copy_gname)
688 g_free ((char *)gname);
690 if (scope != NULL) {
691 if (scope->sheet_local_functions == NULL)
692 scope->sheet_local_functions = g_hash_table_new_full (
693 g_str_hash, g_str_equal,
694 NULL, (GDestroyNotify) gnm_func_free);
695 g_hash_table_insert (scope->sheet_local_functions,
696 (gpointer)func->name, func);
699 return func;
703 * When importing it is useful to keep track of unknown function names.
704 * We may be missing a plugin or something similar.
706 * TODO : Eventully we should be able to keep track of these
707 * and replace them with something else. Possibly even reordering the
708 * arguments.
710 GnmFunc *
711 gnm_func_add_placeholder (Workbook *scope,
712 char const *name, char const *type)
714 return gnm_func_add_placeholder_full (scope, name, NULL, type);
717 GnmFunc *
718 gnm_func_add_placeholder_localized (char const *gname, char const *lname)
720 return gnm_func_add_placeholder_full (NULL, gname, lname, "?");
723 /* Utility routine to be used for import and analysis tools */
724 GnmFunc *
725 gnm_func_lookup_or_add_placeholder (char const *name)
727 GnmFunc * f = gnm_func_lookup (name, NULL);
728 if (f == NULL)
729 f = gnm_func_add_placeholder (NULL, name, "");
730 return f;
734 * gnm_func_get_user_data:
735 * @func:
737 * Returns: (transfer none):
739 gpointer
740 gnm_func_get_user_data (GnmFunc const *func)
742 g_return_val_if_fail (func != NULL, NULL);
744 return func->user_data;
747 void
748 gnm_func_set_user_data (GnmFunc *func, gpointer user_data)
750 g_return_if_fail (func != NULL);
752 func->user_data = user_data;
756 * gnm_func_get_name:
757 * @func: #GnmFunc to query
758 * @localized: if %TRUE, use localized name
760 * Returns: (transfer none): @func's name
762 char const *
763 gnm_func_get_name (GnmFunc const *func, gboolean localized)
765 int i;
766 GnmFunc *fd = (GnmFunc *)func;
768 g_return_val_if_fail (func != NULL, NULL);
770 if (!localized)
771 return func->name;
773 if (func->localized_name)
774 return func->localized_name;
777 * Deduce the translated names from the help texts. This
778 * code doesn't currently check for clashes in translated
779 * names.
782 gnm_func_load_if_stub (fd);
784 for (i = 0;
785 (func->localized_name == NULL &&
786 func->help &&
787 func->help[i].type != GNM_FUNC_HELP_END);
788 i++) {
789 const char *s, *sl;
790 char *U;
791 if (func->help[i].type != GNM_FUNC_HELP_NAME)
792 continue;
794 s = func->help[i].text;
795 sl = F2 (func, s);
796 if (s == sl) /* String not actually translated. */
797 continue;
799 U = split_at_colon (F2 (func, s), NULL);
800 if (U) {
801 char *lname = g_utf8_strdown (U, -1);
802 gnm_func_set_localized_name (fd, lname);
803 g_free (lname);
805 g_free (U);
808 if (!func->localized_name)
809 gnm_func_set_localized_name (fd, fd->name);
811 return func->localized_name;
815 * gnm_func_get_description:
816 * @fn_def: the fn defintion
818 * Returns: (transfer none): the description of the function
820 char const*
821 gnm_func_get_description (GnmFunc const *fn_def)
823 gint i;
824 g_return_val_if_fail (fn_def != NULL, NULL);
826 gnm_func_load_if_stub ((GnmFunc *)fn_def);
828 for (i = 0;
829 fn_def->help && fn_def->help[i].type != GNM_FUNC_HELP_END;
830 i++) {
831 const char *desc;
833 if (fn_def->help[i].type != GNM_FUNC_HELP_NAME)
834 continue;
836 desc = strchr (F2 (fn_def, fn_def->help[i].text), ':');
837 return desc ? (desc + 1) : "";
839 return "";
843 * gnm_func_count_args:
844 * @fn_def: pointer to function definition
845 * @min: (out): location for mininum args
846 * @max: (out): location for mininum args
848 * This calculates the maximum and minimum number of args tha can be passed.
849 * For a vararg function, the maximum will be set to G_MAXINT.
851 void
852 gnm_func_count_args (GnmFunc const *fn_def, int *min, int *max)
854 char const *ptr;
855 int i;
856 int vararg;
858 g_return_if_fail (min != NULL);
859 g_return_if_fail (max != NULL);
860 g_return_if_fail (fn_def != NULL);
862 gnm_func_load_if_stub ((GnmFunc *)fn_def);
865 * FIXME: clearly for 'nodes' functions many of
866 * the type fields will need to be filled.
868 if (fn_def->fn_type == GNM_FUNC_TYPE_NODES) {
869 *min = 0;
870 if (g_ascii_strcasecmp ("INDEX",fn_def->name) == 0)
871 *max = 4;
872 else
873 *max = G_MAXINT;
874 return;
877 ptr = fn_def->fn.args.arg_spec;
878 for (i = vararg = 0; ptr && *ptr; ptr++) {
879 if (*ptr == '|') {
880 vararg = 1;
881 *min = i;
882 } else
883 i++;
885 *max = i;
886 if (!vararg)
887 *min = i;
891 * gnm_func_get_arg_type:
892 * @fn_def: the fn defintion
893 * @arg_idx: zero based argument offset
895 * Returns: the type of the argument
897 char
898 gnm_func_get_arg_type (GnmFunc const *fn_def, int arg_idx)
900 char const *ptr;
902 g_return_val_if_fail (arg_idx >= 0, '?');
903 g_return_val_if_fail (fn_def != NULL, '?');
905 gnm_func_load_if_stub ((GnmFunc *)fn_def);
907 switch (fn_def->fn_type) {
908 case GNM_FUNC_TYPE_ARGS:
909 for (ptr = fn_def->fn.args.arg_spec; ptr && *ptr; ptr++) {
910 if (*ptr == '|')
911 continue;
912 if (arg_idx-- == 0)
913 return *ptr;
915 return '?';
917 case GNM_FUNC_TYPE_NODES:
918 return '?'; /* Close enough for now. */
920 case GNM_FUNC_TYPE_STUB:
921 #ifndef DEBUG_SWITCH_ENUM
922 default:
923 #endif
924 g_assert_not_reached ();
925 return '?';
930 * gnm_func_get_arg_type_string:
931 * @fn_def: the fn defintion
932 * @arg_idx: zero based argument offset
934 * Return value: (transfer none): the type of the argument as a string
936 char const *
937 gnm_func_get_arg_type_string (GnmFunc const *fn_def,
938 int arg_idx)
940 switch (gnm_func_get_arg_type (fn_def, arg_idx)) {
941 case 'f':
942 return _("Number");
943 case 's':
944 return _("String");
945 case 'b':
946 return _("Boolean");
947 case 'r':
948 return _("Cell Range");
949 case 'A':
950 return _("Area");
951 case 'E':
952 return _("Scalar, Blank, or Error");
953 case 'S':
954 return _("Scalar");
955 case '?':
956 /* Missing values will be NULL. */
957 return _("Any");
959 default:
960 g_warning ("Unknown arg type");
961 return "Broken";
966 * gnm_func_get_arg_name:
967 * @fn_def: the fn defintion
968 * @arg_idx: zero based argument offset
970 * Returns: (transfer full): the name of the argument
972 char *
973 gnm_func_get_arg_name (GnmFunc const *fn_def, guint arg_idx)
975 g_return_val_if_fail (fn_def != NULL, NULL);
977 gnm_func_load_if_stub ((GnmFunc *)fn_def);
979 if ((fn_def->arg_names_p != NULL)
980 && (arg_idx < fn_def->arg_names_p->len))
981 return g_strdup (g_ptr_array_index (fn_def->arg_names_p,
982 arg_idx));
983 return NULL;
987 * gnm_func_get_arg_description:
988 * @fn_def: the fn defintion
989 * @arg_idx: zero based argument offset
991 * Returns: (transfer none): the description of the argument
993 char const*
994 gnm_func_get_arg_description (GnmFunc const *fn_def, guint arg_idx)
996 gint i;
997 g_return_val_if_fail (fn_def != NULL, NULL);
999 gnm_func_load_if_stub ((GnmFunc *)fn_def);
1001 for (i = 0;
1002 fn_def->help && fn_def->help[i].type != GNM_FUNC_HELP_END;
1003 i++) {
1004 gchar const *desc;
1006 if (fn_def->help[i].type != GNM_FUNC_HELP_ARG)
1007 continue;
1008 if (arg_idx--)
1009 continue;
1011 desc = strchr (F2 (fn_def, fn_def->help[i].text), ':');
1012 if (!desc)
1013 return "";
1015 desc++;
1016 while (g_unichar_isspace (g_utf8_get_char (desc)))
1017 desc = g_utf8_next_char (desc);
1018 return desc;
1021 return "";
1025 * gnm_func_convert_markup_to_pango:
1026 * @desc: the fn or arg description string
1027 * @target: target widget for the markup.
1029 * Return value: the escaped string with @{} markup converted to
1030 * pango markup
1032 char *
1033 gnm_func_convert_markup_to_pango (char const *desc, GtkWidget *target)
1035 GString *str;
1036 gchar *markup, *at;
1037 GdkRGBA link_color;
1038 PangoColor pg;
1039 char *link_color_text, *span_text;
1040 size_t span_text_len;
1042 gnm_get_link_color (target, &link_color);
1043 pg.red = 65535 * link_color.red;
1044 pg.green = 65535 * link_color.green;
1045 pg.blue = 65535 * link_color.blue;
1046 link_color_text = pango_color_to_string (&pg);
1047 span_text = g_strdup_printf ("<span foreground=\"%s\">",
1048 link_color_text);
1049 span_text_len = strlen (span_text);
1050 g_free (link_color_text);
1052 markup = g_markup_escape_text (desc, -1);
1053 str = g_string_new (markup);
1054 g_free (markup);
1056 while ((at = strstr (str->str, "@{"))) {
1057 gint len = at - str->str;
1058 go_string_replace (str, len, 2, span_text, -1);
1059 if ((at = strstr
1060 (str->str + len + span_text_len, "}"))) {
1061 len = at - str->str;
1062 go_string_replace (str, len, 1, "</span>", -1);
1063 } else
1064 g_string_append (str, "</span>");
1066 g_free (span_text);
1068 return g_string_free (str, FALSE);
1072 /* ------------------------------------------------------------------------- */
1074 static inline void
1075 free_values (GnmValue **values, int top)
1077 int i;
1079 for (i = 0; i < top; i++)
1080 if (values [i])
1081 value_release (values [i]);
1084 /* ------------------------------------------------------------------------- */
1087 * function_call_with_exprs:
1088 * @ei: EvalInfo containing valid fn_def!
1090 * Do the guts of calling a function.
1092 * Returns the result.
1094 GnmValue *
1095 function_call_with_exprs (GnmFuncEvalInfo *ei)
1097 GnmFunc const *fn_def;
1098 int i, iter_count, iter_width = 0, iter_height = 0;
1099 char arg_type;
1100 GnmValue **args, *tmp = NULL;
1101 int *iter_item = NULL;
1102 int argc;
1103 GnmExprConstPtr *argv;
1104 GnmExprEvalFlags flags, pass_flags;
1106 g_return_val_if_fail (ei != NULL, NULL);
1107 g_return_val_if_fail (ei->func_call != NULL, NULL);
1109 flags = ei->flags;
1111 argc = ei->func_call->argc;
1112 argv = ei->func_call->argv;
1113 fn_def = ei->func_call->func;
1115 gnm_func_load_if_stub ((GnmFunc *)fn_def);
1117 /* Functions that deal with ExprNodes */
1118 if (fn_def->fn_type == GNM_FUNC_TYPE_NODES)
1119 return fn_def->fn.nodes (ei, argc, argv);
1121 /* Functions that take pre-computed Values */
1122 if (argc > fn_def->fn.args.max_args ||
1123 argc < fn_def->fn.args.min_args)
1124 return value_new_error_NA (ei->pos);
1126 args = g_alloca (sizeof (GnmValue *) * fn_def->fn.args.max_args);
1127 iter_count = (eval_pos_is_array_context (ei->pos) &&
1128 (flags & GNM_EXPR_EVAL_PERMIT_NON_SCALAR))
1129 ? 0 : -1;
1131 /* Optimization for IF when implicit iteration is not used. */
1132 if (ei->func_call->func->fn.args.func == gnumeric_if &&
1133 iter_count == -1)
1134 return gnumeric_if2 (ei, argc, argv, flags);
1136 pass_flags = (flags &
1137 (GNM_EXPR_EVAL_ARRAY_CONTEXT));
1139 for (i = 0; i < argc; i++) {
1140 char arg_type = fn_def->fn.args.arg_types[i];
1141 /* expr is always non-null, missing args are encoded as
1142 * const = empty */
1143 GnmExpr const *expr = argv[i];
1145 if (arg_type == 'A' || arg_type == 'r') {
1146 tmp = args[i] = gnm_expr_eval
1147 (expr, ei->pos,
1148 pass_flags |
1149 GNM_EXPR_EVAL_PERMIT_NON_SCALAR |
1150 GNM_EXPR_EVAL_WANT_REF);
1151 if (VALUE_IS_ERROR (tmp)) {
1152 free_values (args, i);
1153 return tmp;
1156 if (VALUE_IS_CELLRANGE (tmp)) {
1157 gnm_cellref_make_abs (&tmp->v_range.cell.a,
1158 &tmp->v_range.cell.a,
1159 ei->pos);
1160 gnm_cellref_make_abs (&tmp->v_range.cell.b,
1161 &tmp->v_range.cell.b,
1162 ei->pos);
1163 /* Array args accept scalars */
1164 } else if (arg_type != 'A' && !VALUE_IS_ARRAY (tmp)) {
1165 free_values (args, i + 1);
1166 return value_new_error_VALUE (ei->pos);
1168 continue;
1171 /* force scalars whenever we are certain */
1172 tmp = args[i] = gnm_expr_eval
1173 (expr, ei->pos,
1174 pass_flags |
1175 GNM_EXPR_EVAL_PERMIT_EMPTY |
1176 (iter_count >= 0 || arg_type == '?'
1177 ? GNM_EXPR_EVAL_PERMIT_NON_SCALAR
1178 : 0));
1180 if (arg_type == '?') /* '?' arguments are unrestriced */
1181 continue;
1183 /* optional arguments can be blank */
1184 if (i >= fn_def->fn.args.min_args && VALUE_IS_EMPTY (tmp)) {
1185 if (arg_type == 'E' && !gnm_expr_is_empty (expr)) {
1186 /* An actual argument produced empty. Make
1187 sure function sees that. */
1188 args[i] = value_new_empty ();
1191 continue;
1194 if (tmp == NULL)
1195 tmp = args[i] = value_new_empty ();
1197 /* Handle implicit intersection or iteration depending on flags */
1198 if (VALUE_IS_CELLRANGE (tmp) || VALUE_IS_ARRAY (tmp)) {
1199 if (iter_count > 0) {
1200 if (iter_width != value_area_get_width (tmp, ei->pos) ||
1201 iter_height != value_area_get_height (tmp, ei->pos)) {
1202 free_values (args, i + 1);
1203 return value_new_error_VALUE (ei->pos);
1205 } else {
1206 if (iter_count < 0) {
1207 g_warning ("Damn I thought this was impossible");
1208 iter_count = 0;
1210 iter_item = g_alloca (sizeof (int) * argc);
1211 iter_width = value_area_get_width (tmp, ei->pos);
1212 iter_height = value_area_get_height (tmp, ei->pos);
1214 iter_item [iter_count++] = i;
1216 /* no need to check type, we would fail comparing a range against a "b, f, or s" */
1217 continue;
1220 /* All of these argument types must be scalars */
1221 switch (arg_type) {
1222 case 'b':
1223 if (VALUE_IS_STRING (tmp)) {
1224 gboolean err;
1225 gboolean b = value_get_as_bool (tmp, &err);
1226 if (err) {
1227 free_values (args, i + 1);
1228 return value_new_error_VALUE (ei->pos);
1230 value_release (args[i]);
1231 tmp = args[i] = value_new_bool (b);
1232 break;
1234 /* Fall through. */
1235 case 'f':
1236 if (VALUE_IS_STRING (tmp)) {
1237 tmp = format_match_number (value_peek_string (tmp), NULL,
1238 sheet_date_conv (ei->pos->sheet));
1239 if (tmp == NULL) {
1240 free_values (args, i + 1);
1241 return value_new_error_VALUE (ei->pos);
1243 value_release (args [i]);
1244 args[i] = tmp;
1245 } else if (VALUE_IS_ERROR (tmp)) {
1246 free_values (args, i);
1247 return tmp;
1248 } else if (VALUE_IS_EMPTY (tmp)) {
1249 value_release (args [i]);
1250 tmp = args[i] = value_new_int (0);
1253 if (!VALUE_IS_NUMBER (tmp))
1254 return value_new_error_VALUE (ei->pos);
1255 break;
1257 case 's':
1258 case 'S':
1259 if (VALUE_IS_ERROR (tmp)) {
1260 free_values (args, i);
1261 return tmp;
1263 break;
1265 case 'E': /* nothing necessary */
1266 break;
1268 /* case '?': handled above */
1269 default:
1270 g_warning ("Unknown argument type '%c'", arg_type);
1271 break;
1275 while (i < fn_def->fn.args.max_args)
1276 args [i++] = NULL;
1278 if (iter_item != NULL) {
1279 int x, y;
1280 GnmValue *res = value_new_array_empty (iter_width, iter_height);
1281 GnmValue const *elem, *err;
1282 GnmValue **iter_vals = g_alloca (sizeof (GnmValue *) * iter_count);
1283 GnmValue **iter_args = g_alloca (sizeof (GnmValue *) * iter_count);
1285 /* collect the args we will iterate on */
1286 for (i = 0 ; i < iter_count; i++)
1287 iter_vals[i] = args[iter_item[i]];
1289 for (x = iter_width; x-- > 0 ; )
1290 for (y = iter_height; y-- > 0 ; ) {
1291 /* marshal the args */
1292 err = NULL;
1293 for (i = 0 ; i < iter_count; i++) {
1294 elem = value_area_get_x_y (iter_vals[i], x, y, ei->pos);
1295 arg_type = fn_def->fn.args.arg_types[iter_item[i]];
1296 if (arg_type == 'b' || arg_type == 'f') {
1297 if (VALUE_IS_EMPTY (elem))
1298 elem = value_zero;
1299 else if (VALUE_IS_STRING (elem)) {
1300 tmp = format_match_number (value_peek_string (elem), NULL,
1301 sheet_date_conv (ei->pos->sheet));
1302 if (tmp != NULL) {
1303 args [iter_item[i]] = iter_args [i] = tmp;
1304 continue;
1305 } else
1306 break;
1307 } else if (VALUE_IS_ERROR (elem)) {
1308 err = elem;
1309 break;
1310 } else if (!VALUE_IS_NUMBER (elem))
1311 break;
1312 } else if (arg_type == 's') {
1313 if (VALUE_IS_EMPTY (elem)) {
1314 args [iter_item[i]] = iter_args [i] = value_new_string ("");
1315 continue;
1316 } else if (VALUE_IS_ERROR (elem)) {
1317 err = elem;
1318 break;
1319 } else if (!VALUE_IS_STRING (elem))
1320 break;
1321 } else if (elem == NULL) {
1322 args [iter_item[i]] = iter_args [i] = value_new_empty ();
1323 continue;
1325 args [iter_item[i]] = iter_args [i] = value_dup (elem);
1328 res->v_array.vals[x][y] = (i == iter_count)
1329 ? fn_def->fn.args.func (ei, (GnmValue const * const *)args)
1330 : ((err != NULL) ? value_dup (err)
1331 : value_new_error_VALUE (ei->pos));
1332 free_values (iter_args, i);
1335 /* free the primaries, not the already freed iteration */
1336 for (i = 0 ; i < iter_count; i++)
1337 args[iter_item[i]] = iter_vals[i];
1338 tmp = res;
1339 i = fn_def->fn.args.max_args;
1340 } else
1341 tmp = fn_def->fn.args.func (ei, (GnmValue const * const *)args);
1343 free_values (args, i);
1344 return tmp;
1348 * Use this to invoke a register function: the only drawback is that
1349 * you have to compute/expand all of the values to use this
1351 GnmValue *
1352 function_call_with_values (GnmEvalPos const *ep, char const *fn_name,
1353 int argc, GnmValue const * const *values)
1355 GnmFunc *fn_def;
1357 g_return_val_if_fail (ep != NULL, NULL);
1358 g_return_val_if_fail (fn_name != NULL, NULL);
1359 g_return_val_if_fail (ep->sheet != NULL, NULL);
1361 /* FIXME : support workbook local functions */
1362 fn_def = gnm_func_lookup (fn_name, NULL);
1363 if (fn_def == NULL)
1364 return value_new_error_NAME (ep);
1365 return function_def_call_with_values (ep, fn_def, argc, values);
1368 GnmValue *
1369 function_def_call_with_values (GnmEvalPos const *ep, GnmFunc const *fn_def,
1370 int argc, GnmValue const * const *values)
1372 GnmValue *retval;
1373 GnmExprFunction ef;
1374 GnmFuncEvalInfo fs;
1376 fs.pos = ep;
1377 fs.func_call = &ef;
1378 ef.func = (GnmFunc *)fn_def;
1380 gnm_func_load_if_stub ((GnmFunc *)fn_def);
1382 if (fn_def->fn_type == GNM_FUNC_TYPE_NODES) {
1384 * If function deals with ExprNodes, create some
1385 * temporary ExprNodes with constants.
1387 GnmExprConstant *expr = g_new (GnmExprConstant, argc);
1388 GnmExprConstPtr *argv = g_new (GnmExprConstPtr, argc);
1389 int i;
1391 for (i = 0; i < argc; i++) {
1392 gnm_expr_constant_init (expr + i, values[i]);
1393 argv[i] = (GnmExprConstPtr)(expr + i);
1395 retval = fn_def->fn.nodes (&fs, argc, argv);
1396 g_free (argv);
1397 g_free (expr);
1398 } else
1399 retval = fn_def->fn.args.func (&fs, values);
1401 return retval;
1404 /* ------------------------------------------------------------------------- */
1406 typedef struct {
1407 FunctionIterateCB callback;
1408 void *closure;
1409 gboolean strict;
1410 gboolean ignore_subtotal;
1411 } IterateCallbackClosure;
1414 * cb_iterate_cellrange:
1416 * Helper routine used by the function_iterate_do_value routine.
1417 * Invoked by the sheet cell range iterator.
1419 static GnmValue *
1420 cb_iterate_cellrange (GnmCellIter const *iter, gpointer user)
1423 IterateCallbackClosure *data = user;
1424 GnmCell *cell;
1425 GnmValue *res;
1426 GnmEvalPos ep;
1428 if (NULL == (cell = iter->cell)) {
1429 ep.sheet = iter->pp.sheet;
1430 ep.dep = NULL;
1431 ep.eval.col = iter->pp.eval.col;
1432 ep.eval.row = iter->pp.eval.row;
1433 return (*data->callback)(&ep, NULL, data->closure);
1436 if (data->ignore_subtotal && gnm_cell_has_expr (cell) &&
1437 gnm_expr_top_contains_subtotal (cell->base.texpr))
1438 return NULL;
1440 gnm_cell_eval (cell);
1441 eval_pos_init_cell (&ep, cell);
1443 /* If we encounter an error for the strict case, short-circuit here. */
1444 if (data->strict && (NULL != (res = gnm_cell_is_error (cell))))
1445 return value_new_error_str (&ep, res->v_err.mesg);
1447 /* All other cases -- including error -- just call the handler. */
1448 return (*data->callback)(&ep, cell->value, data->closure);
1452 * function_iterate_do_value:
1454 * Helper routine for function_iterate_argument_values.
1456 static GnmValue *
1457 function_iterate_do_value (GnmEvalPos const *ep,
1458 FunctionIterateCB callback,
1459 gpointer closure,
1460 GnmValue const *value,
1461 gboolean strict,
1462 CellIterFlags iter_flags)
1464 GnmValue *res = NULL;
1466 switch (value->v_any.type){
1467 case VALUE_ERROR:
1468 if (strict) {
1469 res = value_dup (value);
1470 break;
1472 /* Fall through. */
1474 case VALUE_EMPTY:
1475 case VALUE_BOOLEAN:
1476 case VALUE_FLOAT:
1477 case VALUE_STRING:
1478 res = (*callback)(ep, value, closure);
1479 break;
1481 case VALUE_ARRAY: {
1482 int x, y;
1484 /* Note the order here. */
1485 for (y = 0; y < value->v_array.y; y++) {
1486 for (x = 0; x < value->v_array.x; x++) {
1487 res = function_iterate_do_value (
1488 ep, callback, closure,
1489 value->v_array.vals [x][y],
1490 strict, CELL_ITER_IGNORE_BLANK);
1491 if (res != NULL)
1492 return res;
1495 break;
1497 case VALUE_CELLRANGE: {
1498 IterateCallbackClosure data;
1500 data.callback = callback;
1501 data.closure = closure;
1502 data.strict = strict;
1503 data.ignore_subtotal = (iter_flags & CELL_ITER_IGNORE_SUBTOTAL) != 0;
1505 res = workbook_foreach_cell_in_range (ep, value, iter_flags,
1506 cb_iterate_cellrange,
1507 &data);
1510 return res;
1514 * function_iterate_argument_values:
1515 * @ep: The position in a workbook at which to evaluate
1516 * @callback: (scope call): The routine to be invoked for every value computed
1517 * @callback_closure: Closure for the callback.
1518 * @argc:
1519 * @argv:
1520 * @strict: If TRUE, the function is considered "strict". This means
1521 * that if an error value occurs as an argument, the iteration
1522 * will stop and that error will be returned. If FALSE, an
1523 * error will be passed on to the callback (as a GnmValue *
1524 * of type VALUE_ERROR).
1525 * @iter_flags:
1527 * Return value:
1528 * NULL : if no errors were reported.
1529 * GnmValue * : if an error was found during strict evaluation
1530 * VALUE_TERMINATE : if the callback requested termination of the iteration.
1532 * This routine provides a simple way for internal functions with variable
1533 * number of arguments to be written: this would iterate over a list of
1534 * expressions (expr_node_list) and will invoke the callback for every
1535 * GnmValue found on the list (this means that ranges get properly expaned).
1537 GnmValue *
1538 function_iterate_argument_values (GnmEvalPos const *ep,
1539 FunctionIterateCB callback,
1540 void *callback_closure,
1541 int argc,
1542 GnmExprConstPtr const *argv,
1543 gboolean strict,
1544 CellIterFlags iter_flags)
1546 GnmValue *result = NULL;
1547 int a;
1549 for (a = 0; result == NULL && a < argc; a++) {
1550 GnmExpr const *expr = argv[a];
1551 GnmValue *val;
1553 if (iter_flags & CELL_ITER_IGNORE_SUBTOTAL &&
1554 gnm_expr_contains_subtotal (expr))
1555 continue;
1557 /* need to drill down into names to handle things like
1558 * sum(name) with name := (A:A,B:B) */
1559 while (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_NAME) {
1560 GnmExprTop const *texpr = expr->name.name->texpr;
1561 expr = texpr ? texpr->expr : NULL;
1562 if (expr == NULL) {
1563 if (strict)
1564 return value_new_error_REF (ep);
1565 break;
1568 if (!expr)
1569 continue;
1571 /* Handle sets as a special case */
1572 if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_SET) {
1573 result = function_iterate_argument_values
1574 (ep, callback, callback_closure,
1575 expr->set.argc, expr->set.argv,
1576 strict, iter_flags);
1577 continue;
1580 /* We need a cleaner model of what to do here.
1581 * In non-array mode
1582 * SUM(Range)
1583 * will obviously return Range
1585 * SUM(INDIRECT(Range))
1586 * SUM(INDIRECT(Range):....)
1587 * will do implicit intersection on Range (in non-array mode),
1588 * but allow non-scalar results from indirect (no intersection)
1590 * SUM(Range=3)
1591 * will do implicit intersection in non-array mode */
1592 if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_CONSTANT)
1593 val = value_dup (expr->constant.value);
1594 else if (eval_pos_is_array_context (ep) ||
1595 GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL ||
1596 GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_RANGE_CTOR ||
1597 GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_INTERSECT)
1598 val = gnm_expr_eval (expr, ep,
1599 GNM_EXPR_EVAL_PERMIT_EMPTY | GNM_EXPR_EVAL_PERMIT_NON_SCALAR);
1600 else
1601 val = gnm_expr_eval (expr, ep, GNM_EXPR_EVAL_PERMIT_EMPTY);
1603 if (val == NULL)
1604 continue;
1606 if (strict && VALUE_IS_ERROR (val)) {
1607 /* Be careful not to make VALUE_TERMINATE into a real value */
1608 return val;
1611 result = function_iterate_do_value (ep, callback, callback_closure,
1612 val, strict, iter_flags);
1613 value_release (val);
1615 return result;
1619 GnmFunc const *
1620 gnm_eval_info_get_func (GnmFuncEvalInfo const *ei)
1622 return ei->func_call->func;
1626 gnm_eval_info_get_arg_count (GnmFuncEvalInfo const *ei)
1628 return ei->func_call->argc;