Use application properties instead of ugly dual-use global variable
[gnumeric.git] / src / expr.h
blobaa90c75df9d8e6d46365a1306b703f5f38469ed9
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 #ifndef _GNM_EXPR_H_
3 # define _GNM_EXPR_H_
5 G_BEGIN_DECLS
7 #include "gnumeric.h"
8 #include "position.h"
10 /* Warning: if you add something here, see do_expr_as_string ! */
11 /* Warning: if you add something here, see ms-formula-write.c ! */
12 typedef enum {
13 GNM_EXPR_OP_PAREN, /* Parentheses for clarity */
14 GNM_EXPR_OP_EQUAL, /* Compare value equal */
15 GNM_EXPR_OP_GT, /* Compare value greather than */
16 GNM_EXPR_OP_LT, /* Compare value less than */
17 GNM_EXPR_OP_GTE, /* Compare value greather or equal than */
18 GNM_EXPR_OP_LTE, /* Compare value less or equal than */
19 GNM_EXPR_OP_NOT_EQUAL, /* Compare for non equivalence */
21 GNM_EXPR_OP_ADD, /* Add */
22 GNM_EXPR_OP_SUB, /* Subtract */
23 GNM_EXPR_OP_MULT, /* Multiply */
24 GNM_EXPR_OP_DIV, /* Divide */
25 GNM_EXPR_OP_EXP, /* Exponentiate */
26 GNM_EXPR_OP_CAT, /* String concatenation */
28 GNM_EXPR_OP_FUNCALL, /* Function call invocation */
30 GNM_EXPR_OP_NAME, /* Name reference */
32 GNM_EXPR_OP_CONSTANT, /* Constant value */
33 GNM_EXPR_OP_CELLREF, /* Cell content lookup (variable) */
34 GNM_EXPR_OP_UNARY_NEG, /* Sign inversion */
35 GNM_EXPR_OP_UNARY_PLUS, /* Mark as positive */
36 GNM_EXPR_OP_PERCENTAGE, /* Percentage (value/100) */
37 GNM_EXPR_OP_ARRAY_CORNER,/* Top Corner of an array */
38 GNM_EXPR_OP_ARRAY_ELEM, /* General Array element */
39 GNM_EXPR_OP_SET, /* A set of expressions */
40 GNM_EXPR_OP_RANGE_CTOR, /* A constructed range eg A1:index(1,2) */
41 GNM_EXPR_OP_INTERSECT /* The intersection of multiple ranges */
42 } GnmExprOp;
44 /* Shorthands for case statements. Easy to read, easy to maintain. */
45 #define GNM_EXPR_OP_ANY_BINARY GNM_EXPR_OP_EQUAL: case GNM_EXPR_OP_GT: case GNM_EXPR_OP_LT: case GNM_EXPR_OP_GTE: \
46 case GNM_EXPR_OP_LTE: case GNM_EXPR_OP_NOT_EQUAL: \
47 case GNM_EXPR_OP_ADD: case GNM_EXPR_OP_SUB: case GNM_EXPR_OP_MULT: case GNM_EXPR_OP_DIV: \
48 case GNM_EXPR_OP_EXP: case GNM_EXPR_OP_CAT
49 #define GNM_EXPR_OP_ANY_UNARY GNM_EXPR_OP_PAREN: case GNM_EXPR_OP_UNARY_NEG: case GNM_EXPR_OP_UNARY_PLUS: case GNM_EXPR_OP_PERCENTAGE
51 GType gnm_expr_get_type (void);
52 GType gnm_expr_array_corner_get_type (void); /* boxed type */
53 GnmExpr const *gnm_expr_new_constant (GnmValue *v);
54 GnmExpr const *gnm_expr_new_unary (GnmExprOp op, GnmExpr const *e);
55 GnmExpr const *gnm_expr_new_binary (GnmExpr const *l, GnmExprOp op,
56 GnmExpr const *r);
57 GnmExpr const *gnm_expr_new_funcall (GnmFunc *func,
58 GnmExprList *args);
59 GnmExpr const *gnm_expr_new_funcall1 (GnmFunc *func,
60 GnmExpr const *arg0);
61 GnmExpr const *gnm_expr_new_funcall2 (GnmFunc *func,
62 GnmExpr const *arg0,
63 GnmExpr const *arg1);
64 GnmExpr const *gnm_expr_new_funcall3 (GnmFunc *func,
65 GnmExpr const *arg0,
66 GnmExpr const *arg1,
67 GnmExpr const *arg2);
68 GnmExpr const *gnm_expr_new_funcall4 (GnmFunc *func,
69 GnmExpr const *arg0,
70 GnmExpr const *arg1,
71 GnmExpr const *arg2,
72 GnmExpr const *arg3);
73 GnmExpr const *gnm_expr_new_funcall5 (GnmFunc *func,
74 GnmExpr const *arg0,
75 GnmExpr const *arg1,
76 GnmExpr const *arg2,
77 GnmExpr const *arg3,
78 GnmExpr const *arg4);
79 GnmExpr const *gnm_expr_new_name (GnmNamedExpr *name,
80 Sheet *sheet_scope, Workbook *wb_scope);
81 GnmExpr const *gnm_expr_new_cellref (GnmCellRef const *cr);
82 GnmExpr const *gnm_expr_new_set (GnmExprList *args);
83 GnmExpr const *gnm_expr_new_range_ctor (GnmExpr const *l, GnmExpr const *r);
85 GnmValue *gnm_expr_get_range (GnmExpr const *expr);
86 GnmFunc *gnm_expr_get_func_def (GnmExpr const *expr);
87 GnmExpr const *gnm_expr_get_func_arg (GnmExpr const *expr, int i);
89 void gnm_expr_free (GnmExpr const *expr);
90 GnmExpr const *gnm_expr_copy (GnmExpr const *expr);
91 gboolean gnm_expr_equal (GnmExpr const *a, GnmExpr const *b);
92 gboolean gnm_expr_is_rangeref (GnmExpr const *expr);
93 gboolean gnm_expr_is_data_table (GnmExpr const *expr,
94 GnmCellPos *c_in, GnmCellPos *r_in);
95 gboolean gnm_expr_is_empty (GnmExpr const *expr);
97 GnmValue const *gnm_expr_get_constant (GnmExpr const *expr);
99 GnmNamedExpr const *gnm_expr_get_name (GnmExpr const *expr);
101 GnmCellRef const*gnm_expr_get_cellref (GnmExpr const *expr);
103 void gnm_expr_as_gstring (GnmExpr const *expr,
104 GnmConventionsOut *out);
105 char *gnm_expr_as_string (GnmExpr const *expr, GnmParsePos const *pp,
106 GnmConventions const *convs);
107 void gnm_expr_list_as_string (int argc, GnmExprConstPtr const *argv,
108 GnmConventionsOut *out);
109 gboolean gnm_expr_contains_subtotal (GnmExpr const *expr);
111 GnmValue *gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
112 GnmExprEvalFlags flags);
114 GnmExpr const *gnm_expr_simplify_if (GnmExpr const *expr);
116 typedef struct GnmExprWalk_ {
117 /* User data */
118 gpointer user;
120 /* Flags the walker callback can use to signal the engine. */
121 gboolean stop;
123 /* Internal flags. */
124 guint flags;
125 } GnmExprWalk;
126 typedef GnmExpr const * (*GnmExprWalkerFunc) (GnmExpr const *expr, GnmExprWalk *data);
127 GnmExpr const *gnm_expr_walk (GnmExpr const *expr, GnmExprWalkerFunc walker, gpointer user);
129 /*****************************************************************************/
131 #define gnm_expr_list_append(l,e) g_slist_append ((l), (gpointer)(e))
132 #define gnm_expr_list_prepend(l,e) g_slist_prepend ((l), (gpointer)(e))
133 #define gnm_expr_list_length(l) g_slist_length((GSList *)(l)) /* const cast */
134 #define gnm_expr_list_free g_slist_free
135 void gnm_expr_list_unref (GnmExprList *list);
136 GnmExprList *gnm_expr_list_copy (GnmExprList *list);
138 /*****************************************************************************/
140 #define GNM_EXPR_TOP_MAGIC 0x42
141 #define GNM_IS_EXPR_TOP(et) ((et) && (et)->magic == GNM_EXPR_TOP_MAGIC)
143 struct _GnmExprTop {
144 unsigned magic : 8;
145 unsigned hash : 24; /* Zero meaning not yet computed. */
146 guint32 refcount;
147 GnmExpr const *expr;
150 GnmExprTop const *gnm_expr_top_new (GnmExpr const *e);
151 GnmExprTop const *gnm_expr_top_new_constant (GnmValue *v);
152 GnmExprTop const *gnm_expr_top_new_array_corner (int cols, int rows, GnmExpr const *expr);
153 GnmExprTop const *gnm_expr_top_new_array_elem (int x, int y);
155 GType gnm_expr_top_get_type (void);
156 GnmExprTop const *gnm_expr_top_ref (GnmExprTop const *texpr);
157 void gnm_expr_top_unref (GnmExprTop const *texpr);
158 gboolean gnm_expr_top_equal (GnmExprTop const *te1, GnmExprTop const *te2);
159 guint gnm_expr_top_hash (GnmExprTop const *texpr);
160 gboolean gnm_expr_top_is_shared (GnmExprTop const *texpr);
161 gboolean gnm_expr_top_is_err (GnmExprTop const *texpr, GnmStdError e);
162 gboolean gnm_expr_top_is_rangeref (GnmExprTop const *texpr);
163 gboolean gnm_expr_top_is_array_elem (GnmExprTop const *texpr, int *x, int *y);
164 gboolean gnm_expr_top_is_array_corner (GnmExprTop const *texpr);
165 gboolean gnm_expr_top_is_array (GnmExprTop const *texpr);
166 void gnm_expr_top_get_array_size (GnmExprTop const *texpr, int *cols, int *rows);
167 GnmValue *gnm_expr_top_get_array_value (GnmExprTop const *texpr);
168 GnmExpr const *gnm_expr_top_get_array_expr (GnmExprTop const *texpr);
169 GnmValue *gnm_expr_top_get_range (GnmExprTop const *texpr);
170 GSList *gnm_expr_top_get_ranges (GnmExprTop const *texpr);
171 GnmValue const *gnm_expr_top_get_constant (GnmExprTop const *texpr);
172 GnmCellRef const*gnm_expr_top_get_cellref (GnmExprTop const *texpr);
173 void gnm_expr_top_get_boundingbox (GnmExprTop const *texpr,
174 Sheet const *sheet,
175 GnmRange *bound);
176 gboolean gnm_expr_top_contains_subtotal (GnmExprTop const *texpr);
177 gboolean gnm_expr_top_is_volatile (GnmExprTop const *texpr);
178 GSList *gnm_expr_top_referenced_sheets (GnmExprTop const *texpr);
179 GnmExpr const *gnm_expr_top_first_funcall (GnmExprTop const *texpr);
180 GnmExprTop const *gnm_expr_top_transpose (GnmExprTop const *texpr);
182 struct _GnmExprRelocateInfo {
183 GnmParsePos pos;
185 GnmRange origin; /* References to cells in origin_sheet!range */
186 Sheet *origin_sheet; /* should to adjusted */
187 Sheet *target_sheet; /* to point at this sheet */
188 int col_offset, row_offset; /* and offset by this amount */
189 enum {
190 /* invalidate references to any sheets with
191 * Sheet::being_invalidated == TRUE */
192 GNM_EXPR_RELOCATE_INVALIDATE_SHEET,
193 GNM_EXPR_RELOCATE_MOVE_RANGE,
194 GNM_EXPR_RELOCATE_COLS, /* ins/del col */
195 GNM_EXPR_RELOCATE_ROWS /* ins/del row */
196 } reloc_type;
198 /* Valid for COLS/ROWS only. Assumed by MOVE_RANGE. If TRUE,
199 ranges ending at the edge of the sheet will keep the end
200 there. */
201 gboolean sticky_end;
204 GnmExprTop const *gnm_expr_top_relocate (GnmExprTop const *texpr,
205 GnmExprRelocateInfo const *rinfo,
206 gboolean include_rel);
207 GnmExprTop const * gnm_expr_top_relocate_sheet (GnmExprTop const *texpr,
208 Sheet const *src,
209 Sheet const *dst);
211 GnmValue *gnm_expr_top_eval (GnmExprTop const *texpr,
212 GnmEvalPos const *pos,
213 GnmExprEvalFlags flags);
214 char *gnm_expr_top_as_string (GnmExprTop const *texpr,
215 GnmParsePos const *pp,
216 GnmConventions const *convs);
217 void gnm_expr_top_as_gstring (GnmExprTop const *texpr,
218 GnmConventionsOut *out);
220 /*****************************************************************************/
222 GType gnm_expr_sharer_get_type (void);
223 GnmExprSharer * gnm_expr_sharer_new (void);
224 void gnm_expr_sharer_destroy (GnmExprSharer *es);
225 GnmExprTop const *gnm_expr_sharer_share (GnmExprSharer *es, GnmExprTop const *texpr);
226 void gnm_expr_sharer_report (GnmExprSharer *es);
228 /*****************************************************************************/
230 void _gnm_expr_init (void);
231 void _gnm_expr_shutdown (void);
233 G_END_DECLS
235 #endif /* _GNM_EXPR_H_ */