func.h 7.92 KB
Newer Older
1 2 3
#ifndef GNUMERIC_FUNC_H
#define GNUMERIC_FUNC_H

4
#include "gnumeric.h"
5
#include "dependent.h"
6

Jody Goldberg's avatar
Jody Goldberg committed
7 8
/* Setup of the symbol table */
void functions_init     (void);
9 10
void functions_shutdown (void);

Jody Goldberg's avatar
Jody Goldberg committed
11
/* Used to build manual */
12
void function_dump_defs (char const *filename, gboolean def_or_state);
13

Jody Goldberg's avatar
Jody Goldberg committed
14
/******************************************************************************/
15
/* Function group support */
16

17 18
typedef struct _GnmFuncGroup GnmFuncGroup;
struct _GnmFuncGroup {
19 20
	String *internal_name, *display_name;
	gboolean has_translation;
21 22
	GList *functions;
};
23

24 25 26 27
GnmFuncGroup *gnm_func_group_get_nth (gint n);
GnmFuncGroup *gnm_func_group_fetch     		    (char const *name);
GnmFuncGroup *gnm_func_group_fetch_with_translation (char const *name,
						     char const *translation);
Jody Goldberg's avatar
Jody Goldberg committed
28 29

/******************************************************************************/
30

31
/*
32
 * Function registration routines
Jody Goldberg's avatar
Jody Goldberg committed
33
 *
34 35 36 37 38 39 40 41 42 43 44 45
 * Functions come in two fashions:  Those that only deal with
 * very specific data types and a constant number of arguments,
 * and those who don't.
 *
 * The former kind of functions receives a precomputed array of
 * Value pointers.
 *
 * The latter sort of functions receives the plain ExprNodes and
 * it is up to that routine to do the value computations and range
 * processing.
 */

46 47
/**
 *  Argument tokens passed in 'args'
Jody Goldberg's avatar
Jody Goldberg committed
48 49 50 51 52 53 54 55 56 57 58 59 60
 *
 * With intersection and iteration support
 * 	f : float 		(no errors, string conversion attempted)
 * 	b : boolean		(identical to f, Do we need this ?)
 * 	s : string		(no errors)
 * 	S : 'scalar': any non-error value
 * 	E : scalar including errors
 * Without intersection or iteration support
 *	r : cell range	content is _NOT_ guaranteed to have been evaluated yet
 *	A : area	either range or array (as above)
 *	a : array
 *	? : anything
 *
61 62 63
 *  For optional arguments do:
 * "ff|ss" where the strings are optional
 **/
Jody Goldberg's avatar
Jody Goldberg committed
64

65
typedef enum {
66 67 68 69 70 71 72 73
	GNM_FUNC_TYPE_ARGS,	/* Takes unevaulated expers directly */
	GNM_FUNC_TYPE_NODES,	/* arguments get marshalled by type */

	/* implementation has not been loaded yet, but we know where it is */
	GNM_FUNC_TYPE_STUB
} GnmFuncType;

typedef enum {
74
	GNM_FUNC_SIMPLE			= 0,
75 76
	GNM_FUNC_VOLATILE		= 0x01, /* eg now(), today() */
	GNM_FUNC_RETURNS_NON_SCALAR	= 0x02, /* eg transpose(), mmult() */
77 78 79 80 81 82

	/* For functions that are not exactly compatible with various import
	 * formats.  We need to recalc their results to avoid changing values
	 * unexpectedly when we recalc later.  This probably needs to be done
	 * on a per import format basis.  It may not belong here.
	 */
83
	GNM_FUNC_RECALC_ONLOAD 		= 0x04,
84

85 86 87
	/* an unknown function that will hopefully be defined later */
	GNM_FUNC_IS_PLACEHOLDER		= 0x08
} GnmFuncFlags;
88

Jody Goldberg's avatar
Jody Goldberg committed
89 90 91 92
/* I do not like this it is going to be different for different apps
 * probably want to split it into bit file with our notion of its state, and 2
 * bits of state per import format.
 */
93 94 95 96 97 98 99 100 101 102
typedef enum {
	GNM_FUNC_IMPL_STATUS_EXISTS = 0,
	GNM_FUNC_IMPL_STATUS_UNIMPLEMENTED,
	GNM_FUNC_IMPL_STATUS_SUBSET,
	GNM_FUNC_IMPL_STATUS_COMPLETE,
	GNM_FUNC_IMPL_STATUS_SUPERSET,
	GNM_FUNC_IMPL_STATUS_SUBSET_WITH_EXTENSIONS,
	GNM_FUNC_IMPL_STATUS_UNDER_DEVELOPMENT,
	GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC,
} GnmFuncImplStatus;
103

104 105
typedef enum {
	GNM_FUNC_TEST_STATUS_UNKNOWN = 0,
Jody Goldberg's avatar
Jody Goldberg committed
106
	GNM_FUNC_TEST_STATUS_NO_TESTSUITE,
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	GNM_FUNC_TEST_STATUS_BASIC,
	GNM_FUNC_TEST_STATUS_EXHAUSTIVE,
	GNM_FUNC_TEST_STATUS_UNDER_DEVELOPMENT
} GnmFuncTestStatus;
typedef struct _GnmFuncDescriptor GnmFuncDescriptor;

typedef Value 		*(*GnmFuncArgs)	  (FunctionEvalInfo *ei, Value **args);
typedef Value 		*(*GnmFuncNodes)  (FunctionEvalInfo *ei, GnmExprList *l);
typedef DependentFlags	 (*GnmFuncLink)	  (FunctionEvalInfo *ei);
typedef void		 (*GnmFuncUnlink) (FunctionEvalInfo *ei);

