diff options
author | Jeffrey Stedfast <fejj@helixcode.com> | 2000-08-01 04:00:20 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2000-08-01 04:00:20 +0800 |
commit | 3ef60c2537f654d15bed4347dbc12076be3064fc (patch) | |
tree | a9fca24bffe91e1e1f4b576e616876b54256c6ec /camel/providers/imap/camel-imap-utils.c | |
parent | f67eb8f79172e77dadb0c02636409e087856baeb (diff) | |
download | gsoc2013-evolution-3ef60c2537f654d15bed4347dbc12076be3064fc.tar gsoc2013-evolution-3ef60c2537f654d15bed4347dbc12076be3064fc.tar.gz gsoc2013-evolution-3ef60c2537f654d15bed4347dbc12076be3064fc.tar.bz2 gsoc2013-evolution-3ef60c2537f654d15bed4347dbc12076be3064fc.tar.lz gsoc2013-evolution-3ef60c2537f654d15bed4347dbc12076be3064fc.tar.xz gsoc2013-evolution-3ef60c2537f654d15bed4347dbc12076be3064fc.tar.zst gsoc2013-evolution-3ef60c2537f654d15bed4347dbc12076be3064fc.zip |
New convenience function to translate a Camel sexp into the equivalent
2000-07-31 Jeffrey Stedfast <fejj@helixcode.com>
* providers/imap/camel-imap-utils.c (imap_translate_sexp): New
convenience function to translate a Camel sexp into the equivalent
IMAP sexp.
* providers/imap/camel-imap-store.c: More places now use
imap_next_word
* providers/imap/camel-imap-folder.c (imap_search_by_expression):
Implemented initial version (this may or may not work quite right)
svn path=/trunk/; revision=4428
Diffstat (limited to 'camel/providers/imap/camel-imap-utils.c')
-rw-r--r-- | camel/providers/imap/camel-imap-utils.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c index 6560481505..08a45de62a 100644 --- a/camel/providers/imap/camel-imap-utils.c +++ b/camel/providers/imap/camel-imap-utils.c @@ -28,6 +28,19 @@ #define d(x) x +struct sexp_node { + struct sexp_node *l_node, *r_node; + char *function; + char *data; +}; + +static char *get_quoted_token (char *string, int *len); +static char *get_token (char *string, int *len); +struct sexp_node *get_sexp_node (const char *exp); +static void print_node (struct sexp_node *node, int depth); +static char *str_sexp_node (struct sexp_node *node); +static void free_sexp_node (struct sexp_node *node); + char * imap_next_word (char *buf) { @@ -95,3 +108,233 @@ imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, return TRUE; } + +static char * +get_quoted_token (char *string, int *len) +{ + char *ep; + + for (ep = string + 1; *ep; ep++) + if (*ep == '"' && *(ep - 1) != '\\') + break; + if (*ep) + ep++; + + *len = ep - string; + + return g_strndup (string, *len); +} + +static char * +get_token (char *string, int *len) +{ + char *p, *ep; + + for (p = string; *p && *p == ' '; p++); + + if (*p == '"') { + char *token; + int i; + + token = get_quoted_token (p, &i); + + *len = i + (p - string); + + return token; + } + + for (ep = p; *ep && *ep != ' '; ep++); + + *len = ep - string; + + return g_strndup (p, *len); +} + +struct sexp_node * +get_sexp_node (const char *exp) +{ + struct sexp_node *node = NULL; + char *p, *ep; + int len; + + switch (*exp) { + case '(': + node = g_malloc0 (sizeof (struct sexp_node)); + node->l_node = NULL; + node->r_node = NULL; + node->data = NULL; + + p = (char *) exp + 1; + + node->function = get_token (p, &len); + + p += len; + for (ep = p; *ep && *ep != '(' && *ep != ')'; ep++); + node->data = g_strndup (p, (gint)(ep - p)); + g_strstrip (node->data); + + p = ep; + + if (*p == '(') + node->r_node = get_sexp_node (p); + else + node->l_node = get_sexp_node (p); + + return node; + break; + case '\0': + return NULL; + break; + case ')': + for (p = (char *) exp + 1; *p && *p == ' '; p++); + return get_sexp_node (p); + break; + default: + node = g_malloc0 (sizeof (struct sexp_node)); + node->l_node = NULL; + node->r_node = NULL; + node->data = NULL; + + p = (char *) exp; + + node->function = get_token (p, &len); + + p += len; + for (ep = p; *ep && *ep != '(' && *ep != ')'; ep++); + node->data = g_strndup (p, (gint)(ep - p)); + g_strstrip (node->data); + + p = ep; + + if (*p == '(') + node->r_node = get_sexp_node (p); + else + node->l_node = get_sexp_node (p); + + return node; + } +} + +static void +print_node (struct sexp_node *node, int depth) +{ + int i; + + for (i = 0; i < depth; i++) + d(fprintf (stderr, " ")); + + d(fprintf (stderr, "%s\n", node->function)); + + if (*node->data) { + for (i = 0; i < depth + 1; i++) + d(fprintf (stderr, " ")); + + d(fprintf (stderr, "%s\n", node->data)); + } + + if (node->r_node) + print_node (node->r_node, depth + 1); + + if (node->l_node) + print_node (node->l_node, depth); +} + +static char *esexp_keys[] = { "or", "body-contains", "header-contains", "match-all", NULL }; +static char *imap_keys[] = { "OR", "BODY", "HEADER", NULL }; + +static char * +str_sexp_node (struct sexp_node *node) +{ + char *node_str, *func, *str, *l_str, *r_str; + int i; + + for (i = 0; esexp_keys[i]; i++) + if (!strncmp (esexp_keys[i], node->function, strlen (node->function))) + break; + + if (esexp_keys[i]) + func = imap_keys[i]; + else + func = node->function; + + if (func) { + if (*node->data) + str = g_strdup_printf ("%s %s", func, node->data); + else + str = g_strdup (func); + } else { + str = NULL; + } + + r_str = NULL; + if (node->r_node) + r_str = str_sexp_node (node->r_node); + + l_str = NULL; + if (node->l_node) + l_str = str_sexp_node (node->l_node); + + if (str) { + if (r_str) { + if (l_str) + node_str = g_strdup_printf ("(%s (%s)) %s", str, r_str, l_str); + else + node_str = g_strdup_printf ("(%s %s)", str, r_str); + } else { + if (l_str) + node_str = g_strdup_printf ("(%s) %s", str, l_str); + else + node_str = g_strdup_printf ("(%s)", str); + } + } else { + if (r_str) { + if (l_str) + node_str = g_strdup_printf ("(%s) %s", r_str, l_str); + else + node_str = g_strdup_printf ("%s", r_str); + } else { + if (l_str) + node_str = g_strdup_printf ("%s", l_str); + else + node_str = g_strdup (""); + } + } + + g_free (str); + g_free (l_str); + g_free (r_str); + + return node_str; +} + +static void +free_sexp_node (struct sexp_node *node) +{ + if (node->r_node) + free_sexp_node (node->r_node); + + if (node->l_node) + free_sexp_node (node->l_node); + + g_free (node->data); + g_free (node); +} + +char * +imap_translate_sexp (const char *expression) +{ + struct sexp_node *root; + char *sexp; + + root = get_sexp_node (expression); + + d(print_node (root, 0)); + + sexp = str_sexp_node (root); + sexp[strlen (sexp) - 1] = '\0'; + strcpy (sexp, sexp + 1); + + free_sexp_node (root); + + return sexp; +} |