aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend/ebook/e-book-query.c
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/backend/ebook/e-book-query.c')
-rw-r--r--addressbook/backend/ebook/e-book-query.c524
1 files changed, 0 insertions, 524 deletions
diff --git a/addressbook/backend/ebook/e-book-query.c b/addressbook/backend/ebook/e-book-query.c
deleted file mode 100644
index 16e325303c..0000000000
--- a/addressbook/backend/ebook/e-book-query.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-#include <config.h>
-
-#include "e-book-query.h"
-#include <e-util/e-sexp.h>
-
-#include <stdarg.h>
-#include <string.h>
-
-typedef enum {
- E_BOOK_QUERY_TYPE_AND,
- E_BOOK_QUERY_TYPE_OR,
- E_BOOK_QUERY_TYPE_NOT,
- E_BOOK_QUERY_TYPE_FIELD_EXISTS,
- E_BOOK_QUERY_TYPE_FIELD_TEST,
- E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS
-} EBookQueryType;
-
-struct EBookQuery {
- EBookQueryType type;
- int ref_count;
-
- union {
- struct {
- guint nqs;
- EBookQuery **qs;
- } andor;
-
- struct {
- EBookQuery *q;
- } not;
-
- struct {
- EBookQueryTest test;
- EContactField field;
- char *value;
- } field_test;
-
- struct {
- EContactField field;
- } exist;
-
- struct {
- char *value;
- } any_field_contains;
- } query;
-};
-
-static EBookQuery *
-conjoin (EBookQueryType type, int nqs, EBookQuery **qs, gboolean unref)
-{
- EBookQuery *ret = g_new0 (EBookQuery, 1);
- int i;
-
- ret->type = type;
- ret->query.andor.nqs = nqs;
- ret->query.andor.qs = g_new (EBookQuery *, nqs);
- for (i = 0; i < nqs; i++) {
- ret->query.andor.qs[i] = qs[i];
- if (!unref)
- e_book_query_ref (qs[i]);
- }
-
- return ret;
-}
-
-EBookQuery *
-e_book_query_and (int nqs, EBookQuery **qs, gboolean unref)
-{
- return conjoin (E_BOOK_QUERY_TYPE_AND, nqs, qs, unref);
-}
-
-EBookQuery *
-e_book_query_or (int nqs, EBookQuery **qs, gboolean unref)
-{
- return conjoin (E_BOOK_QUERY_TYPE_OR, nqs, qs, unref);
-}
-
-static EBookQuery *
-conjoinv (EBookQueryType type, EBookQuery *q, va_list ap)
-{
- EBookQuery *ret = g_new0 (EBookQuery, 1);
- GPtrArray *qs;
-
- qs = g_ptr_array_new ();
- while (q) {
- g_ptr_array_add (qs, q);
- q = va_arg (ap, EBookQuery *);
- }
- va_end (ap);
-
- ret->type = type;
- ret->query.andor.nqs = qs->len;
- ret->query.andor.qs = (EBookQuery **)qs->pdata;
- g_ptr_array_free (qs, FALSE);
-
- return ret;
-}
-
-EBookQuery *
-e_book_query_andv (EBookQuery *q, ...)
-{
- va_list ap;
-
- va_start (ap, q);
- return conjoinv (E_BOOK_QUERY_TYPE_AND, q, ap);
-}
-
-EBookQuery *
-e_book_query_orv (EBookQuery *q, ...)
-{
- va_list ap;
-
- va_start (ap, q);
- return conjoinv (E_BOOK_QUERY_TYPE_OR, q, ap);
-}
-
-EBookQuery *
-e_book_query_not (EBookQuery *q, gboolean unref)
-{
- EBookQuery *ret = g_new0 (EBookQuery, 1);
-
- ret->type = E_BOOK_QUERY_TYPE_NOT;
- ret->query.not.q = q;
- if (!unref)
- e_book_query_ref (q);
-
- return ret;
-}
-
-EBookQuery *
-e_book_query_field_test (EContactField field,
- EBookQueryTest test,
- const char *value)
-{
- EBookQuery *ret = g_new0 (EBookQuery, 1);
-
- ret->type = E_BOOK_QUERY_TYPE_FIELD_TEST;
- ret->query.field_test.field = field;
- ret->query.field_test.test = test;
- ret->query.field_test.value = g_strdup (value);
-
- return ret;
-}
-
-EBookQuery *
-e_book_query_field_exists (EContactField field)
-{
- EBookQuery *ret = g_new0 (EBookQuery, 1);
-
- ret->type = E_BOOK_QUERY_TYPE_FIELD_EXISTS;
- ret->query.exist.field = field;
-
- return ret;
-}
-
-EBookQuery *
-e_book_query_any_field_contains (const char *value)
-{
- EBookQuery *ret = g_new0 (EBookQuery, 1);
-
- ret->type = E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS;
- ret->query.any_field_contains.value = g_strdup (value);
-
- return ret;
-}
-
-void
-e_book_query_unref (EBookQuery *q)
-{
- int i;
-
- if (q->ref_count--)
- return;
-
- switch (q->type) {
- case E_BOOK_QUERY_TYPE_AND:
- case E_BOOK_QUERY_TYPE_OR:
- for (i = 0; i < q->query.andor.nqs; i++)
- e_book_query_unref (q->query.andor.qs[i]);
- g_free (q->query.andor.qs);
- break;
-
- case E_BOOK_QUERY_TYPE_NOT:
- e_book_query_unref (q->query.not.q);
- break;
-
- case E_BOOK_QUERY_TYPE_FIELD_TEST:
- g_free (q->query.field_test.value);
- break;
-
- case E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS:
- g_free (q->query.any_field_contains.value);
- break;
-
- default:
- break;
- }
-
- g_free (q);
-}
-
-void
-e_book_query_ref (EBookQuery *q)
-{
- q->ref_count++;
-}
-
-static ESExpResult *
-func_and(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- GList **list = data;
- ESExpResult *r;
- EBookQuery **qs;
-
- if (argc > 0) {
- int i;
-
- qs = g_new0(EBookQuery*, argc);
-
- for (i = 0; i < argc; i ++) {
- GList *list_head = *list;
- if (!list_head)
- break;
- qs[i] = list_head->data;
- *list = g_list_remove_link(*list, list_head);
- g_list_free_1(list_head);
- }
-
- *list = g_list_prepend(*list,
- e_book_query_and (argc, qs, TRUE));
-
- g_free (qs);
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
-
- return r;
-}
-
-static ESExpResult *
-func_or(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- GList **list = data;
- ESExpResult *r;
- EBookQuery **qs;
-
- if (argc > 0) {
- int i;
-
- qs = g_new0(EBookQuery*, argc);
-
- for (i = 0; i < argc; i ++) {
- GList *list_head = *list;
- if (!list_head)
- break;
- qs[i] = list_head->data;
- *list = g_list_remove_link(*list, list_head);
- g_list_free_1(list_head);
- }
-
- *list = g_list_prepend(*list,
- e_book_query_or (argc, qs, TRUE));
-
- g_free (qs);
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
-
- return r;
-}
-
-static ESExpResult *
-func_not(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- GList **list = data;
- ESExpResult *r;
-
- /* just replace the head of the list with the NOT of it. */
- if (argc > 0) {
- EBookQuery *term = (*list)->data;
- (*list)->data = e_book_query_not (term, TRUE);
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
-
- return r;
-}
-
-static ESExpResult *
-func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- GList **list = data;
- ESExpResult *r;
-
- if (argc == 2
- && argv[0]->type == ESEXP_RES_STRING
- && argv[1]->type == ESEXP_RES_STRING) {
- char *propname = argv[0]->value.string;
- char *str = argv[1]->value.string;
-
- if (!strcmp (propname, "x-evolution-any-field")) {
- *list = g_list_prepend (*list, e_book_query_any_field_contains (str));
- }
- else {
- EContactField field = e_contact_field_id (propname);
-
- if (field)
- *list = g_list_prepend (*list, e_book_query_field_test (field,
- E_BOOK_QUERY_CONTAINS,
- str));
- }
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
-
- return r;
-}
-
-static ESExpResult *
-func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- GList **list = data;
- ESExpResult *r;
-
- if (argc == 2
- && argv[0]->type == ESEXP_RES_STRING
- && argv[1]->type == ESEXP_RES_STRING) {
- char *propname = argv[0]->value.string;
- char *str = argv[1]->value.string;
- EContactField field = e_contact_field_id (propname);
-
- if (field)
- *list = g_list_prepend (*list, e_book_query_field_test (field,
- E_BOOK_QUERY_IS,
- str));
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
-
- return r;
-}
-
-static ESExpResult *
-func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- GList **list = data;
- ESExpResult *r;
-
- if (argc == 2
- && argv[0]->type == ESEXP_RES_STRING
- && argv[1]->type == ESEXP_RES_STRING) {
- char *propname = argv[0]->value.string;
- char *str = argv[1]->value.string;
- EContactField field = e_contact_field_id (propname);
-
- if (field)
- *list = g_list_prepend (*list, e_book_query_field_test (field,
- E_BOOK_QUERY_BEGINS_WITH,
- str));
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
-
- return r;
-}
-
-static ESExpResult *
-func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- GList **list = data;
- ESExpResult *r;
-
- if (argc == 2
- && argv[0]->type == ESEXP_RES_STRING
- && argv[1]->type == ESEXP_RES_STRING) {
- char *propname = argv[0]->value.string;
- char *str = argv[1]->value.string;
- EContactField field = e_contact_field_id (propname);
-
- if (field)
- *list = g_list_prepend (*list, e_book_query_field_test (field,
- E_BOOK_QUERY_ENDS_WITH,
- str));
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = FALSE;
-
- return r;
-}
-
-/* 'builtin' functions */
-static struct {
- char *name;
- ESExpFunc *func;
- int type; /* set to 1 if a function can perform shortcut evaluation, or
- doesn't execute everything, 0 otherwise */
-} symbols[] = {
- { "and", func_and, 0 },
- { "or", func_or, 0 },
- { "not", func_not, 0 },
- { "contains", func_contains, 0 },
- { "is", func_is, 0 },
- { "beginswith", func_beginswith, 0 },
- { "endswith", func_endswith, 0 },
-};
-
-EBookQuery*
-e_book_query_from_string (const char *query_string)
-{
- ESExp *sexp;
- ESExpResult *r;
- EBookQuery *retval;
- GList *list = NULL;
- int i;
-
- sexp = e_sexp_new();
-
- for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) {
- if (symbols[i].type == 1) {
- e_sexp_add_ifunction(sexp, 0, symbols[i].name,
- (ESExpIFunc *)symbols[i].func, &list);
- } else {
- e_sexp_add_function(sexp, 0, symbols[i].name,
- symbols[i].func, &list);
- }
- }
-
- e_sexp_input_text(sexp, query_string, strlen(query_string));
- e_sexp_parse(sexp);
-
- r = e_sexp_eval(sexp);
-
- e_sexp_result_free(sexp, r);
- e_sexp_unref (sexp);
-
- if (list) {
- if (list->next) {
- g_warning ("conversion to EBookQuery");
- retval = NULL;
- g_list_foreach (list, (GFunc)e_book_query_unref, NULL);
- }
- else {
- retval = list->data;
- }
- }
- else {
- g_warning ("conversion to EBookQuery failed");
- retval = NULL;
- }
-
- g_list_free (list);
- return retval;
-}
-
-char*
-e_book_query_to_string (EBookQuery *q)
-{
- GString *str = g_string_new ("(");
- int i;
- char *s = NULL;
-
- switch (q->type) {
- case E_BOOK_QUERY_TYPE_AND:
- g_string_append (str, "and ");
- for (i = 0; i < q->query.andor.nqs; i ++) {
- s = e_book_query_to_string (q->query.andor.qs[i]);
- g_string_append (str, s);
- g_free (s);
- g_string_append_c (str, ' ');
- }
- break;
- case E_BOOK_QUERY_TYPE_OR:
- g_string_append (str, "or ");
- for (i = 0; i < q->query.andor.nqs; i ++) {
- s = e_book_query_to_string (q->query.andor.qs[i]);
- g_string_append (str, s);
- g_free (s);
- g_string_append_c (str, ' ');
- }
- break;
- case E_BOOK_QUERY_TYPE_NOT:
- s = e_book_query_to_string (q->query.not.q);
- g_string_append_printf (str, "not %s", s);
- g_free (s);
- break;
- case E_BOOK_QUERY_TYPE_FIELD_EXISTS:
- g_string_append_printf (str, "exists \"%s\"", e_contact_field_name (q->query.exist.field));
- break;
- case E_BOOK_QUERY_TYPE_FIELD_TEST:
- switch (q->query.field_test.test) {
- case E_BOOK_QUERY_IS: s = "is"; break;
- case E_BOOK_QUERY_CONTAINS: s = "contains"; break;
- case E_BOOK_QUERY_BEGINS_WITH: s = "beginswith"; break;
- case E_BOOK_QUERY_ENDS_WITH: s = "endswith"; break;
- default:
- g_assert_not_reached();
- break;
- }
-
- /* XXX need to escape q->query.field_test.value */
- g_string_append_printf (str, "%s \"%s\" \"%s\"",
- s,
- e_contact_field_name (q->query.field_test.field),
- q->query.field_test.value);
- break;
- case E_BOOK_QUERY_TYPE_ANY_FIELD_CONTAINS:
- g_string_append_printf (str, "contains \"x-evolution-any-field\" \"%s\"", q->query.any_field_contains.value);
- break;
- }
-
-
- g_string_append (str, ")");
-
- return g_string_free (str, FALSE);
-}