Update Spanish translation
[gnumeric.git] / src / func.c
blob452cd65fab278650c7c42cb86aac54172145b948
1 /*
2 * func.c: Function management and utility routines.
4 * Author:
5 * Miguel de Icaza (miguel@gnu.org)
6 * Michael Meeks (mmeeks@gnu.org)
7 * Morten Welinder (terra@gnome.org)
8 * Jody Goldberg (jody@gnome.org)
9 */
11 #include <gnumeric-config.h>
12 #include <glib/gi18n-lib.h>
13 #include <glib/gstdio.h>
14 #include <gnm-i18n.h>
15 #include <gnumeric.h>
16 #include <func.h>
18 #include <parse-util.h>
19 #include <dependent.h>
20 #include <expr.h>
21 #include <expr-impl.h>
22 #include <expr-name.h>
23 #include <cell.h>
24 #include <workbook-priv.h>
25 #include <sheet.h>
26 #include <value.h>
27 #include <number-match.h>
28 #include <func-builtin.h>
29 #include <command-context-stderr.h>
30 #include <gnm-plugin.h>
31 #include <gutils.h>
32 #include <gui-util.h>
33 #include <expr-deriv.h>
34 #include <gnm-marshalers.h>
36 #include <goffice/goffice.h>
37 #include <glib.h>
38 #include <string.h>
39 #include <stdlib.h>
41 enum {
42 PROP_0,
43 PROP_NAME,
44 PROP_TRANSLATION_DOMAIN,
45 PROP_IN_USE,
48 enum {
49 SIG_LOAD_STUB,
50 SIG_LINK_DEP,
51 SIG_DERIVATIVE,
52 LAST_SIGNAL
54 static guint signals[LAST_SIGNAL] = { 0 };
57 static GList *categories;
58 static GnmFuncGroup *unknown_cat;
60 static GHashTable *functions_by_name;
61 static GHashTable *functions_by_localized_name;
63 static GnmFunc *fn_if;
65 /**
66 * gnm_func_init_: (skip)
68 void
69 gnm_func_init_ (void)
71 functions_by_name =
72 g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal);
74 /* FIXME: ascii??? */
75 functions_by_localized_name =
76 g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal);
78 gnm_func_builtin_init ();
80 fn_if = gnm_func_lookup ("if", NULL);
83 /**
84 * gnm_func_shutdown_: (skip)
86 void
87 gnm_func_shutdown_ (void)
89 fn_if = NULL;
91 while (unknown_cat != NULL && unknown_cat->functions != NULL) {
92 GnmFunc *func = unknown_cat->functions->data;
93 if (func->usage_count > 0) {
94 g_warning ("Function %s still has %d users.\n",
95 gnm_func_get_name (func, FALSE),
96 func->usage_count);
97 func->usage_count = 0;
99 g_object_unref (func);
101 gnm_func_builtin_shutdown ();
103 g_hash_table_destroy (functions_by_name);
104 functions_by_name = NULL;
106 g_hash_table_destroy (functions_by_localized_name);
107 functions_by_localized_name = NULL;
111 * gnm_func_enumerate:
113 * Return value: (element-type GnmFunc) (transfer container):
115 GPtrArray *
116 gnm_func_enumerate (void)
118 GPtrArray *res = g_ptr_array_new ();
119 GHashTableIter hiter;
120 gpointer value;
122 g_hash_table_iter_init (&hiter, functions_by_name);
123 while (g_hash_table_iter_next (&hiter, NULL, &value))
124 g_ptr_array_add (res, value);
126 return res;
129 static GnmValue *
130 error_function_no_full_info (GnmFuncEvalInfo *ei,
131 int argc,
132 GnmExprConstPtr const *argv)
134 return value_new_error (ei->pos, _("Function implementation not available."));
137 static void
138 gnm_func_load_stub (GnmFunc *func)
140 g_return_if_fail (func->fn_type == GNM_FUNC_TYPE_STUB);
142 g_signal_emit (G_OBJECT (func), signals[SIG_LOAD_STUB], 0);
144 if (func->fn_type == GNM_FUNC_TYPE_STUB) {
145 g_printerr ("Failed to load %s\n", func->name);
146 gnm_func_set_varargs (func, error_function_no_full_info, NULL);
147 gnm_func_set_help (func, NULL, 0);
151 inline void
152 gnm_func_load_if_stub (GnmFunc *func)
154 if (func->fn_type == GNM_FUNC_TYPE_STUB)
155 gnm_func_load_stub (func);
158 static char *
159 split_at_colon (char const *s, char **rest)
161 char *dup = g_strdup (s);
162 char *colon = strchr (dup, ':');
163 if (colon) {
164 *colon = 0;
165 if (rest) *rest = colon + 1;
166 } else {
167 if (rest) *rest = NULL;
169 return dup;
172 /* ------------------------------------------------------------------------- */
174 static void
175 gnm_func_group_free (GnmFuncGroup *fn_group)
177 g_return_if_fail (fn_group != NULL);
178 g_return_if_fail (fn_group->functions == NULL);
180 if (fn_group->ref_count-- > 1)
181 return;
183 go_string_unref (fn_group->internal_name);
184 go_string_unref (fn_group->display_name);
185 g_free (fn_group);
188 static GnmFuncGroup *
189 gnm_func_group_ref (GnmFuncGroup *fn_group)
191 fn_group->ref_count++;
192 return fn_group;
195 GType
196 gnm_func_group_get_type (void)
198 static GType t = 0;
200 if (t == 0) {
201 t = g_boxed_type_register_static ("GnmFuncGroup",
202 (GBoxedCopyFunc)gnm_func_group_ref,
203 (GBoxedFreeFunc)gnm_func_group_free);
205 return t;
208 static gint
209 function_category_compare (gconstpointer a, gconstpointer b)
211 GnmFuncGroup const *cat_a = a;
212 GnmFuncGroup const *cat_b = b;
214 return go_string_cmp (cat_a->display_name, cat_b->display_name);
217 GnmFuncGroup *
218 gnm_func_group_fetch (char const *name, char const *translation)
220 GnmFuncGroup *cat = NULL;
221 GList *l;
223 g_return_val_if_fail (name != NULL, NULL);
225 for (l = categories; l != NULL; l = l->next) {
226 cat = l->data;
227 if (strcmp (cat->internal_name->str, name) == 0) {
228 break;
232 if (l == NULL) {
233 cat = g_new (GnmFuncGroup, 1);
234 cat->internal_name = go_string_new (name);
235 cat->ref_count = 1;
236 if (translation != NULL) {
237 cat->display_name = go_string_new (translation);
238 cat->has_translation = TRUE;
239 } else {
240 cat->display_name = go_string_new (name);
241 cat->has_translation = FALSE;
243 cat->functions = NULL;
244 categories = g_list_insert_sorted (
245 categories, cat, &function_category_compare);
246 } else if (translation != NULL && translation != name &&
247 !cat->has_translation) {
248 go_string_unref (cat->display_name);
249 cat->display_name = go_string_new (translation);
250 cat->has_translation = TRUE;
251 categories = g_list_remove_link (categories, l);
252 g_list_free_1 (l);
253 categories = g_list_insert_sorted (
254 categories, cat, &function_category_compare);
257 return cat;
260 GnmFuncGroup *
261 gnm_func_group_get_nth (int n)
263 return g_list_nth_data (categories, n);
266 static void
267 gnm_func_group_add_func (GnmFuncGroup *fn_group, GnmFunc *func)
269 g_return_if_fail (fn_group != NULL);
270 g_return_if_fail (func != NULL);
272 fn_group->functions = g_slist_prepend (fn_group->functions, func);
275 static void
276 gnm_func_group_remove_func (GnmFuncGroup *fn_group, GnmFunc *func)
278 g_return_if_fail (fn_group != NULL);
279 g_return_if_fail (func != NULL);
281 fn_group->functions = g_slist_remove (fn_group->functions, func);
282 if (fn_group->functions == NULL) {
283 categories = g_list_remove (categories, fn_group);
284 if (unknown_cat == fn_group)
285 unknown_cat = NULL;
286 gnm_func_group_free (fn_group);
290 /******************************************************************************/
292 static void
293 gnm_func_create_arg_names (GnmFunc *func)
295 int i;
296 GPtrArray *ptr;
298 g_return_if_fail (func != NULL);
300 ptr = g_ptr_array_new ();
301 for (i = 0; i < func->help_count; i++) {
302 const char *s;
303 if (func->help[i].type != GNM_FUNC_HELP_ARG)
304 continue;
306 s = gnm_func_gettext (func, func->help[i].text);
307 g_ptr_array_add (ptr, split_at_colon (s, NULL));
310 func->arg_names = ptr;
313 gboolean
314 gnm_func_is_varargs (GnmFunc *func)
316 gnm_func_load_if_stub (func);
317 return func->fn_type == GNM_FUNC_TYPE_NODES;
320 gboolean
321 gnm_func_is_fixargs (GnmFunc *func)
323 gnm_func_load_if_stub (func);
324 return func->fn_type == GNM_FUNC_TYPE_ARGS;
327 void
328 gnm_func_set_stub (GnmFunc *func)
330 func->fn_type = GNM_FUNC_TYPE_STUB;
332 g_free (func->arg_spec);
333 func->arg_spec = NULL;
335 g_free (func->arg_types);
336 func->arg_types = NULL;
338 func->min_args = func->max_args = 0;
340 func->nodes_func = NULL;
341 func->args_func = NULL;
343 gnm_func_set_help (func, NULL, 0);
347 * gnm_func_set_varargs: (skip)
348 * @func: #GnmFunc
349 * @fn: evaluation function
350 * @spec: (nullable): argument type specification
352 void
353 gnm_func_set_varargs (GnmFunc *func, GnmFuncNodes fn, const char *spec)
355 g_return_if_fail (GNM_IS_FUNC (func));
356 g_return_if_fail (fn != NULL);
358 gnm_func_set_stub (func); // Clear out stuff
360 func->fn_type = GNM_FUNC_TYPE_NODES;
361 func->nodes_func = fn;
362 func->arg_spec = g_strdup (spec);
363 func->min_args = 0;
364 func->min_args = G_MAXINT;
366 if (spec) {
367 const char *p = strchr (spec, '|');
368 const char *q = strchr (spec, '.'); // "..."
369 if (p) func->min_args = p - spec;
370 if (!q) func->min_args = strlen (spec) - (p != NULL);
375 * gnm_func_set_fixargs: (skip)
376 * @func: #GnmFunc
377 * @fn: evaluation function
378 * @spec: argument type specification
380 void
381 gnm_func_set_fixargs (GnmFunc *func, GnmFuncArgs fn, const char *spec)
383 char *p;
385 g_return_if_fail (GNM_IS_FUNC (func));
386 g_return_if_fail (fn != NULL);
387 g_return_if_fail (spec != NULL);
389 gnm_func_set_stub (func); // Clear out stuff
391 func->fn_type = GNM_FUNC_TYPE_ARGS;
392 func->args_func = fn;
393 func->arg_spec = g_strdup (spec);
395 func->arg_types = g_strdup (func->arg_spec);
396 p = strchr (func->arg_types, '|');
397 if (p) {
398 func->min_args = p - func->arg_types;
399 memmove (p, p + 1, strlen (p));
400 } else
401 func->min_args = strlen (func->arg_types);
402 func->max_args = strlen (func->arg_types);
406 * gnm_func_get_help:
407 * @func: #GnmFunc
408 * @n: (out) (optional): number of help items, not counting the end item
410 * Returns: (transfer none) (array length=n) (nullable): @func's help items.
412 GnmFuncHelp const *
413 gnm_func_get_help (GnmFunc *func, int *n)
415 if (n) *n = 0;
417 g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
418 g_return_val_if_fail (func->help, NULL);
420 if (n) *n = func->help_count;
421 return func->help;
425 void
426 gnm_func_set_help (GnmFunc *func, GnmFuncHelp const *help, int n)
428 g_return_if_fail (GNM_IS_FUNC (func));
429 g_return_if_fail (n <= 0 || help != NULL);
431 if (n < 0) {
432 for (n = 0; help && help[n].type != GNM_FUNC_HELP_END; )
433 n++;
436 if (func->help) {
437 int i;
438 for (i = 0; i <= func->help_count; i++)
439 g_free ((char *)(func->help[i].text));
440 g_free (func->help);
441 func->help = NULL;
444 if (func->arg_names) {
445 g_ptr_array_foreach (func->arg_names, (GFunc)g_free, NULL);
446 g_ptr_array_free (func->arg_names, TRUE);
447 func->arg_names = NULL;
450 if (help) {
451 int i;
453 func->help = g_new (GnmFuncHelp, n + 1);
454 for (i = 0; i < n; i++) {
455 func->help[i].type = help[i].type;
456 func->help[i].text = g_strdup (help[i].text);
458 func->help[n].type = GNM_FUNC_HELP_END;
459 func->help[n].text = NULL;
461 func->help_count = n;
462 gnm_func_create_arg_names (func);
463 } else {
464 func->help_count = 0;
469 static void
470 gnm_func_set_localized_name (GnmFunc *fd, const char *lname)
472 gboolean in_hashes = !(fd->flags & GNM_FUNC_IS_WORKBOOK_LOCAL);
474 if (g_strcmp0 (fd->localized_name, lname) == 0)
475 return;
477 if (in_hashes && fd->localized_name)
478 g_hash_table_remove (functions_by_localized_name, fd->localized_name);
479 g_free (fd->localized_name);
481 fd->localized_name = g_strdup (lname);
482 if (in_hashes && lname)
483 g_hash_table_insert (functions_by_localized_name,
484 fd->localized_name, fd);
488 * gnm_func_inc_usage:
489 * @func: #GnmFunc
491 * This function increments the usage count of @func. A non-zero usage count
492 * prevents the unloading of the function.
494 * Returns: (transfer full): a new reference to @func.
496 GnmFunc *
497 gnm_func_inc_usage (GnmFunc *func)
499 g_return_val_if_fail (func != NULL, NULL);
501 func->usage_count++;
502 if (func->usage_count == 1)
503 g_object_notify (G_OBJECT (func), "in-use");
504 return func;
508 * gnm_func_dec_usage:
509 * @func: (transfer full): #GnmFunc
511 * This function decrements the usage count of @func. When the usage count
512 * reaches zero, the function may be unloaded, for example by unloading the
513 * plugin that defines it.
515 void
516 gnm_func_dec_usage (GnmFunc *func)
518 g_return_if_fail (func != NULL);
519 g_return_if_fail (func->usage_count > 0);
521 func->usage_count--;
522 if (func->usage_count == 0)
523 g_object_notify (G_OBJECT (func), "in-use");
526 gboolean
527 gnm_func_get_in_use (GnmFunc *func)
529 g_return_val_if_fail (func != NULL, FALSE);
531 return func->usage_count > 0;
536 * gnm_func_lookup:
537 * @name: name of function
538 * @scope: (nullable): scope of function, %NULL for global
540 * Returns: (nullable) (transfer none): the function of that name.
542 GnmFunc *
543 gnm_func_lookup (char const *name, Workbook *scope)
545 GnmFunc *fd = g_hash_table_lookup (functions_by_name, name);
546 if (fd != NULL)
547 return fd;
548 if (scope == NULL || scope->sheet_local_functions == NULL)
549 return NULL;
550 return g_hash_table_lookup (scope->sheet_local_functions, (gpointer)name);
554 * gnm_func_lookup_localized:
555 * @name: localized name of function
556 * @scope: (nullable): scope of function, %NULL for global
558 * Returns: (nullable) (transfer none): the function of that name.
560 GnmFunc *
561 gnm_func_lookup_localized (char const *name, Workbook *scope)
563 GnmFunc *fd;
564 GHashTableIter hiter;
565 gpointer value;
567 /* Must localize all function names. */
568 g_hash_table_iter_init (&hiter, functions_by_name);
569 while (g_hash_table_iter_next (&hiter, NULL, &value)) {
570 GnmFunc *fd = value;
571 (void)gnm_func_get_name (fd, TRUE);
574 fd = g_hash_table_lookup (functions_by_localized_name, name);
575 if (fd != NULL)
576 return fd;
577 if (scope == NULL || scope->sheet_local_functions == NULL)
578 return NULL;
579 return g_hash_table_lookup (scope->sheet_local_functions, (gpointer)name);
583 * gnm_func_lookup_prefix:
584 * @prefix: prefix to search for
585 * @scope:
586 * @trans: whether to search translated function names
588 * Returns: (element-type GnmFunc*) (transfer full): A list of functions
589 * whose names start with @prefix.
591 GSList *
592 gnm_func_lookup_prefix (char const *prefix, Workbook *scope, gboolean trans)
594 GSList *res = NULL;
595 GHashTableIter hiter;
596 gpointer value;
599 * Always iterate over functions_by_name as the localized name
600 * might not be set yet.
602 g_hash_table_iter_init (&hiter, functions_by_name);
603 while (g_hash_table_iter_next (&hiter, NULL, &value)) {
604 GnmFunc *fd = value;
605 if (!(fd->flags & (GNM_FUNC_IS_PLACEHOLDER | GNM_FUNC_INTERNAL))) {
606 const char *name = gnm_func_get_name (fd, trans);
607 if (g_str_has_prefix (name, prefix)) {
608 gnm_func_inc_usage (fd);
609 res = g_slist_prepend (res, fd);
614 return res;
618 * gnm_func_get_translation_domain:
619 * @func: #GnmFunc
621 * Returns: (transfer none): the translation domain for @func's help text.
623 char const *
624 gnm_func_get_translation_domain (GnmFunc *func)
626 g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
627 return func->tdomain->str;
631 * gnm_func_set_translation_domain:
632 * @func: #GnmFunc
633 * @tdomain: (nullable): Translation domain, %NULL for Gnumeric's.
635 void
636 gnm_func_set_translation_domain (GnmFunc *func, const char *tdomain)
638 g_return_if_fail (GNM_IS_FUNC (func));
640 if (!tdomain)
641 tdomain = GETTEXT_PACKAGE;
643 if (g_strcmp0 (func->tdomain->str, tdomain) == 0)
644 return;
646 go_string_unref (func->tdomain);
647 func->tdomain = go_string_new (tdomain);
649 g_object_notify (G_OBJECT (func), "translation-domain");
653 * gnm_func_gettext:
654 * @func: #GnmFunc
655 * @str: string to translate
657 * Returns: (transfer none): @str translated in @func's translation
658 * domain.
660 char const *
661 gnm_func_gettext (GnmFunc *func, const char *str)
663 g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
664 g_return_val_if_fail (str != NULL, NULL);
666 return dgettext (func->tdomain->str, str);
670 GnmFuncFlags
671 gnm_func_get_flags (GnmFunc *func)
673 g_return_val_if_fail (GNM_IS_FUNC (func), GNM_FUNC_SIMPLE);
674 return func->flags;
677 void
678 gnm_func_set_flags (GnmFunc *func, GnmFuncFlags f)
680 g_return_if_fail (GNM_IS_FUNC (func));
681 func->flags = f;
684 GnmFuncImplStatus
685 gnm_func_get_impl_status (GnmFunc *func)
687 g_return_val_if_fail (GNM_IS_FUNC (func), GNM_FUNC_IMPL_STATUS_UNIMPLEMENTED);
688 return func->impl_status;
691 void
692 gnm_func_set_impl_status (GnmFunc *func, GnmFuncImplStatus st)
694 g_return_if_fail (GNM_IS_FUNC (func));
695 func->impl_status = st;
699 GnmFuncTestStatus
700 gnm_func_get_test_status (GnmFunc *func)
702 g_return_val_if_fail (GNM_IS_FUNC (func), GNM_FUNC_TEST_STATUS_UNKNOWN);
703 return func->test_status;
706 void
707 gnm_func_set_test_status (GnmFunc *func, GnmFuncTestStatus st)
709 g_return_if_fail (GNM_IS_FUNC (func));
710 func->test_status = st;
715 * gnm_func_get_function_group:
716 * @func: #GnmFunc
718 * Returns: (transfer none): the function group to which @func belongs.
720 GnmFuncGroup *
721 gnm_func_get_function_group (GnmFunc *func)
723 g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
724 return func->fn_group;
728 void
729 gnm_func_set_function_group (GnmFunc *func, GnmFuncGroup *group)
731 g_return_if_fail (GNM_IS_FUNC (func));
732 g_return_if_fail (group != NULL);
734 if (func->fn_group == group)
735 return;
737 if (func->fn_group)
738 gnm_func_group_remove_func (func->fn_group, func);
739 func->fn_group = group;
740 gnm_func_group_add_func (group, func);
742 if (group == unknown_cat)
743 func->flags |= GNM_FUNC_IS_PLACEHOLDER;
744 else
745 func->flags &= ~GNM_FUNC_IS_PLACEHOLDER;
748 void
749 gnm_func_set_from_desc (GnmFunc *func, GnmFuncDescriptor const *desc)
751 //static char const valid_tokens[] = "fsbraAES?|";
753 g_return_if_fail (GNM_IS_FUNC (func));
754 g_return_if_fail (desc != NULL);
756 // Not setting name, localized_name. Also not setting things not present
757 // in desc, such as translation domain.
759 if (desc->fn_args != NULL) {
760 gnm_func_set_fixargs (func, desc->fn_args, desc->arg_spec);
761 } else if (desc->fn_nodes != NULL) {
762 gnm_func_set_varargs (func, desc->fn_nodes, desc->arg_spec);
763 } else {
764 gnm_func_set_stub (func);
765 return;
768 gnm_func_set_help (func, desc->help, -1);
769 func->flags = desc->flags;
770 func->impl_status = desc->impl_status;
771 func->test_status = desc->test_status;
776 * gnm_func_add:
777 * @group:
778 * @descriptor:
779 * @tdomain: (nullable):
781 * Returns: (transfer full): a new #GnmFunc.
783 GnmFunc *
784 gnm_func_add (GnmFuncGroup *fn_group,
785 GnmFuncDescriptor const *desc,
786 const char *tdomain)
788 GnmFunc *func;
790 g_return_val_if_fail (fn_group != NULL, NULL);
791 g_return_val_if_fail (desc != NULL, NULL);
793 func = g_object_new (GNM_FUNC_TYPE,
794 "name", desc->name,
795 NULL);
796 gnm_func_set_translation_domain (func, tdomain);
798 gnm_func_set_from_desc (func, desc);
800 if (func->fn_type == GNM_FUNC_TYPE_STUB) {
801 g_warning ("Invalid function has neither args nor nodes handler");
802 g_object_unref (func);
803 return NULL;
806 gnm_func_set_function_group (func, fn_group);
808 if (!(func->flags & GNM_FUNC_IS_WORKBOOK_LOCAL))
809 g_hash_table_insert (functions_by_name,
810 (gpointer)(func->name), func);
812 return func;
815 /* Handle unknown functions on import without losing their names */
816 static GnmValue *
817 unknownFunctionHandler (GnmFuncEvalInfo *ei,
818 G_GNUC_UNUSED int argc,
819 G_GNUC_UNUSED GnmExprConstPtr const *argv)
821 return value_new_error_NAME (ei->pos);
824 static char *
825 invent_name (const char *pref, GHashTable *h, const char *template)
827 static int count = 0;
828 char *name = g_utf8_strdown (pref, -1);
830 while (g_hash_table_lookup (h, name)) {
831 count++;
832 g_free (name);
833 name = g_strdup_printf (template, count);
836 return name;
839 static GnmFunc *
840 gnm_func_add_placeholder_full (Workbook *scope,
841 char const *gname, char const *lname,
842 char const *type)
844 GnmFuncDescriptor desc;
845 GnmFunc *func;
846 char const *unknown_cat_name = N_("Unknown Function");
847 gboolean copy_gname = TRUE;
848 gboolean copy_lname = TRUE;
850 g_return_val_if_fail (gname || lname, NULL);
851 g_return_val_if_fail (gname == NULL || gnm_func_lookup (gname, scope) == NULL, NULL);
852 g_return_val_if_fail (lname == NULL || gnm_func_lookup_localized (lname, scope) == NULL, NULL);
854 if (!unknown_cat)
855 unknown_cat = gnm_func_group_fetch
856 (unknown_cat_name, _(unknown_cat_name));
858 if (!gname) {
860 * This is actually a bit of a problem if we don't end up
861 * with a copy of lname (because there already is a function
862 * with that name). We're likely to save a template name,
863 * but I don't see what else to do.
865 gname = invent_name (lname, functions_by_name, "unknown%d");
866 copy_gname = FALSE;
868 if (!lname) {
869 /* xgettext: This represents a made-up translated function name. */
870 lname = invent_name (gname, functions_by_localized_name, _("unknown%d"));
871 copy_lname = FALSE;
874 if (gnm_debug_flag ("func"))
875 g_printerr ("Adding placeholder for %s (aka %s)\n", gname, lname);
877 memset (&desc, 0, sizeof (GnmFuncDescriptor));
878 desc.name = gname;
879 desc.arg_spec = NULL;
880 desc.help = NULL;
881 desc.fn_args = NULL;
882 desc.fn_nodes = &unknownFunctionHandler;
883 desc.flags = GNM_FUNC_IS_PLACEHOLDER;
884 desc.impl_status = GNM_FUNC_IMPL_STATUS_EXISTS;
885 desc.test_status = GNM_FUNC_TEST_STATUS_UNKNOWN;
887 if (scope != NULL)
888 desc.flags |= GNM_FUNC_IS_WORKBOOK_LOCAL;
889 else {
890 #if 0
891 /* WISHLIST : it would be nice to have a log if these. */
892 g_warning ("Unknown %s function : %s", type, desc.name);
893 #endif
896 func = gnm_func_add (unknown_cat, &desc, NULL);
898 if (lname) {
899 gnm_func_set_localized_name (func, lname);
900 if (!copy_lname)
901 g_free ((char *)lname);
904 if (!copy_gname)
905 g_free ((char *)gname);
907 if (scope != NULL) {
908 if (scope->sheet_local_functions == NULL)
909 scope->sheet_local_functions = g_hash_table_new_full (
910 g_str_hash, g_str_equal,
911 NULL, g_object_unref);
912 g_hash_table_insert (scope->sheet_local_functions,
913 (gpointer)func->name, func);
916 return func;
920 * gnm_func_add_placeholder:
921 * @scope: (nullable): scope to defined placeholder, %NULL for global
922 * @name: (nullable): function name
923 * @type:
925 * Returns: (transfer none): a placeholder with the given name.
927 GnmFunc *
928 gnm_func_add_placeholder (Workbook *scope,
929 char const *name, char const *type)
931 return gnm_func_add_placeholder_full (scope, name, NULL, type);
935 * gnm_func_add_placeholder_localized:
936 * @gname: (nullable): function name
937 * @lname: localized function name
939 * Returns: (transfer none): a placeholder with the given localized name.
941 GnmFunc *
942 gnm_func_add_placeholder_localized (char const *gname, char const *lname)
944 return gnm_func_add_placeholder_full (NULL, gname, lname, "?");
948 * gnm_func_lookup_or_add_placeholder:
949 * @name: function name
951 * Returns: (transfer none): a #GnmFunc named @name, either an existing
952 * one or a placeholder.
954 GnmFunc *
955 gnm_func_lookup_or_add_placeholder (char const *name)
957 GnmFunc * f = gnm_func_lookup (name, NULL);
958 if (f == NULL)
959 f = gnm_func_add_placeholder (NULL, name, "");
960 return f;
964 * gnm_func_get_name:
965 * @func: #GnmFunc to query
966 * @localized: if %TRUE, use localized name
968 * Returns: (transfer none): @func's name
970 char const *
971 gnm_func_get_name (GnmFunc const *func, gboolean localized)
973 int i;
974 GnmFunc *fd = (GnmFunc *)func;
976 g_return_val_if_fail (func != NULL, NULL);
978 if (!localized)
979 return func->name;
981 if (func->localized_name)
982 return func->localized_name;
985 * Deduce the translated names from the help texts. This
986 * code doesn't currently check for clashes in translated
987 * names.
990 gnm_func_load_if_stub (fd);
992 for (i = 0; func->localized_name == NULL && i < func->help_count; i++) {
993 const char *s, *sl;
994 char *U;
995 if (func->help[i].type != GNM_FUNC_HELP_NAME)
996 continue;
998 s = func->help[i].text;
999 sl = gnm_func_gettext (fd, s);
1000 if (s == sl) /* String not actually translated. */
1001 continue;
1003 U = split_at_colon (sl, NULL);
1004 if (U) {
1005 char *lname = g_utf8_strdown (U, -1);
1006 gnm_func_set_localized_name (fd, lname);
1007 g_free (lname);
1009 g_free (U);
1012 if (!func->localized_name)
1013 gnm_func_set_localized_name (fd, fd->name);
1015 return func->localized_name;
1019 * gnm_func_get_description:
1020 * @func: #GnmFunc
1022 * Returns: (transfer none): the description of the function
1024 char const *
1025 gnm_func_get_description (GnmFunc *func)
1027 gint i;
1028 g_return_val_if_fail (func != NULL, NULL);
1030 gnm_func_load_if_stub (func);
1032 for (i = 0; i < func->help_count; i++) {
1033 const char *desc;
1035 if (func->help[i].type != GNM_FUNC_HELP_NAME)
1036 continue;
1038 desc = strchr (gnm_func_gettext (func, func->help[i].text), ':');
1039 return desc ? (desc + 1) : "";
1041 return "";
1045 * gnm_func_count_args:
1046 * @func: pointer to function definition
1047 * @min: (out): location for mininum args
1048 * @max: (out): location for mininum args
1050 * This calculates the maximum and minimum number of args that can be passed.
1051 * For a vararg function, the maximum will be set to G_MAXINT.
1053 void
1054 gnm_func_count_args (GnmFunc *func, int *min, int *max)
1056 g_return_if_fail (min != NULL);
1057 g_return_if_fail (max != NULL);
1058 g_return_if_fail (func != NULL);
1060 gnm_func_load_if_stub (func);
1062 *min = func->min_args;
1063 *max = func->max_args;
1067 * gnm_func_get_arg_type:
1068 * @func: the fn defintion
1069 * @arg_idx: zero-based argument offset
1071 * Returns: the type of the argument
1073 char
1074 gnm_func_get_arg_type (GnmFunc *func, int arg_idx)
1076 g_return_val_if_fail (func != NULL, '?');
1078 gnm_func_load_if_stub (func);
1080 g_return_val_if_fail (arg_idx >= 0 && arg_idx < func->max_args, '?');
1082 return func->arg_types ? func->arg_types[arg_idx] : '?';
1086 * gnm_func_get_arg_type_string:
1087 * @func: the fn defintion
1088 * @arg_idx: zero-based argument offset
1090 * Return value: (transfer none): the type of the argument as a string
1092 char const *
1093 gnm_func_get_arg_type_string (GnmFunc *func, int arg_idx)
1095 switch (gnm_func_get_arg_type (func, arg_idx)) {
1096 case 'f':
1097 return _("Number");
1098 case 's':
1099 return _("String");
1100 case 'b':
1101 return _("Boolean");
1102 case 'r':
1103 return _("Cell Range");
1104 case 'A':
1105 return _("Area");
1106 case 'E':
1107 return _("Scalar, Blank, or Error");
1108 case 'S':
1109 return _("Scalar");
1110 case '?':
1111 /* Missing values will be NULL. */
1112 return _("Any");
1114 default:
1115 g_warning ("Unknown arg type");
1116 return "Broken";
1121 * gnm_func_get_arg_name:
1122 * @func: #GnmFunc
1123 * @arg_idx: zero-based argument offset
1125 * Returns: (transfer full) (nullable): the name of the argument
1127 char *
1128 gnm_func_get_arg_name (GnmFunc const *func, guint arg_idx)
1130 g_return_val_if_fail (func != NULL, NULL);
1132 gnm_func_load_if_stub ((GnmFunc *)func);
1134 if (func->arg_names && arg_idx < func->arg_names->len)
1135 return g_strdup (g_ptr_array_index (func->arg_names, arg_idx));
1136 return NULL;
1140 * gnm_func_get_arg_description:
1141 * @func: the fn defintion
1142 * @arg_idx: zero-based argument offset
1144 * Returns: (transfer none): the description of the argument
1146 char const *
1147 gnm_func_get_arg_description (GnmFunc *func, guint arg_idx)
1149 gint i;
1150 g_return_val_if_fail (func != NULL, NULL);
1152 gnm_func_load_if_stub (func);
1154 for (i = 0; i < func->help_count; i++) {
1155 gchar const *desc;
1157 if (func->help[i].type != GNM_FUNC_HELP_ARG)
1158 continue;
1159 if (arg_idx--)
1160 continue;
1162 desc = strchr (gnm_func_gettext (func, func->help[i].text), ':');
1163 if (!desc)
1164 return "";
1166 desc++;
1167 while (g_unichar_isspace (g_utf8_get_char (desc)))
1168 desc = g_utf8_next_char (desc);
1169 return desc;
1172 return "";
1176 * gnm_func_convert_markup_to_pango:
1177 * @desc: the fn or arg description string
1178 * @target: target widget for the markup.
1180 * Return value: the escaped string with @{} markup converted to
1181 * pango markup
1183 char *
1184 gnm_func_convert_markup_to_pango (char const *desc, GtkWidget *target)
1186 GString *str;
1187 gchar *markup, *at;
1188 GdkRGBA link_color;
1189 PangoColor pg;
1190 char *link_color_text, *span_text;
1191 size_t span_text_len;
1193 gnm_get_link_color (target, &link_color);
1194 pg.red = 65535 * link_color.red;
1195 pg.green = 65535 * link_color.green;
1196 pg.blue = 65535 * link_color.blue;
1197 link_color_text = pango_color_to_string (&pg);
1198 span_text = g_strdup_printf ("<span foreground=\"%s\">",
1199 link_color_text);
1200 span_text_len = strlen (span_text);
1201 g_free (link_color_text);
1203 markup = g_markup_escape_text (desc, -1);
1204 str = g_string_new (markup);
1205 g_free (markup);
1207 while ((at = strstr (str->str, "@{"))) {
1208 gint len = at - str->str;
1209 go_string_replace (str, len, 2, span_text, -1);
1210 if ((at = strstr
1211 (str->str + len + span_text_len, "}"))) {
1212 len = at - str->str;
1213 go_string_replace (str, len, 1, "</span>", -1);
1214 } else
1215 g_string_append (str, "</span>");
1217 g_free (span_text);
1219 return g_string_free (str, FALSE);
1223 /* ------------------------------------------------------------------------- */
1225 static inline void
1226 free_values (GnmValue **values, int top)
1228 int i;
1230 for (i = 0; i < top; i++)
1231 if (values [i])
1232 value_release (values [i]);
1235 /* ------------------------------------------------------------------------- */
1238 * function_call_with_exprs:
1239 * @ei: EvalInfo containing valid fn_def!
1241 * Do the guts of calling a function.
1243 * Returns the result.
1245 GnmValue *
1246 function_call_with_exprs (GnmFuncEvalInfo *ei)
1248 GnmFunc const *fn_def;
1249 int i, iter_count, iter_width = 0, iter_height = 0;
1250 char arg_type;
1251 GnmValue **args, *tmp = NULL;
1252 int *iter_item = NULL;
1253 int argc;
1254 GnmExprConstPtr *argv;
1255 GnmExprEvalFlags flags, pass_flags;
1257 g_return_val_if_fail (ei != NULL, NULL);
1258 g_return_val_if_fail (ei->func_call != NULL, NULL);
1260 flags = ei->flags;
1262 argc = ei->func_call->argc;
1263 argv = ei->func_call->argv;
1264 fn_def = ei->func_call->func;
1266 gnm_func_load_if_stub ((GnmFunc *)fn_def);
1268 /* Functions that deal with ExprNodes */
1269 if (fn_def->fn_type == GNM_FUNC_TYPE_NODES)
1270 return fn_def->nodes_func (ei, argc, argv);
1272 /* Functions that take pre-computed Values */
1273 if (argc > fn_def->max_args ||
1274 argc < fn_def->min_args)
1275 return value_new_error_NA (ei->pos);
1277 args = g_alloca (sizeof (GnmValue *) * fn_def->max_args);
1278 iter_count = (eval_pos_is_array_context (ei->pos) &&
1279 (flags & GNM_EXPR_EVAL_PERMIT_NON_SCALAR))
1280 ? 0 : -1;
1282 /* Optimization for IF when implicit iteration is not used. */
1283 if (ei->func_call->func == fn_if && iter_count == -1)
1284 return gnumeric_if2 (ei, argc, argv, flags);
1286 pass_flags = (flags &
1287 (GNM_EXPR_EVAL_ARRAY_CONTEXT));
1289 for (i = 0; i < argc; i++) {
1290 char arg_type = fn_def->arg_types[i];
1291 /* expr is always non-null, missing args are encoded as
1292 * const = empty */
1293 GnmExpr const *expr = argv[i];
1295 if (arg_type == 'A' || arg_type == 'r') {
1296 tmp = args[i] = gnm_expr_eval
1297 (expr, ei->pos,
1298 pass_flags |
1299 GNM_EXPR_EVAL_PERMIT_NON_SCALAR |
1300 GNM_EXPR_EVAL_WANT_REF);
1301 if (VALUE_IS_ERROR (tmp)) {
1302 free_values (args, i);
1303 return tmp;
1306 if (VALUE_IS_CELLRANGE (tmp)) {
1307 gnm_cellref_make_abs (&tmp->v_range.cell.a,
1308 &tmp->v_range.cell.a,
1309 ei->pos);
1310 gnm_cellref_make_abs (&tmp->v_range.cell.b,
1311 &tmp->v_range.cell.b,
1312 ei->pos);
1313 /* Array args accept scalars */
1314 } else if (arg_type != 'A' && !VALUE_IS_ARRAY (tmp)) {
1315 free_values (args, i + 1);
1316 return value_new_error_VALUE (ei->pos);
1318 continue;
1321 /* force scalars whenever we are certain */
1322 tmp = args[i] = gnm_expr_eval
1323 (expr, ei->pos,
1324 pass_flags |
1325 GNM_EXPR_EVAL_PERMIT_EMPTY |
1326 (iter_count >= 0 || arg_type == '?'
1327 ? GNM_EXPR_EVAL_PERMIT_NON_SCALAR
1328 : 0));
1330 if (arg_type == '?') /* '?' arguments are unrestriced */
1331 continue;
1333 /* optional arguments can be blank */
1334 if (i >= fn_def->min_args && VALUE_IS_EMPTY (tmp)) {
1335 if (arg_type == 'E' && !gnm_expr_is_empty (expr)) {
1336 /* An actual argument produced empty. Make
1337 sure function sees that. */
1338 args[i] = value_new_empty ();
1341 continue;
1344 if (tmp == NULL)
1345 tmp = args[i] = value_new_empty ();
1347 /* Handle implicit intersection or iteration depending on flags */
1348 if (VALUE_IS_CELLRANGE (tmp) || VALUE_IS_ARRAY (tmp)) {
1349 if (iter_count > 0) {
1350 if (iter_width != value_area_get_width (tmp, ei->pos) ||
1351 iter_height != value_area_get_height (tmp, ei->pos)) {
1352 free_values (args, i + 1);
1353 return value_new_error_VALUE (ei->pos);
1355 } else {
1356 if (iter_count < 0) {
1357 g_warning ("Damn I thought this was impossible");
1358 iter_count = 0;
1360 iter_item = g_alloca (sizeof (int) * argc);
1361 iter_width = value_area_get_width (tmp, ei->pos);
1362 iter_height = value_area_get_height (tmp, ei->pos);
1364 iter_item [iter_count++] = i;
1366 /* no need to check type, we would fail comparing a range against a "b, f, or s" */
1367 continue;
1370 /* All of these argument types must be scalars */
1371 switch (arg_type) {
1372 case 'b':
1373 if (VALUE_IS_STRING (tmp)) {
1374 gboolean err;
1375 gboolean b = value_get_as_bool (tmp, &err);
1376 if (err) {
1377 free_values (args, i + 1);
1378 return value_new_error_VALUE (ei->pos);
1380 value_release (args[i]);
1381 tmp = args[i] = value_new_bool (b);
1382 break;
1384 /* Fall through. */
1385 case 'f':
1386 if (VALUE_IS_STRING (tmp)) {
1387 tmp = format_match_number (value_peek_string (tmp), NULL,
1388 sheet_date_conv (ei->pos->sheet));
1389 if (tmp == NULL) {
1390 free_values (args, i + 1);
1391 return value_new_error_VALUE (ei->pos);
1393 value_release (args [i]);
1394 args[i] = tmp;
1395 } else if (VALUE_IS_ERROR (tmp)) {
1396 free_values (args, i);
1397 return tmp;
1398 } else if (VALUE_IS_EMPTY (tmp)) {
1399 value_release (args [i]);
1400 tmp = args[i] = value_new_int (0);
1403 if (!VALUE_IS_NUMBER (tmp))
1404 return value_new_error_VALUE (ei->pos);
1405 break;
1407 case 's':
1408 case 'S':
1409 if (VALUE_IS_ERROR (tmp)) {
1410 free_values (args, i);
1411 return tmp;
1413 break;
1415 case 'E': /* nothing necessary */
1416 break;
1418 /* case '?': handled above */
1419 default:
1420 g_warning ("Unknown argument type '%c'", arg_type);
1421 break;
1425 while (i < fn_def->max_args)
1426 args [i++] = NULL;
1428 if (iter_item != NULL) {
1429 int x, y;
1430 GnmValue *res = value_new_array_empty (iter_width, iter_height);
1431 GnmValue const *elem, *err;
1432 GnmValue **iter_vals = g_alloca (sizeof (GnmValue *) * iter_count);
1433 GnmValue **iter_args = g_alloca (sizeof (GnmValue *) * iter_count);
1435 /* collect the args we will iterate on */
1436 for (i = 0 ; i < iter_count; i++)
1437 iter_vals[i] = args[iter_item[i]];
1439 for (x = iter_width; x-- > 0 ; )
1440 for (y = iter_height; y-- > 0 ; ) {
1441 /* marshal the args */
1442 err = NULL;
1443 for (i = 0 ; i < iter_count; i++) {
1444 elem = value_area_get_x_y (iter_vals[i], x, y, ei->pos);
1445 arg_type = fn_def->arg_types[iter_item[i]];
1446 if (arg_type == 'b' || arg_type == 'f') {
1447 if (VALUE_IS_EMPTY (elem))
1448 elem = value_zero;
1449 else if (VALUE_IS_STRING (elem)) {
1450 tmp = format_match_number (value_peek_string (elem), NULL,
1451 sheet_date_conv (ei->pos->sheet));
1452 if (tmp != NULL) {
1453 args [iter_item[i]] = iter_args [i] = tmp;
1454 continue;
1455 } else
1456 break;
1457 } else if (VALUE_IS_ERROR (elem)) {
1458 err = elem;
1459 break;
1460 } else if (!VALUE_IS_NUMBER (elem))
1461 break;
1462 } else if (arg_type == 's') {
1463 if (VALUE_IS_EMPTY (elem)) {
1464 args [iter_item[i]] = iter_args [i] = value_new_string ("");
1465 continue;
1466 } else if (VALUE_IS_ERROR (elem)) {
1467 err = elem;
1468 break;
1469 } else if (!VALUE_IS_STRING (elem))
1470 break;
1471 } else if (elem == NULL) {
1472 args [iter_item[i]] = iter_args [i] = value_new_empty ();
1473 continue;
1475 args [iter_item[i]] = iter_args [i] = value_dup (elem);
1478 res->v_array.vals[x][y] = (i == iter_count)
1479 ? fn_def->args_func (ei, (GnmValue const * const *)args)
1480 : ((err != NULL) ? value_dup (err)
1481 : value_new_error_VALUE (ei->pos));
1482 free_values (iter_args, i);
1485 /* free the primaries, not the already freed iteration */
1486 for (i = 0 ; i < iter_count; i++)
1487 args[iter_item[i]] = iter_vals[i];
1488 tmp = res;
1489 i = fn_def->max_args;
1490 } else
1491 tmp = fn_def->args_func (ei, (GnmValue const * const *)args);
1493 free_values (args, i);
1494 return tmp;
1498 * Use this to invoke a register function: the only drawback is that
1499 * you have to compute/expand all of the values to use this
1501 GnmValue *
1502 function_call_with_values (GnmEvalPos const *ep, char const *fn_name,
1503 int argc, GnmValue const * const *values)
1505 GnmFunc *fn_def;
1507 g_return_val_if_fail (ep != NULL, NULL);
1508 g_return_val_if_fail (fn_name != NULL, NULL);
1509 g_return_val_if_fail (ep->sheet != NULL, NULL);
1511 /* FIXME : support workbook local functions */
1512 fn_def = gnm_func_lookup (fn_name, NULL);
1513 if (fn_def == NULL)
1514 return value_new_error_NAME (ep);
1515 return function_def_call_with_values (ep, fn_def, argc, values);
1518 GnmValue *
1519 function_def_call_with_values (GnmEvalPos const *ep, GnmFunc const *fn_def,
1520 int argc, GnmValue const * const *values)
1522 GnmValue *retval;
1523 GnmExprFunction ef;
1524 GnmFuncEvalInfo fs;
1526 fs.pos = ep;
1527 fs.func_call = &ef;
1528 ef.func = (GnmFunc *)fn_def;
1530 gnm_func_load_if_stub (ef.func);
1532 if (fn_def->fn_type == GNM_FUNC_TYPE_NODES) {
1534 * If function deals with ExprNodes, create some
1535 * temporary ExprNodes with constants.
1537 GnmExprConstant *expr = g_new (GnmExprConstant, argc);
1538 GnmExprConstPtr *argv = g_new (GnmExprConstPtr, argc);
1539 int i;
1541 for (i = 0; i < argc; i++) {
1542 gnm_expr_constant_init (expr + i, values[i]);
1543 argv[i] = (GnmExprConstPtr)(expr + i);
1545 retval = fn_def->nodes_func (&fs, argc, argv);
1546 g_free (argv);
1547 g_free (expr);
1548 } else
1549 retval = fn_def->args_func (&fs, values);
1551 return retval;
1554 /* ------------------------------------------------------------------------- */
1556 typedef struct {
1557 FunctionIterateCB callback;
1558 void *closure;
1559 gboolean strict;
1560 gboolean ignore_subtotal;
1561 } IterateCallbackClosure;
1564 * cb_iterate_cellrange:
1566 * Helper routine used by the function_iterate_do_value routine.
1567 * Invoked by the sheet cell range iterator.
1569 static GnmValue *
1570 cb_iterate_cellrange (GnmCellIter const *iter, gpointer user)
1573 IterateCallbackClosure *data = user;
1574 GnmCell *cell;
1575 GnmValue *res;
1576 GnmEvalPos ep;
1578 if (NULL == (cell = iter->cell)) {
1579 ep.sheet = iter->pp.sheet;
1580 ep.dep = NULL;
1581 ep.eval.col = iter->pp.eval.col;
1582 ep.eval.row = iter->pp.eval.row;
1583 return (*data->callback)(&ep, NULL, data->closure);
1586 if (data->ignore_subtotal && gnm_cell_has_expr (cell) &&
1587 gnm_expr_top_contains_subtotal (cell->base.texpr))
1588 return NULL;
1590 gnm_cell_eval (cell);
1591 eval_pos_init_cell (&ep, cell);
1593 /* If we encounter an error for the strict case, short-circuit here. */
1594 if (data->strict && (NULL != (res = gnm_cell_is_error (cell))))
1595 return value_new_error_str (&ep, res->v_err.mesg);
1597 /* All other cases -- including error -- just call the handler. */
1598 return (*data->callback)(&ep, cell->value, data->closure);
1602 * function_iterate_do_value:
1604 * Helper routine for function_iterate_argument_values.
1606 static GnmValue *
1607 function_iterate_do_value (GnmEvalPos const *ep,
1608 FunctionIterateCB callback,
1609 gpointer closure,
1610 GnmValue const *value,
1611 gboolean strict,
1612 CellIterFlags iter_flags)
1614 GnmValue *res = NULL;
1616 switch (value->v_any.type){
1617 case VALUE_ERROR:
1618 if (strict) {
1619 res = value_dup (value);
1620 break;
1622 /* Fall through. */
1624 case VALUE_EMPTY:
1625 case VALUE_BOOLEAN:
1626 case VALUE_FLOAT:
1627 case VALUE_STRING:
1628 res = (*callback)(ep, value, closure);
1629 break;
1631 case VALUE_ARRAY: {
1632 int x, y;
1634 /* Note the order here. */
1635 for (y = 0; y < value->v_array.y; y++) {
1636 for (x = 0; x < value->v_array.x; x++) {
1637 res = function_iterate_do_value (
1638 ep, callback, closure,
1639 value->v_array.vals [x][y],
1640 strict, CELL_ITER_IGNORE_BLANK);
1641 if (res != NULL)
1642 return res;
1645 break;
1647 case VALUE_CELLRANGE: {
1648 IterateCallbackClosure data;
1650 data.callback = callback;
1651 data.closure = closure;
1652 data.strict = strict;
1653 data.ignore_subtotal = (iter_flags & CELL_ITER_IGNORE_SUBTOTAL) != 0;
1655 res = workbook_foreach_cell_in_range (ep, value, iter_flags,
1656 cb_iterate_cellrange,
1657 &data);
1660 return res;
1664 * function_iterate_argument_values:
1665 * @ep: The position in a workbook at which to evaluate
1666 * @callback: (scope call): The routine to be invoked for every value computed
1667 * @callback_closure: Closure for the callback.
1668 * @argc:
1669 * @argv:
1670 * @strict: If TRUE, the function is considered "strict". This means
1671 * that if an error value occurs as an argument, the iteration
1672 * will stop and that error will be returned. If FALSE, an
1673 * error will be passed on to the callback (as a GnmValue *
1674 * of type VALUE_ERROR).
1675 * @iter_flags:
1677 * Return value:
1678 * NULL : if no errors were reported.
1679 * GnmValue * : if an error was found during strict evaluation
1680 * VALUE_TERMINATE : if the callback requested termination of the iteration.
1682 * This routine provides a simple way for internal functions with variable
1683 * number of arguments to be written: this would iterate over a list of
1684 * expressions (expr_node_list) and will invoke the callback for every
1685 * GnmValue found on the list (this means that ranges get properly expaned).
1687 GnmValue *
1688 function_iterate_argument_values (GnmEvalPos const *ep,
1689 FunctionIterateCB callback,
1690 void *callback_closure,
1691 int argc,
1692 GnmExprConstPtr const *argv,
1693 gboolean strict,
1694 CellIterFlags iter_flags)
1696 GnmValue *result = NULL;
1697 int a;
1699 for (a = 0; result == NULL && a < argc; a++) {
1700 GnmExpr const *expr = argv[a];
1701 GnmValue *val;
1703 if (iter_flags & CELL_ITER_IGNORE_SUBTOTAL &&
1704 gnm_expr_contains_subtotal (expr))
1705 continue;
1707 /* need to drill down into names to handle things like
1708 * sum(name) with name := (A:A,B:B) */
1709 while (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_NAME) {
1710 GnmExprTop const *texpr = expr->name.name->texpr;
1711 expr = texpr ? texpr->expr : NULL;
1712 if (expr == NULL) {
1713 if (strict)
1714 return value_new_error_REF (ep);
1715 break;
1718 if (!expr)
1719 continue;
1721 /* Handle sets as a special case */
1722 if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_SET) {
1723 result = function_iterate_argument_values
1724 (ep, callback, callback_closure,
1725 expr->set.argc, expr->set.argv,
1726 strict, iter_flags);
1727 continue;
1730 /* We need a cleaner model of what to do here.
1731 * In non-array mode
1732 * SUM(Range)
1733 * will obviously return Range
1735 * SUM(INDIRECT(Range))
1736 * SUM(INDIRECT(Range):....)
1737 * will do implicit intersection on Range (in non-array mode),
1738 * but allow non-scalar results from indirect (no intersection)
1740 * SUM(Range=3)
1741 * will do implicit intersection in non-array mode */
1742 if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_CONSTANT)
1743 val = value_dup (expr->constant.value);
1744 else if (eval_pos_is_array_context (ep) ||
1745 GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL ||
1746 GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_RANGE_CTOR ||
1747 GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_INTERSECT)
1748 val = gnm_expr_eval (expr, ep,
1749 GNM_EXPR_EVAL_PERMIT_EMPTY | GNM_EXPR_EVAL_PERMIT_NON_SCALAR);
1750 else
1751 val = gnm_expr_eval (expr, ep, GNM_EXPR_EVAL_PERMIT_EMPTY);
1753 if (val == NULL)
1754 continue;
1756 if (strict && VALUE_IS_ERROR (val)) {
1757 /* Be careful not to make VALUE_TERMINATE into a real value */
1758 return val;
1761 result = function_iterate_do_value (ep, callback, callback_closure,
1762 val, strict, iter_flags);
1763 value_release (val);
1765 return result;
1770 * gnm_eval_info_get_func:
1771 * @ei: #GnmFuncEvalInfo
1773 * Returns: (transfer none): the called function.
1775 GnmFunc const *
1776 gnm_eval_info_get_func (GnmFuncEvalInfo const *ei)
1778 return ei->func_call->func;
1782 gnm_eval_info_get_arg_count (GnmFuncEvalInfo const *ei)
1784 return ei->func_call->argc;
1787 GnmDependentFlags
1788 gnm_func_link_dep (GnmFunc *func, GnmFuncEvalInfo *ei, gboolean qlink)
1790 int res = DEPENDENT_NO_FLAG;
1791 g_signal_emit (func, signals[SIG_LINK_DEP], 0, ei, qlink, &res);
1792 return (GnmDependentFlags)res;
1796 * gnm_func_derivative:
1797 * @func: #GnmFunc
1798 * @expr: expression that calls @func
1799 * @ep: position of @expr
1800 * @info: #GnmExprDeriv
1802 * Returns: (transfer full) (nullable): the derivative of @expr with respect to
1803 * @info.
1805 GnmExpr const *
1806 gnm_func_derivative (GnmFunc *func, GnmExpr const *expr, GnmEvalPos const *ep,
1807 GnmExprDeriv *info)
1809 GnmExpr *res = NULL;
1811 g_return_val_if_fail (GNM_IS_FUNC (func), NULL);
1812 g_signal_emit (func, signals[SIG_DERIVATIVE], 0, expr, ep, info, &res);
1813 return res;
1816 /* ------------------------------------------------------------------------- */
1818 static GObjectClass *parent_class;
1820 typedef struct {
1821 GObjectClass parent;
1823 void (*load_stub) (GnmFunc *func);
1824 int (*link_dep) (GnmFunc *func, GnmFuncEvalInfo *ei, gboolean qlink);
1825 GnmExpr* (*derivative) (GnmFunc *func, GnmExpr const *expr, GnmEvalPos *ep, GnmExprDeriv *info);
1826 } GnmFuncClass;
1828 static void
1829 gnm_func_finalize (GObject *obj)
1831 GnmFunc *func = GNM_FUNC (obj);
1833 g_free (func->arg_types);
1835 g_free ((char *)func->name);
1837 go_string_unref (func->tdomain);
1839 parent_class->finalize (obj);
1842 static void
1843 gnm_func_real_dispose (GObject *obj)
1845 GnmFunc *func = GNM_FUNC (obj);
1847 if (func->usage_count != 0) {
1848 g_printerr ("Function %s still has a usage count of %d\n",
1849 func->name, func->usage_count);
1852 gnm_func_set_stub (func);
1854 if (func->fn_group) {
1855 gnm_func_group_remove_func (func->fn_group, func);
1856 func->fn_group = NULL;
1859 gnm_func_set_localized_name (func, NULL);
1861 if (!(func->flags & GNM_FUNC_IS_WORKBOOK_LOCAL)) {
1862 g_hash_table_remove (functions_by_name, func->name);
1865 parent_class->dispose (obj);
1868 void
1869 gnm_func_dispose (GnmFunc *func)
1871 g_object_run_dispose (G_OBJECT (func));
1874 static void
1875 gnm_func_get_property (GObject *object, guint property_id,
1876 GValue *value, GParamSpec *pspec)
1878 GnmFunc *func = (GnmFunc *)object;
1880 switch (property_id) {
1881 case PROP_NAME:
1882 g_value_set_string (value, func->name);
1883 break;
1884 case PROP_TRANSLATION_DOMAIN:
1885 g_value_set_string (value, func->tdomain->str);
1886 break;
1887 case PROP_IN_USE:
1888 g_value_set_boolean (value, func->usage_count > 0);
1889 break;
1890 default:
1891 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1892 break;
1896 static void
1897 gnm_func_set_property (GObject *object, guint property_id,
1898 GValue const *value, GParamSpec *pspec)
1900 GnmFunc *func = (GnmFunc *)object;
1902 switch (property_id) {
1903 case PROP_NAME:
1904 func->name = g_value_dup_string (value);
1905 break;
1906 case PROP_TRANSLATION_DOMAIN:
1907 gnm_func_set_translation_domain (func,
1908 g_value_get_string (value));
1909 break;
1910 default:
1911 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1912 break;
1916 static void
1917 gnm_func_init (GnmFunc *func)
1919 func->tdomain = go_string_new (GETTEXT_PACKAGE);
1920 func->flags = GNM_FUNC_SIMPLE;
1921 func->impl_status = GNM_FUNC_IMPL_STATUS_UNIMPLEMENTED;
1922 func->test_status = GNM_FUNC_TEST_STATUS_UNKNOWN;
1925 static void
1926 gnm_func_class_init (GObjectClass *gobject_class)
1928 parent_class = g_type_class_peek_parent (gobject_class);
1930 gobject_class->finalize = gnm_func_finalize;
1931 gobject_class->dispose = gnm_func_real_dispose;
1932 gobject_class->get_property = gnm_func_get_property;
1933 gobject_class->set_property = gnm_func_set_property;
1935 g_object_class_install_property (gobject_class, PROP_NAME,
1936 g_param_spec_string ("name",
1937 P_("Name"),
1938 P_("The name of the function."),
1939 NULL,
1940 GSF_PARAM_STATIC |
1941 G_PARAM_READWRITE |
1942 G_PARAM_CONSTRUCT_ONLY));
1944 g_object_class_install_property (gobject_class, PROP_TRANSLATION_DOMAIN,
1945 g_param_spec_string ("translation-domain",
1946 P_("Translation Domain"),
1947 P_("The translation domain for help texts"),
1948 NULL,
1949 GSF_PARAM_STATIC |
1950 G_PARAM_READWRITE));
1952 g_object_class_install_property (gobject_class, PROP_IN_USE,
1953 g_param_spec_boolean ("in-use",
1954 P_("In use"),
1955 P_("Is function being used?"),
1956 FALSE,
1957 GSF_PARAM_STATIC |
1958 G_PARAM_READABLE));
1961 * GnmFunc::load-stub:
1962 * @func: the #GnmFunc that needs to be loaded
1964 * Signals that @func, which is a stub, needs to be loaded now. Anyone
1965 * creating a stub function should arrange for this signal to be caught
1966 * and the function to be properly instantiated.
1968 signals[SIG_LOAD_STUB] = g_signal_new
1969 ("load-stub",
1970 GNM_FUNC_TYPE,
1971 G_SIGNAL_RUN_LAST,
1972 G_STRUCT_OFFSET (GnmFuncClass, load_stub),
1973 NULL, NULL,
1974 g_cclosure_marshal_VOID__VOID,
1975 G_TYPE_NONE, 0);
1978 * GnmFunc::link-dep:
1979 * @func: the #GnmFunc that is being linked or unlinked
1980 * @ei: #GnmFuncEvalInfo for the call initiating the link or unlink.
1981 * @qlink: %TRUE for link, %FALSE for unlink
1983 * Signals that an expressions that is a call to @func is being linked
1984 * or unlinked. Most functions do not need this.
1986 * Returns: A #GnmDependentFlags allowing arguments not be be linked if
1987 * that is appropriate.
1989 signals[SIG_LINK_DEP] = g_signal_new
1990 ("link-dep",
1991 GNM_FUNC_TYPE,
1992 G_SIGNAL_RUN_LAST,
1993 G_STRUCT_OFFSET (GnmFuncClass, link_dep),
1994 NULL, NULL,
1995 gnm__INT__POINTER_BOOLEAN,
1996 // GnmDependentFlags ... GnmFuncEvalInfo
1997 G_TYPE_INT, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN);
2000 * GnmFunc::derivative:
2001 * @func: #GnmFunc
2002 * @expr: #GnmExpr for the call for which the derivative is sought
2003 * @ep: position f @expr
2004 * @info: #GnmExprDeriv telling which derivative is sought
2006 * Signals that a function call's derivative should be calculatted
2008 * Returns: (transfer full) (nullable): #GnmExpr representing the
2009 * derivative, %NULL for error.
2011 signals[SIG_DERIVATIVE] = g_signal_new
2012 ("derivative",
2013 GNM_FUNC_TYPE,
2014 G_SIGNAL_RUN_LAST,
2015 G_STRUCT_OFFSET (GnmFuncClass, derivative),
2016 NULL, NULL,
2017 gnm__BOXED__BOXED_BOXED_BOXED,
2018 gnm_expr_get_type(),
2019 3, gnm_expr_get_type(), gnm_eval_pos_get_type(), gnm_expr_deriv_info_get_type());
2022 GSF_CLASS (GnmFunc, gnm_func,
2023 gnm_func_class_init, gnm_func_init, G_TYPE_OBJECT)