/*
* This library is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see .
*
*/
#if !defined (__LIBEDATASERVER_H_INSIDE__) && !defined (LIBEDATASERVER_COMPILATION)
#error "Only should be included directly."
#endif
#ifndef _E_SEXP_H
#define _E_SEXP_H
#include
#include
#include
/* Don't define E_SEXP_IS_G_OBJECT as this object is now used by camel */
#ifdef E_SEXP_IS_G_OBJECT
#include
#endif
#ifdef E_SEXP_IS_G_OBJECT
#define E_TYPE_SEXP (e_sexp_get_type ())
#define E_SEXP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SEXP, ESExp))
#define E_SEXP_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST ((cls), E_TYPE_SEXP, ESExpClass))
#define IS_E_SEXP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SEXP))
#define IS_E_SEXP_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE ((cls), E_TYPE_SEXP))
#define E_SEXP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_SEXP, ESExpClass))
#else
#define E_TYPE_SEXP (0)
#define E_SEXP(obj) ((struct _ESExp *) (obj))
#define E_SEXP_CLASS(cls) ((struct _ESExpClass *) (cls))
#define IS_E_SEXP(obj) (1)
#define IS_E_SEXP_CLASS(obj) (1)
#define E_SEXP_GET_CLASS(obj) (NULL)
#endif
G_BEGIN_DECLS
typedef struct _ESExp ESExp;
typedef struct _ESExpClass ESExpClass;
typedef struct _ESExpSymbol ESExpSymbol;
typedef struct _ESExpResult ESExpResult;
typedef struct _ESExpTerm ESExpTerm;
typedef enum {
ESEXP_RES_ARRAY_PTR=0, /* type is a ptrarray, what it points to is implementation dependant */
ESEXP_RES_INT, /* type is a number */
ESEXP_RES_STRING, /* type is a pointer to a single string */
ESEXP_RES_BOOL, /* boolean type */
ESEXP_RES_TIME, /* time_t type */
ESEXP_RES_UNDEFINED /* unknown type */
} ESExpResultType;
struct _ESExpResult {
ESExpResultType type;
union {
GPtrArray *ptrarray;
gint number;
gchar *string;
gint boolean;
time_t time;
} value;
gboolean time_generator;
time_t occuring_start;
time_t occuring_end;
};
typedef struct _ESExpResult *(ESExpFunc)(struct _ESExp *sexp, gint argc,
struct _ESExpResult **argv,
gpointer data);
typedef struct _ESExpResult *(ESExpIFunc)(struct _ESExp *sexp, gint argc,
struct _ESExpTerm **argv,
gpointer data);
typedef enum {
ESEXP_TERM_INT = 0, /* integer literal */
ESEXP_TERM_BOOL, /* boolean literal */
ESEXP_TERM_STRING, /* string literal */
ESEXP_TERM_TIME, /* time_t literal (number of seconds past the epoch) */
ESEXP_TERM_FUNC, /* normal function, arguments are evaluated before calling */
ESEXP_TERM_IFUNC, /* immediate function, raw terms are arguments */
ESEXP_TERM_VAR /* variable reference */
} ESExpTermType;
struct _ESExpSymbol {
gint type; /* ESEXP_TERM_FUNC or ESEXP_TERM_VAR */
gchar *name;
gpointer data;
union {
ESExpFunc *func;
ESExpIFunc *ifunc;
} f;
};
struct _ESExpTerm {
ESExpTermType type;
union {
gchar *string;
gint number;
gint boolean;
time_t time;
struct {
struct _ESExpSymbol *sym;
struct _ESExpTerm **terms;
gint termcount;
} func;
struct _ESExpSymbol *var;
} value;
};
struct _ESExp {
#ifdef E_SEXP_IS_G_OBJECT
GObject parent_object;
#else
gint refcount;
#endif
GScanner *scanner; /* for parsing text version */
ESExpTerm *tree; /* root of expression tree */
/* private stuff */
jmp_buf failenv;
gchar *error;
GSList *operators;
/* TODO: may also need a pool allocator for term strings, so we dont lose them
* in error conditions? */
struct _EMemChunk *term_chunks;
struct _EMemChunk *result_chunks;
};
struct _ESExpClass {
#ifdef E_SEXP_IS_G_OBJECT
GObjectClass parent_class;
#else
gint dummy;
#endif
};
#ifdef E_SEXP_IS_G_OBJECT
GType e_sexp_get_type (void);
#endif
ESExp *e_sexp_new (void);
#ifdef E_SEXP_IS_G_OBJECT
#define e_sexp_ref(f) g_object_ref (f)
#define e_sexp_unref(f) g_object_unref (f)
#else
void e_sexp_ref (ESExp *f);
void e_sexp_unref (ESExp *f);
#endif
void e_sexp_add_function (ESExp *f, gint scope, const gchar *name, ESExpFunc *func, gpointer data);
void e_sexp_add_ifunction (ESExp *f, gint scope, const gchar *name, ESExpIFunc *func, gpointer data);
void e_sexp_add_variable (ESExp *f, gint scope, gchar *name, ESExpTerm *value);
void e_sexp_remove_symbol (ESExp *f, gint scope, const gchar *name);
gint e_sexp_set_scope (ESExp *f, gint scope);
void e_sexp_input_text (ESExp *f, const gchar *text, gint len);
void e_sexp_input_file (ESExp *f, gint fd);
gint e_sexp_parse (ESExp *f);
ESExpResult *e_sexp_eval (ESExp *f);
ESExpResult *e_sexp_term_eval (struct _ESExp *f, struct _ESExpTerm *t);
ESExpResult *e_sexp_result_new (struct _ESExp *f, gint type);
void e_sexp_result_free (struct _ESExp *f, struct _ESExpResult *t);
/* used in normal functions if they have to abort, to free their arguments */
void e_sexp_resultv_free (struct _ESExp *f, gint argc, struct _ESExpResult **argv);
/* utility functions for creating s-exp strings. */
void e_sexp_encode_bool (GString *s, gboolean state);
void e_sexp_encode_string (GString *s, const gchar *string);
/* only to be called from inside a callback to signal a fatal execution error */
void e_sexp_fatal_error (struct _ESExp *f, const gchar *why, ...) G_GNUC_NORETURN;
/* return the error string */
const gchar *e_sexp_error (struct _ESExp *f);
ESExpTerm * e_sexp_parse_value (ESExp *f);
gboolean e_sexp_evaluate_occur_times (ESExp *f, time_t *start, time_t *end);
G_END_DECLS
#endif /* _E_SEXP_H */