typedef void	 (*GnmFuncRefNotify) (GnmFunc *f, int refcount);
typedef gboolean (*GnmFuncLoadDesc)  (GnmFunc const *f, GnmFuncDescriptor *fd);

struct _GnmFuncDescriptor {
	char const *name;
	char const *arg_spec;
	char const *arg_names;
	char const **help;	/* this is easier for compilers */
	GnmFuncArgs	  fn_args;
	GnmFuncNodes	  fn_nodes;
	GnmFuncLink	  linker;
	GnmFuncUnlink	  unlinker;
	GnmFuncRefNotify  ref_notify;
	GnmFuncFlags	  flags;
	GnmFuncImplStatus impl_status;
	GnmFuncTestStatus test_status;
134 135
};

136 137 138 139 140
struct _GnmFunc {
	char const *name;
	char const *arg_names;
	char const *help;
	GnmFuncType fn_type;
141
	union {
142
		GnmFuncNodes nodes;
143 144
		struct {
			char const *arg_spec;
145
			GnmFuncArgs  func;
146 147 148
			int min_args, max_args;
			char *arg_types;
		} args;
149
		GnmFuncLoadDesc	load_desc;
150
	} fn;
151 152 153 154 155 156 157 158 159 160
	GnmFuncGroup		*fn_group; /* most recent it was assigned to */
	GnmFuncLink		 linker;
	GnmFuncUnlink		 unlinker;
	GnmFuncRefNotify	 ref_notify;
	GnmFuncImplStatus	 impl_status;
	GnmFuncTestStatus	 test_status;
	GnmFuncFlags		 flags;

	gint         		 ref_count;
	gpointer     		 user_data;
161 162
};

163 164 165 166
struct _FunctionEvalInfo {
	EvalPos const *pos;
	GnmExprFunction const *func_call;
};
Jon Kåre Hellan's avatar
Jon Kåre Hellan committed
167

168 169 170 171 172 173 174
void	    gnm_func_ref	     (GnmFunc *func);
void	    gnm_func_unref	     (GnmFunc *func);
void	    gnm_func_load_stub	     (GnmFunc *fn_def);
char const *gnm_func_get_name	     (GnmFunc const *fn_def);
gpointer    gnm_func_get_user_data   (GnmFunc const *func);
void        gnm_func_set_user_data   (GnmFunc *func, gpointer user_data);
GnmFunc	   *gnm_func_lookup	     (char const *name, Workbook const *scope);
175
GnmFunc    *gnm_func_add	     (GnmFuncGroup *group,
176
				      GnmFuncDescriptor const *descriptor);
177
GnmFunc    *gnm_func_add_stub	     (GnmFuncGroup *group,
178 179 180 181 182 183 184
				      char const *name,
				      GnmFuncLoadDesc  load_desc,
				      GnmFuncRefNotify opt_ref_notify);
GnmFunc    *gnm_func_add_placeholder (char const *name, char const *type,
				      gboolean copy_name);

/* TODO */
185
void                function_remove     (GnmFuncGroup *group,
186 187 188
                                         char const *name);

void        function_def_count_args    (GnmFunc const *fn_def,
189
                                        gint *min, int *max);
190
char        function_def_get_arg_type  (GnmFunc const *fn_def,
191
                                        gint arg_idx);
192
char const *function_def_get_arg_type_string  (GnmFunc const *fn_def,
193
                                        gint arg_idx);
194
char       *function_def_get_arg_name  (GnmFunc const *fn_def,
195
                                        gint arg_idx);
Michael Meeks's avatar
Michael Meeks committed
196

197
/*************************************************************************/
198

199 200
Value *function_call_with_list	     (FunctionEvalInfo *ei, GnmExprList *args,
				      GnmExprEvalFlags flags);
201
Value *function_call_with_values     (EvalPos const *ep, char const *name,
202
                                      gint argc, Value *values []);
203
Value *function_def_call_with_values (EvalPos const *ep, GnmFunc const *fn,
204
                                      gint argc, Value *values []);
Jody Goldberg's avatar
Jody Goldberg committed
205 206

/* Utilies to interate through ranges and argument lists */
207
typedef Value * (*FunctionIterateCB) (EvalPos const *ep,
208
                                      Value *value, gpointer user_data);
209
Value *function_iterate_argument_values	(EvalPos const	   *ep,
210 211
                                         FunctionIterateCB  cb,
                                         gpointer           user_data,
212
                                         GnmExprList       *expr_node_list,
213
                                         gboolean           strict,
214
                                         CellIterFlags	    iter_flags);
215
Value *function_iterate_do_value	(EvalPos const      *ep,
216 217 218 219 220
					 FunctionIterateCB   cb,
					 gpointer            user_data,
					 Value              *value,
					 gboolean            strict,
					 CellIterFlags	     iter_flags);
Jody Goldberg's avatar
Jody Goldberg committed
221 222 223 224

/******************************************************************************/

/* Detailed function help */
Michael Meeks's avatar
Michael Meeks committed
225
typedef struct {
226
	GPtrArray *sections;
227
	gboolean   help_is_localized;
228 229
	char     *help_copy;
	GnmFunc const *fndef;
230
} TokenizedHelp;
Michael Meeks's avatar
Michael Meeks committed
231

232
TokenizedHelp *tokenized_help_new     (GnmFunc const *fn_def);
Jody Goldberg's avatar
Jody Goldberg committed
233
char const    *tokenized_help_find    (TokenizedHelp *tok, char const *token);
234
void           tokenized_help_destroy (TokenizedHelp *tok);
235

236
#endif /* GNUMERIC_FUNC_H */