goa: Add missing linker flag (for real).
[platform/upstream/evolution-data-server.git] / libedataserver / e-sexp.h
1 /*
2  * generic s-exp evaluator class
3 */
4
5 #if !defined (__LIBEDATASERVER_H_INSIDE__) && !defined (LIBEDATASERVER_COMPILATION)
6 #error "Only <libedataserver/libedataserver.h> should be included directly."
7 #endif
8
9 #ifndef _E_SEXP_H
10 #define _E_SEXP_H
11
12 #include <setjmp.h>
13 #include <time.h>
14 #include <glib.h>
15
16 /* Don't define E_SEXP_IS_G_OBJECT as this object is now used by camel */
17
18 #ifdef E_SEXP_IS_G_OBJECT
19 #include <glib-object.h>
20 #endif
21
22 #ifdef E_SEXP_IS_G_OBJECT
23 #define E_TYPE_SEXP            (e_sexp_get_type ())
24 #define E_SEXP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SEXP, ESExp))
25 #define E_SEXP_CLASS(cls)      (G_TYPE_CHECK_CLASS_CAST ((cls), E_TYPE_SEXP, ESExpClass))
26 #define IS_E_SEXP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SEXP))
27 #define IS_E_SEXP_CLASS(cls)   (G_TYPE_CHECK_CLASS_TYPE ((cls), E_TYPE_SEXP))
28 #define E_SEXP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_SEXP, ESExpClass))
29 #else
30 #define E_TYPE_SEXP            (0)
31 #define E_SEXP(obj)            ((struct _ESExp *) (obj))
32 #define E_SEXP_CLASS(cls)      ((struct _ESExpClass *) (cls))
33 #define IS_E_SEXP(obj)         (1)
34 #define IS_E_SEXP_CLASS(obj)   (1)
35 #define E_SEXP_GET_CLASS(obj)  (NULL)
36 #endif
37
38 G_BEGIN_DECLS
39
40 typedef struct _ESExp      ESExp;
41 typedef struct _ESExpClass ESExpClass;
42
43 typedef struct _ESExpSymbol ESExpSymbol;
44 typedef struct _ESExpResult ESExpResult;
45 typedef struct _ESExpTerm ESExpTerm;
46
47 typedef enum {
48         ESEXP_RES_ARRAY_PTR=0,  /* type is a ptrarray, what it points to is implementation dependant */
49         ESEXP_RES_INT,          /* type is a number */
50         ESEXP_RES_STRING,       /* type is a pointer to a single string */
51         ESEXP_RES_BOOL,         /* boolean type */
52         ESEXP_RES_TIME,         /* time_t type */
53         ESEXP_RES_UNDEFINED     /* unknown type */
54 } ESExpResultType;
55
56 struct _ESExpResult {
57         ESExpResultType type;
58         union {
59                 GPtrArray *ptrarray;
60                 gint number;
61                 gchar *string;
62                 gint boolean;
63                 time_t time;
64         } value;
65         gboolean time_generator;
66         time_t occuring_start;
67         time_t occuring_end;
68 };
69
70 typedef struct _ESExpResult *(ESExpFunc)(struct _ESExp *sexp, gint argc,
71                                          struct _ESExpResult **argv,
72                                          gpointer data);
73
74 typedef struct _ESExpResult *(ESExpIFunc)(struct _ESExp *sexp, gint argc,
75                                           struct _ESExpTerm **argv,
76                                           gpointer data);
77
78 typedef enum {
79         ESEXP_TERM_INT  = 0,    /* integer literal */
80         ESEXP_TERM_BOOL,        /* boolean literal */
81         ESEXP_TERM_STRING,      /* string literal */
82         ESEXP_TERM_TIME,        /* time_t literal (number of seconds past the epoch) */
83         ESEXP_TERM_FUNC,        /* normal function, arguments are evaluated before calling */
84         ESEXP_TERM_IFUNC,       /* immediate function, raw terms are arguments */
85         ESEXP_TERM_VAR          /* variable reference */
86 } ESExpTermType;
87
88 struct _ESExpSymbol {
89         gint type;              /* ESEXP_TERM_FUNC or ESEXP_TERM_VAR */
90         gchar *name;
91         gpointer data;
92         union {
93                 ESExpFunc *func;
94                 ESExpIFunc *ifunc;
95         } f;
96 };
97
98 struct _ESExpTerm {
99         ESExpTermType type;
100         union {
101                 gchar *string;
102                 gint number;
103                 gint boolean;
104                 time_t time;
105                 struct {
106                         struct _ESExpSymbol *sym;
107                         struct _ESExpTerm **terms;
108                         gint termcount;
109                 } func;
110                 struct _ESExpSymbol *var;
111         } value;
112 };
113
114 struct _ESExp {
115 #ifdef E_SEXP_IS_G_OBJECT
116         GObject parent_object;
117 #else
118         gint refcount;
119 #endif
120         GScanner *scanner;      /* for parsing text version */
121         ESExpTerm *tree;        /* root of expression tree */
122
123         /* private stuff */
124         jmp_buf failenv;
125         gchar *error;
126         GSList *operators;
127
128         /* TODO: may also need a pool allocator for term strings, so we dont lose them
129          * in error conditions? */
130         struct _EMemChunk *term_chunks;
131         struct _EMemChunk *result_chunks;
132 };
133
134 struct _ESExpClass {
135 #ifdef E_SEXP_IS_G_OBJECT
136         GObjectClass parent_class;
137 #else
138         gint dummy;
139 #endif
140 };
141
142 #ifdef E_SEXP_IS_G_OBJECT
143 GType           e_sexp_get_type         (void);
144 #endif
145 ESExp          *e_sexp_new              (void);
146 #ifdef E_SEXP_IS_G_OBJECT
147 #define         e_sexp_ref(f)           g_object_ref (f)
148 #define         e_sexp_unref(f)         g_object_unref (f)
149 #else
150 void            e_sexp_ref              (ESExp *f);
151 void            e_sexp_unref            (ESExp *f);
152 #endif
153 void            e_sexp_add_function     (ESExp *f, gint scope, const gchar *name, ESExpFunc *func, gpointer data);
154 void            e_sexp_add_ifunction    (ESExp *f, gint scope, const gchar *name, ESExpIFunc *func, gpointer data);
155 void            e_sexp_add_variable     (ESExp *f, gint scope, gchar *name, ESExpTerm *value);
156 void            e_sexp_remove_symbol    (ESExp *f, gint scope, const gchar *name);
157 gint            e_sexp_set_scope        (ESExp *f, gint scope);
158
159 void            e_sexp_input_text       (ESExp *f, const gchar *text, gint len);
160 void            e_sexp_input_file       (ESExp *f, gint fd);
161
162 gint            e_sexp_parse            (ESExp *f);
163 ESExpResult    *e_sexp_eval             (ESExp *f);
164
165 ESExpResult    *e_sexp_term_eval        (struct _ESExp *f, struct _ESExpTerm *t);
166 ESExpResult    *e_sexp_result_new       (struct _ESExp *f, gint type);
167 void            e_sexp_result_free      (struct _ESExp *f, struct _ESExpResult *t);
168
169 /* used in normal functions if they have to abort, to free their arguments */
170 void            e_sexp_resultv_free     (struct _ESExp *f, gint argc, struct _ESExpResult **argv);
171
172 /* utility functions for creating s-exp strings. */
173 void            e_sexp_encode_bool      (GString *s, gboolean state);
174 void            e_sexp_encode_string    (GString *s, const gchar *string);
175
176 /* only to be called from inside a callback to signal a fatal execution error */
177 void            e_sexp_fatal_error      (struct _ESExp *f, const gchar *why, ...) G_GNUC_NORETURN;
178
179 /* return the error string */
180 const gchar     *e_sexp_error           (struct _ESExp *f);
181
182 ESExpTerm * e_sexp_parse_value (ESExp *f);
183
184 gboolean        e_sexp_evaluate_occur_times     (ESExp *f, time_t *start, time_t *end);
185 G_END_DECLS
186
187 #endif /* _E_SEXP_H */