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 (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION) 17 #error "Only <camel/camel.h> can be included directly." 18 #endif 19 20 #ifndef CAMEL_SEXP_H 21 #define CAMEL_SEXP_H 22 23 #include <setjmp.h> 24 #include <time.h> 25 #include <glib.h> 26 27 #include <glib-object.h> 28 29 #include <camel/camel-memchunk.h> 30 31 /* Standard GObject macros */ 32 #define CAMEL_TYPE_SEXP \ 33 (camel_sexp_get_type ()) 34 #define CAMEL_SEXP(obj) \ 35 (G_TYPE_CHECK_INSTANCE_CAST \ 36 ((obj), CAMEL_TYPE_SEXP, CamelSExp)) 37 #define CAMEL_SEXP_CLASS(cls) \ 38 (G_TYPE_CHECK_CLASS_CAST \ 39 ((cls), CAMEL_TYPE_SEXP, CamelSExpClass)) 40 #define CAMEL_IS_SEXP(obj) \ 41 (G_TYPE_CHECK_INSTANCE_TYPE \ 42 ((obj), CAMEL_TYPE_SEXP)) 43 #define CAMEL_IS_SEXP_CLASS(cls) \ 44 (G_TYPE_CHECK_CLASS_TYPE \ 45 ((cls), CAMEL_TYPE_SEXP)) 46 #define CAMEL_SEXP_GET_CLASS(obj) \ 47 (G_TYPE_INSTANCE_GET_CLASS \ 48 ((obj), CAMEL_TYPE_SEXP, CamelSExpClass)) 49 50 G_BEGIN_DECLS 51 52 typedef struct _CamelSExp CamelSExp; 53 typedef struct _CamelSExpClass CamelSExpClass; 54 typedef struct _CamelSExpPrivate CamelSExpPrivate; 55 56 typedef struct _CamelSExpSymbol CamelSExpSymbol; 57 typedef struct _CamelSExpResult CamelSExpResult; 58 typedef struct _CamelSExpTerm CamelSExpTerm; 59 60 /** 61 * CamelSExpResultType: 62 * @CAMEL_SEXP_RES_ARRAY_PTR: type is a ptrarray, what it points to is implementation dependant 63 * @CAMEL_SEXP_RES_INT: type is a number 64 * @CAMEL_SEXP_RES_STRING: type is a pointer to a single string 65 * @CAMEL_SEXP_RES_BOOL: boolean type 66 * @CAMEL_SEXP_RES_TIME: time_t type 67 * @CAMEL_SEXP_RES_UNDEFINED: unknown type 68 * 69 * Defines type of a #CamelSExpResult. 70 * 71 * Since: 3.4 72 **/ 73 typedef enum { 74 CAMEL_SEXP_RES_ARRAY_PTR, /* type is a ptrarray, what it points to is implementation dependant */ 75 CAMEL_SEXP_RES_INT, /* type is a number */ 76 CAMEL_SEXP_RES_STRING, /* type is a pointer to a single string */ 77 CAMEL_SEXP_RES_BOOL, /* boolean type */ 78 CAMEL_SEXP_RES_TIME, /* time_t type */ 79 CAMEL_SEXP_RES_UNDEFINED /* unknown type */ 80 } CamelSExpResultType; 81 82 /** 83 * CamelSExpResult: 84 * @type: a #CamelSExpResultType, defining the @value type 85 * @value: a union with the actual value 86 * @time_generator: a boolean whether the occuring times are used 87 * @occuring_start: start time 88 * @occuring_end: end time 89 * 90 * Since: 3.4 91 **/ 92 struct _CamelSExpResult { 93 CamelSExpResultType type; 94 union { 95 GPtrArray *ptrarray; 96 gint number; 97 gchar *string; 98 gint boolean; 99 time_t time; 100 } value; 101 gboolean time_generator; 102 time_t occuring_start; 103 time_t occuring_end; 104 }; 105 106 /** 107 * CamelSExpFunc: 108 * @sexp: a #CamelSExp 109 * @argc: count of arguments 110 * @argv: (in) (array length=argc): array of values of the arguments 111 * @user_data: user data as passed to camel_sexp_add_function() 112 * 113 * Callback type for function symbols used with camel_sexp_add_function(). 114 * 115 * Returns: Result of the function call, allocated by camel_sexp_result_new(). 116 * 117 * Since: 3.4 118 **/ 119 typedef CamelSExpResult * 120 (*CamelSExpFunc) (CamelSExp *sexp, 121 gint argc, 122 CamelSExpResult **argv, 123 gpointer user_data); 124 125 /** 126 * CamelSExpIFunc: 127 * @sexp: a #CamelSExp 128 * @argc: count of arguments 129 * @argv: (in) (array length=argc): array of values of the arguments 130 * @user_data: user data as passed to camel_sexp_add_ifunction() 131 * 132 * Callback type for function symbols used with camel_sexp_add_ifunction(). 133 * 134 * Returns: Result of the function call, allocated by camel_sexp_result_new(). 135 * 136 * Since: 3.4 137 **/ 138 typedef CamelSExpResult * 139 (*CamelSExpIFunc) (CamelSExp *sexp, 140 gint argc, 141 CamelSExpTerm **argv, 142 gpointer user_data); 143 144 /** 145 * CamelSExpTermType: 146 * @CAMEL_SEXP_TERM_INT: integer literal 147 * @CAMEL_SEXP_TERM_BOOL: boolean literal 148 * @CAMEL_SEXP_TERM_STRING: string literal 149 * @CAMEL_SEXP_TERM_TIME: time_t literal (number of seconds past the epoch) 150 * @CAMEL_SEXP_TERM_FUNC: normal function, arguments are evaluated before calling 151 * @CAMEL_SEXP_TERM_IFUNC: immediate function, raw terms are arguments 152 * @CAMEL_SEXP_TERM_VAR: variable reference 153 * 154 * Defines type of a #CamelSExpTerm and partly also #CamelSExpSymbol 155 * 156 * Since: 3.4 157 **/ 158 typedef enum { 159 CAMEL_SEXP_TERM_INT, /* integer literal */ 160 CAMEL_SEXP_TERM_BOOL, /* boolean literal */ 161 CAMEL_SEXP_TERM_STRING, /* string literal */ 162 CAMEL_SEXP_TERM_TIME, /* time_t literal (number of seconds past the epoch) */ 163 CAMEL_SEXP_TERM_FUNC, /* normal function, arguments are evaluated before calling */ 164 CAMEL_SEXP_TERM_IFUNC, /* immediate function, raw terms are arguments */ 165 CAMEL_SEXP_TERM_VAR /* variable reference */ 166 } CamelSExpTermType; 167 168 /** 169 * CamelSExpSymbol: 170 * @type: a type of the symbol, either CAMEL_SEXP_TERM_FUNC or CAMEL_SEXP_TERM_VAR 171 * @name: name of the symbol 172 * @data: user data for the callback 173 * @f.func: a #CamelSExpFunc callback 174 * @f.ifunc: a #CamelSExpIFunc callback 175 * 176 * Describes a function or a variable symbol 177 * 178 * Since: 3.4 179 **/ 180 struct _CamelSExpSymbol { 181 gint type; /* TERM_FUNC or TERM_VAR */ 182 gchar *name; 183 gpointer data; 184 union { 185 CamelSExpFunc func; 186 CamelSExpIFunc ifunc; 187 } f; 188 }; 189 190 /** 191 * CamelSExpTerm: 192 * @type: a type of the term; one of #CamelSExpTermType 193 * @value: value of the term 194 * 195 * Since: 3.4 196 **/ 197 struct _CamelSExpTerm { 198 CamelSExpTermType type; 199 union { 200 gchar *string; 201 gint number; 202 gint boolean; 203 time_t time; 204 struct { 205 CamelSExpSymbol *sym; 206 CamelSExpTerm **terms; 207 gint termcount; 208 } func; 209 CamelSExpSymbol *var; 210 } value; 211 }; 212 213 /** 214 * CamelSExp: 215 * 216 * Since: 3.4 217 **/ 218 struct _CamelSExp { 219 /*< private >*/ 220 GObject parent; 221 CamelSExpPrivate *priv; 222 }; 223 224 struct _CamelSExpClass { 225 GObjectClass parent_class; 226 227 /* Padding for future expansion */ 228 gpointer reserved[20]; 229 }; 230 231 GType camel_sexp_get_type (void) G_GNUC_CONST; 232 CamelSExp * camel_sexp_new (void); 233 void camel_sexp_add_function (CamelSExp *sexp, 234 guint scope, 235 const gchar *name, 236 CamelSExpFunc func, 237 gpointer user_data); 238 void camel_sexp_add_ifunction (CamelSExp *sexp, 239 guint scope, 240 const gchar *name, 241 CamelSExpIFunc ifunc, 242 gpointer user_data); 243 void camel_sexp_add_variable (CamelSExp *sexp, 244 guint scope, 245 const gchar *name, 246 CamelSExpTerm *value); 247 void camel_sexp_remove_symbol (CamelSExp *sexp, 248 guint scope, 249 const gchar *name); 250 gint camel_sexp_set_scope (CamelSExp *sexp, 251 guint scope); 252 void camel_sexp_input_text (CamelSExp *sexp, 253 const gchar *text, 254 gint len); 255 void camel_sexp_input_file (CamelSExp *sexp, 256 gint fd); 257 gint camel_sexp_parse (CamelSExp *sexp); 258 CamelSExpResult * 259 camel_sexp_eval (CamelSExp *sexp); 260 CamelSExpResult * 261 camel_sexp_term_eval (CamelSExp *sexp, 262 CamelSExpTerm *term); 263 CamelSExpResult * 264 camel_sexp_result_new (CamelSExp *sexp, 265 gint type); 266 void camel_sexp_result_free (CamelSExp *sexp, 267 CamelSExpResult *result); 268 269 /* used in normal functions if they have to abort, to free their arguments */ 270 void camel_sexp_resultv_free (CamelSExp *sexp, 271 gint argc, 272 CamelSExpResult **argv); 273 274 /* utility functions for creating s-exp strings. */ 275 void camel_sexp_encode_bool (GString *string, 276 gboolean v_bool); 277 void camel_sexp_encode_string (GString *string, 278 const gchar *v_string); 279 280 /* only to be called from inside a callback to signal a fatal execution error */ 281 void camel_sexp_fatal_error (CamelSExp *sexp, 282 const gchar *why, 283 ...) G_GNUC_NORETURN; 284 285 /* return the error string */ 286 const gchar * camel_sexp_error (CamelSExp *sexp); 287 288 CamelSExpTerm * camel_sexp_parse_value (CamelSExp *sexp); 289 290 gboolean camel_sexp_evaluate_occur_times (CamelSExp *sexp, 291 time_t *start, 292 time_t *end); 293 294 G_END_DECLS 295 296 #endif /* CAMEL_SEXP_H */ 297