1 #ifndef _GNM_FUNC_H_
2 # define _GNM_FUNC_H_
3 
4 #include <gnumeric.h>
5 #include <dependent.h>
6 
7 G_BEGIN_DECLS
8 
9 /* Setup of the symbol table */
10 void gnm_func_init_     (void);
11 void gnm_func_shutdown_ (void);
12 
13 GPtrArray *gnm_func_enumerate (void);
14 
15 /******************************************************************************/
16 /* Function group support */
17 
18 struct _GnmFuncGroup {
19 	GOString *internal_name, *display_name;
20 	gboolean has_translation;
21 	GSList *functions;
22 	unsigned ref_count; /* boxed type */
23 };
24 
25 GType gnm_func_group_get_type (void); /* boxed type */
26 GnmFuncGroup *gnm_func_group_get_nth (gint n);
27 GnmFuncGroup *gnm_func_group_fetch (char const *name,
28 				    char const *translation);
29 
30 /******************************************************************************/
31 
32 /*
33  * Function registration routines
34  *
35  * Functions come in two fashions:  Those that only deal with
36  * very specific data types and a constant number of arguments,
37  * and those who don't.
38  *
39  * The former kind of functions receives a precomputed array of
40  * GnmValue pointers.
41  *
42  * The latter sort of functions receives the plain ExprNodes and
43  * it is up to that routine to do the value computations and range
44  * processing.
45  */
46 
47 /*
48  *  Argument tokens passed in 'args'
49  *
50  * With intersection and iteration support
51  *	f : floating point	(no errors, string conversion attempted)
52  *	b : boolean		(identical to f, Do we need this ?)
53  *	s : string		(no errors)
54  *	S : 'scalar': any non-error value
55  *	E : scalar including errors
56  * Without intersection or iteration support
57  *	r : cell range	content is _NOT_ guaranteed to have been evaluated yet
58  *	A : area	either range or array (as above)
59  *	? : anything
60  *
61  *  For optional arguments do:
62  * "ff|ss" where the strings are optional
63  */
64 
65 typedef enum {
66 	GNM_FUNC_TYPE_ARGS,	/* Arguments get marshalled by type */
67 	GNM_FUNC_TYPE_NODES,	/* Takes unevaulated expers directly */
68 
69 	/* implementation has not been loaded yet, but we know where it is */
70 	GNM_FUNC_TYPE_STUB
71 } GnmFuncType;
72 
73 typedef enum {
74 	GNM_FUNC_SIMPLE			= 0,
75 	GNM_FUNC_VOLATILE		= 1 << 0, /* eg now(), today() */
76 	GNM_FUNC_RETURNS_NON_SCALAR	= 1 << 1, /* eg transpose(), mmult() */
77 
78 	/* an unknown function that will hopefully be defined later */
79 	GNM_FUNC_IS_PLACEHOLDER		= 1 << 3,
80 	GNM_FUNC_IS_WORKBOOK_LOCAL	= 1 << 5,
81 	GNM_FUNC_INTERNAL		= 1 << 6,
82 
83 	GNM_FUNC_AUTO_UNKNOWN           = 0 << 8,
84 	GNM_FUNC_AUTO_MONETARY          = 1 << 8,  /* Like PV */
85 	GNM_FUNC_AUTO_DATE              = 2 << 8,  /* Like DATE */
86 	GNM_FUNC_AUTO_TIME              = 3 << 8,  /* Like TIME */
87 	GNM_FUNC_AUTO_PERCENT           = 4 << 8,  /* Like IRR */
88 	GNM_FUNC_AUTO_FIRST             = 5 << 8,  /* Like SUM */
89 	GNM_FUNC_AUTO_SECOND            = 6 << 8,  /* Like IF */
90 	GNM_FUNC_AUTO_UNITLESS          = 7 << 8,  /* Like COUNT */
91 	GNM_FUNC_AUTO_MASK              = 7 << 8   /* The bits we use for AUTO.  */
92 } GnmFuncFlags;
93 
94 /* I do not like this.  It is going to be different for different apps probably
95  * want to split it into bit file with our notion of its state, and 2 bits of
96  * state per import format.
97  */
98 typedef enum {
99 	GNM_FUNC_IMPL_STATUS_EXISTS = 0,
100 	GNM_FUNC_IMPL_STATUS_UNIMPLEMENTED,
101 	GNM_FUNC_IMPL_STATUS_SUBSET,
102 	GNM_FUNC_IMPL_STATUS_COMPLETE,
103 	GNM_FUNC_IMPL_STATUS_SUPERSET,
104 	GNM_FUNC_IMPL_STATUS_SUBSET_WITH_EXTENSIONS,
105 	GNM_FUNC_IMPL_STATUS_UNDER_DEVELOPMENT,
106 	GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC
107 } GnmFuncImplStatus;
108 
109 typedef enum {
110 	GNM_FUNC_TEST_STATUS_UNKNOWN = 0,
111 	GNM_FUNC_TEST_STATUS_NO_TESTSUITE,
112 	GNM_FUNC_TEST_STATUS_BASIC,
113 	GNM_FUNC_TEST_STATUS_EXHAUSTIVE,
114 	GNM_FUNC_TEST_STATUS_UNDER_DEVELOPMENT
115 } GnmFuncTestStatus;
116 
117 typedef GnmValue	*(*GnmFuncArgs)	  (GnmFuncEvalInfo *ei, GnmValue const * const *args);
118 typedef GnmValue	*(*GnmFuncNodes)  (GnmFuncEvalInfo *ei,
119 					   int argc, GnmExprConstPtr const *argv);
120 
121 typedef enum {
122 	GNM_FUNC_HELP_END,		/* Format */
123 					/* ------ */
124 	GNM_FUNC_HELP_NAME,
125 	/* <NAME>:<1 SENTENCE DESCRIPTION> (translated) */
126 
127 	GNM_FUNC_HELP_ARG,
128 	/* <NAME>:<1 SENTENCE DESCRIPTION> (translated) */
129 
130 	GNM_FUNC_HELP_DESCRIPTION,
131 	/* <LONG DESCRIPTION (reference args using @{arg})> (translated) */
132 
133 	GNM_FUNC_HELP_NOTE,
134 	/* <SPECIAL CASES (reference args using @{arg})> (translated) */
135 
136 	GNM_FUNC_HELP_EXAMPLES,
137 	/*
138 	 * Either translated text, or a formula that is only marked for
139 	 * translation if it contains strings that need to be translated.
140 	 */
141 
142 	GNM_FUNC_HELP_SEEALSO,
143 	/* name,name,name ...	(not translated) */
144 
145 	GNM_FUNC_HELP_EXTREF,
146 	/*
147 	 * Link to external descriptions.  The following styles defined:
148 	 * wolfram:Sine.html
149 	 * wiki:en:Trigonometric_functions
150 	 */
151 
152 	GNM_FUNC_HELP_EXCEL,
153 	/* <SPECIAL NOTE RE EXCEL (reference args using @{arg})> (translated) */
154 
155 	GNM_FUNC_HELP_ODF
156 	/* <SPECIAL NOTE RE ODF (reference args using @{arg})> (translated) */
157 } GnmFuncHelpType;
158 
159 typedef struct {
160     GnmFuncHelpType	 type;
161     char const		*text;
162 } GnmFuncHelp;
163 
164 struct _GnmFuncDescriptor {
165 	char const *name;
166 	char const *arg_spec;
167 	GnmFuncHelp const *help;
168 	GnmFuncArgs	  fn_args;
169 	GnmFuncNodes	  fn_nodes;
170 	GnmFuncFlags	  flags;
171 	GnmFuncImplStatus impl_status;
172 	GnmFuncTestStatus test_status;
173 };
174 
175 struct GnmFunc_ {
176 	GObject	base;
177 
178 	char const *name;
179 	GnmFuncHelp *help;
180 
181 	/* <private> */
182 	GnmFuncType fn_type;
183 	GnmFuncGroup *fn_group;
184 	GnmFuncFlags flags;
185 	GnmFuncImplStatus impl_status;
186 	GnmFuncTestStatus test_status;
187 
188 	GOString *tdomain;
189 	char *localized_name;
190 
191 	gint usage_count;
192 
193 	// Meaningful for ARGS only
194 	char *arg_spec;
195 	GnmFuncArgs args_func;
196 
197 	// Meaningful for NODES only
198 	GnmFuncNodes nodes_func;
199 
200 	// Derived for quick access
201 	GPtrArray *arg_names;
202 	int min_args, max_args;
203 	char *arg_types;
204 	int help_count;
205 };
206 
207 #define GNM_FUNC_TYPE	(gnm_func_get_type ())
208 #define GNM_FUNC(obj)   (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNM_FUNC_TYPE, GnmFunc))
209 #define GNM_IS_FUNC(o)  (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_FUNC_TYPE))
210 
211 GType       gnm_func_get_type        (void);
212 void        gnm_func_load_if_stub    (GnmFunc *func);
213 void        gnm_func_dispose         (GnmFunc *func);
214 
215 GnmFunc	   *gnm_func_inc_usage	     (GnmFunc *func);
216 void	    gnm_func_dec_usage	     (GnmFunc *func);
217 gboolean    gnm_func_get_in_use      (GnmFunc *func);
218 
219 char const *gnm_func_get_translation_domain (GnmFunc const *func);
220 void        gnm_func_set_translation_domain (GnmFunc *func,
221 					     const char *tdomain);
222 char const *gnm_func_gettext         (GnmFunc const *func, const char *str);
223 
224 GnmFuncFlags gnm_func_get_flags      (GnmFunc const *func);
225 void        gnm_func_set_flags       (GnmFunc *func, GnmFuncFlags f);
226 
227 
228 GnmFuncImplStatus gnm_func_get_impl_status (GnmFunc const *func);
229 void        gnm_func_set_impl_status (GnmFunc *func, GnmFuncImplStatus st);
230 
231 GnmFuncTestStatus gnm_func_get_test_status (GnmFunc const *func);
232 void        gnm_func_set_test_status (GnmFunc *func, GnmFuncTestStatus st);
233 
234 GnmFuncGroup*gnm_func_get_function_group (GnmFunc *func);
235 void        gnm_func_set_function_group (GnmFunc *func, GnmFuncGroup *group);
236 
237 gboolean    gnm_func_is_varargs      (GnmFunc const *func);
238 gboolean    gnm_func_is_fixargs      (GnmFunc const *func);
239 
240 void        gnm_func_set_stub        (GnmFunc *func);
241 void        gnm_func_set_varargs     (GnmFunc *func, GnmFuncNodes fn,
242 				      const char *spec);
243 void        gnm_func_set_fixargs     (GnmFunc *func, GnmFuncArgs fn,
244 				      const char *spec);
245 
246 GnmFuncHelp const *gnm_func_get_help (GnmFunc const *func, int *n);
247 void        gnm_func_set_help (GnmFunc *func, GnmFuncHelp const *help, int n);
248 
249 GnmDependentFlags gnm_func_link_dep (GnmFunc *func, GnmFuncEvalInfo *ei, gboolean qlink);
250 
251 char const *gnm_func_get_name	     (GnmFunc const *func,
252 				      gboolean localized);
253 GnmFunc	   *gnm_func_lookup	     (char const *name, Workbook *scope);
254 GnmFunc    *gnm_func_lookup_localized (char const *name, Workbook *scope);
255 GSList	   *gnm_func_lookup_prefix   (char const *prefix, Workbook *scope,
256 				      gboolean trans);
257 GnmFunc    *gnm_func_add	     (GnmFuncGroup *group,
258 				      GnmFuncDescriptor const *descriptor,
259 				      const char *tdomain);
260 void        gnm_func_set_from_desc   (GnmFunc *func, GnmFuncDescriptor const *desc);
261 
262 GnmFunc    *gnm_func_add_placeholder (Workbook *scope,
263 				      char const *name,
264 				      char const *type);
265 GnmFunc    *gnm_func_add_placeholder_localized (char const *gname, char const *lname);
266 GnmFunc	   *gnm_func_lookup_or_add_placeholder (char const *name);
267 
268 /* TODO */
269 char const *gnm_func_get_description (GnmFunc const *func);
270 void        gnm_func_count_args    (GnmFunc const *func, gint *min, int *max);
271 char        gnm_func_get_arg_type  (GnmFunc const *func, gint arg_idx);
272 char const *gnm_func_get_arg_type_string  (GnmFunc const *func, gint arg_idx);
273 char       *gnm_func_get_arg_name  (GnmFunc const *func, guint arg_idx);
274 char const *gnm_func_get_arg_description (GnmFunc const *func, guint arg_idx);
275 char       *gnm_func_convert_markup_to_pango (char const *desc,
276 					      GtkWidget *target);
277 
278 /*************************************************************************/
279 
280 GnmValue *function_call_with_exprs	(GnmFuncEvalInfo *ei);
281 GnmValue *function_call_with_values     (GnmEvalPos const *ep, char const *name,
282 					 int argc, GnmValue const * const *values);
283 GnmValue *function_def_call_with_values (GnmEvalPos const *ep, GnmFunc const *fn,
284 					 int argc, GnmValue const * const *values);
285 
286 /* Utilies to interate through ranges and argument lists */
287 typedef GnmValue * (*FunctionIterateCB) (GnmEvalPos const *ep, GnmValue const *value,
288 					 gpointer user_data);
289 GnmValue *function_iterate_argument_values (GnmEvalPos const *ep,
290 					    FunctionIterateCB callback,
291 					    gpointer callback_closure,
292 					    int argc,
293 					    GnmExprConstPtr const *argv,
294 					    gboolean strict,
295 					    CellIterFlags iter_flags);
296 
297 /*************************************************************************/
298 
299 struct _GnmFuncEvalInfo {
300 	GnmEvalPos const *pos;
301 	GnmExprFunction const *func_call;
302 	GnmExprEvalFlags flags;
303 };
304 
305 GnmFunc const *gnm_eval_info_get_func (GnmFuncEvalInfo const *ei);
306 int gnm_eval_info_get_arg_count (GnmFuncEvalInfo const *ei);
307 
308 /*************************************************************************/
309 
310 GnmExpr const *gnm_func_derivative (GnmFunc *func,
311 				    GnmExpr const *expr, GnmEvalPos const *ep,
312 				    GnmExprDeriv *info);
313 
314 
315 G_END_DECLS
316 
317 #endif /* _GNM_FUNC_H_ */
318