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