1 /*
2  * This library is free software: you can redistribute it and/or modify it
3  * under the terms of the GNU Lesser General Public License as published by
4  * the Free Software Foundation.
5  *
6  * This library is distributed in the hope that it will be useful, but
7  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
9  * for more details.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this library. If not, see <http://www.gnu.org/licenses/>.
13  *
14  */
15 
16 #if !defined (__LIBEDATASERVER_H_INSIDE__) && !defined (LIBEDATASERVER_COMPILATION)
17 #error "Only <libedataserver/libedataserver.h> should be included directly."
18 #endif
19 
20 #ifndef _E_SEXP_H
21 #define _E_SEXP_H
22 
23 #include <setjmp.h>
24 #include <time.h>
25 #include <glib.h>
26 
27 #include <glib-object.h>
28 
29 #define E_TYPE_SEXP            (e_sexp_get_type ())
30 #define E_SEXP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SEXP, ESExp))
31 #define E_SEXP_CLASS(cls)      (G_TYPE_CHECK_CLASS_CAST ((cls), E_TYPE_SEXP, ESExpClass))
32 #define E_IS_SEXP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SEXP))
33 #define E_IS_SEXP_CLASS(cls)   (G_TYPE_CHECK_CLASS_TYPE ((cls), E_TYPE_SEXP))
34 #define E_SEXP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_SEXP, ESExpClass))
35 
36 G_BEGIN_DECLS
37 
38 typedef struct _ESExp        ESExp;
39 typedef struct _ESExpClass   ESExpClass;
40 typedef struct _ESExpPrivate ESExpPrivate;
41 
42 typedef struct _ESExpSymbol ESExpSymbol;
43 typedef struct _ESExpResult ESExpResult;
44 typedef struct _ESExpTerm ESExpTerm;
45 
46 typedef enum {
47 	ESEXP_RES_ARRAY_PTR=0,	/* type is a ptrarray, what it points to is implementation dependant */
48 	ESEXP_RES_INT,		/* type is a number */
49 	ESEXP_RES_STRING,	/* type is a pointer to a single string */
50 	ESEXP_RES_BOOL,		/* boolean type */
51 	ESEXP_RES_TIME,		/* time_t type */
52 	ESEXP_RES_UNDEFINED	/* unknown type */
53 } ESExpResultType;
54 
55 struct _ESExpResult {
56 	ESExpResultType type;
57 	union {
58 		GPtrArray *ptrarray;
59 		gint number;
60 		gchar *string;
61 		gint boolean;
62 		time_t time;
63 	} value;
64 	gboolean time_generator;
65 	time_t occuring_start;
66 	time_t occuring_end;
67 };
68 
69 /**
70  * ESExpFunc:
71  * @sexp: an #ESExp
72  * @argc: count of arguments
73  * @argv: (in) (array length=argc): array of values of the arguments
74  * @user_data: user data as passed to e_sexp_add_function()
75  *
76  * Callback type for function symbols used with e_sexp_add_function().
77  *
78  * Returns: Result of the function call, allocated by e_sexp_result_new().
79  */
80 typedef struct _ESExpResult *(ESExpFunc)(struct _ESExp *sexp,
81 					 gint argc,
82 					 struct _ESExpResult **argv,
83 					 gpointer user_data);
84 
85 /**
86  * ESExpIFunc:
87  * @sexp: an #ESExp
88  * @argc: count of arguments
89  * @argv: (in) (array length=argc): array of values of the arguments
90  * @user_data: user data as passed to e_sexp_add_ifunction()
91  *
92  * Callback type for function symbols used with e_sexp_add_ifunction().
93  *
94  * Returns: Result of the function call, allocated by e_sexp_result_new().
95  */
96 typedef struct _ESExpResult *(ESExpIFunc)(struct _ESExp *sexp,
97 					  gint argc,
98 					  struct _ESExpTerm **argv,
99 					  gpointer user_data);
100 
101 typedef enum {
102 	ESEXP_TERM_INT	= 0,	/* integer literal */
103 	ESEXP_TERM_BOOL,	/* boolean literal */
104 	ESEXP_TERM_STRING,	/* string literal */
105 	ESEXP_TERM_TIME,	/* time_t literal (number of seconds past the epoch) */
106 	ESEXP_TERM_FUNC,	/* normal function, arguments are evaluated before calling */
107 	ESEXP_TERM_IFUNC,	/* immediate function, raw terms are arguments */
108 	ESEXP_TERM_VAR		/* variable reference */
109 } ESExpTermType;
110 
111 struct _ESExpSymbol {
112 	gint type;		/* ESEXP_TERM_FUNC or ESEXP_TERM_VAR */
113 	gchar *name;
114 	gpointer data;
115 	union {
116 		ESExpFunc *func;
117 		ESExpIFunc *ifunc;
118 	} f;
119 };
120 
121 struct _ESExpTerm {
122 	ESExpTermType type;
123 	union {
124 		gchar *string;
125 		gint number;
126 		gint boolean;
127 		time_t time;
128 		struct {
129 			struct _ESExpSymbol *sym;
130 			struct _ESExpTerm **terms;
131 			gint termcount;
132 		} func;
133 		struct _ESExpSymbol *var;
134 	} value;
135 };
136 
137 struct _ESExp {
138 	GObject parent_object;
139 
140 	ESExpPrivate *priv;
141 };
142 
143 struct _ESExpClass {
144 	GObjectClass parent_class;
145 };
146 
147 GType           e_sexp_get_type		(void);
148 ESExp	       *e_sexp_new		(void);
149 void		e_sexp_add_function	(ESExp *sexp,
150 					 gint scope,
151 					 const gchar *name,
152 					 ESExpFunc *func,
153 					 gpointer user_data);
154 void		e_sexp_add_ifunction	(ESExp *sexp,
155 					 gint scope,
156 					 const gchar *name,
157 					 ESExpIFunc *func,
158 					 gpointer user_data);
159 void		e_sexp_add_variable	(ESExp *sexp,
160 					 gint scope,
161 					 gchar *name,
162 					 ESExpTerm *value);
163 void		e_sexp_remove_symbol	(ESExp *sexp,
164 					 gint scope,
165 					 const gchar *name);
166 gint		e_sexp_set_scope	(ESExp *sexp,
167 					 gint scope);
168 
169 void		e_sexp_input_text	(ESExp *sexp,
170 					 const gchar *text,
171 					 gint len);
172 void		e_sexp_input_file	(ESExp *sexp,
173 					 gint fd);
174 
175 gint		e_sexp_parse		(ESExp *sexp);
176 ESExpResult    *e_sexp_eval		(ESExp *sexp);
177 
178 ESExpResult    *e_sexp_term_eval	(ESExp *sexp,
179 					 ESExpTerm *t);
180 ESExpResult    *e_sexp_result_new	(ESExp *sexp,
181 					 gint type);
182 void		e_sexp_result_free	(ESExp *sexp,
183 					 ESExpResult *t);
184 
185 /* used in normal functions if they have to abort, to free their arguments */
186 void		e_sexp_resultv_free	(ESExp *sexp,
187 					 gint argc,
188 					 ESExpResult **argv);
189 
190 /* utility functions for creating s-exp strings. */
191 void		e_sexp_encode_bool	(GString *s,
192 					 gboolean state);
193 void		e_sexp_encode_string	(GString *s,
194 					 const gchar *string);
195 
196 /* only to be called from inside a callback to signal a fatal execution error */
197 void		e_sexp_fatal_error	(ESExp *sexp,
198 					 const gchar *why,
199 					 ...) G_GNUC_NORETURN;
200 
201 /* return the error string */
202 const gchar *	e_sexp_get_error	(ESExp *sexp);
203 
204 ESExpTerm * 	e_sexp_parse_value	(ESExp *sexp);
205 
206 gboolean	e_sexp_evaluate_occur_times
207 					(ESExp *sexp,
208 					 time_t *start,
209 					 time_t *end);
210 
211 G_END_DECLS
212 
213 #endif /* _E_SEXP_H */
214