aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filter/ChangeLog3
-rw-r--r--filter/filter-driver.c151
2 files changed, 85 insertions, 69 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog
index bceed1c312..9cbf2f1d98 100644
--- a/filter/ChangeLog
+++ b/filter/ChangeLog
@@ -1,5 +1,8 @@
2000-07-07 Dan Winship <danw@helixcode.com>
+ * filter-driver.c: Update for camel_folder_search_by_expression
+ change (GList -> GPtrArray).
+
* vfoldertypes.xml: sync this to filtertypes.xml (to/cc thing)
2000-07-05 Dan Winship <danw@helixcode.com>
diff --git a/filter/filter-driver.c b/filter/filter-driver.c
index aa26e38f51..0ccd70e56b 100644
--- a/filter/filter-driver.c
+++ b/filter/filter-driver.c
@@ -43,9 +43,10 @@ struct _FilterDriverPrivate {
/* run-time data */
GHashTable *folders; /* currently open folders */
- GList *matches; /* all messages which match current rule */
+ GPtrArray *matches; /* all messages which match current rule */
GHashTable *terminated; /* messages for which processing is terminated */
GHashTable *processed; /* all messages that were processed in some way */
+ GHashTable *copies; /* lists of folders to copy messages to */
CamelFolder *source; /* temporary input folder */
@@ -65,8 +66,8 @@ static CamelFolder *open_folder(FilterDriver *d, const char *folder_url);
static int close_folders(FilterDriver *d);
static ESExpResult *do_delete(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
-static ESExpResult *do_forward(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
-static ESExpResult *do_copy(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
+static ESExpResult *mark_forward(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
+static ESExpResult *mark_copy(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
static ESExpResult *do_stop(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *);
static struct {
@@ -76,8 +77,8 @@ static struct {
doesn't execute everything, 0 otherwise */
} symbols[] = {
{ "delete", (ESExpFunc *)do_delete, 0 },
- { "forward-to", (ESExpFunc *)do_forward, 0 },
- { "copy-to", (ESExpFunc *)do_copy, 0 },
+ { "forward-to", (ESExpFunc *)mark_forward, 0 },
+ { "copy-to", (ESExpFunc *)mark_copy, 0 },
{ "stop", (ESExpFunc *)do_stop, 0 },
};
@@ -337,47 +338,41 @@ static ESExpResult *
do_delete(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
{
struct _FilterDriverPrivate *p = _PRIVATE(d);
- GList *m;
+ char *uid;
+ int i;
printf("doing delete\n");
- m = p->matches;
- while (m) {
- printf(" %s\n", (char *)m->data);
-
- camel_folder_delete_message (p->source, m->data, p->ex);
- if (g_hash_table_lookup(p->processed, m->data) == NULL) {
- g_hash_table_insert(p->processed, g_strdup(m->data), (void *)1);
- }
+ for (i = 0; i < p->matches->len; i++) {
+ uid = p->matches->pdata[i];
+ printf(" %s\n", uid);
- m = m->next;
+ camel_folder_delete_message (p->source, uid, p->ex);
}
return NULL;
}
static ESExpResult *
-do_forward(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
+mark_forward(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
{
struct _FilterDriverPrivate *p = _PRIVATE(d);
- GList *m;
+ int i;
- printf("doing forward on the following messages:\n");
- m = p->matches;
- while (m) {
- printf(" %s\n", (char *)m->data);
- m = m->next;
+ printf("marking the following messages for forwarding:\n");
+ for (i = 0; i < p->matches->len; i++) {
+ printf(" %s\n", (char *)p->matches->pdata[i]);
}
return NULL;
}
static ESExpResult *
-do_copy(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
+mark_copy(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
{
- GList *m;
- int i;
+ int i, m;
+ char *uid;
struct _FilterDriverPrivate *p = _PRIVATE(d);
- printf("doing copy\n");
- for (i=0;i<argc;i++) {
+ printf("marking for copy\n");
+ for (i = 0; i < argc; i++) {
if (argv[i]->type == ESEXP_RES_STRING) {
char *folder = argv[i]->value.string;
CamelFolder *outbox;
@@ -386,22 +381,16 @@ do_copy(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
if (outbox == NULL)
continue;
- m = p->matches;
- while (m) {
- CamelMimeMessage *mm;
-
- printf("appending message %s to %s\n", (char *)m->data, folder);
+ for (m = 0; m < p->matches->len; m++) {
+ gpointer old_key, old_value;
- mm = camel_folder_get_message(p->source, m->data, p->ex);
- camel_folder_append_message(outbox, mm, p->ex);
- gtk_object_unref((GtkObject *)mm);
+ uid = p->matches->pdata[m];
+ printf(" %s\n", uid);
- if (!camel_exception_is_set(p->ex) &&
- g_hash_table_lookup(p->processed, m->data) == NULL) {
- g_hash_table_insert(p->processed, g_strdup(m->data), (void *)1);
- }
-
- m = m->next;
+ if (g_hash_table_lookup_extended(p->copies, uid, &old_key, &old_value))
+ g_hash_table_insert(p->copies, old_key, g_list_prepend(old_value, outbox));
+ else
+ g_hash_table_insert(p->copies, g_strdup(uid), g_list_append(NULL, outbox));
}
}
}
@@ -412,18 +401,15 @@ do_copy(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
static ESExpResult *
do_stop(struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d)
{
- GList *m;
+ int i;
+ char *uid;
struct _FilterDriverPrivate *p = _PRIVATE(d);
printf("doing stop on the following messages:\n");
- m = p->matches;
- while (m) {
- printf(" %s\n", (char *)m->data);
- g_hash_table_insert(p->terminated, g_strdup(m->data), (void *)1);
- if (g_hash_table_lookup(p->processed, m->data) == NULL) {
- g_hash_table_insert(p->processed, g_strdup(m->data), (void *)1);
- }
- m = m->next;
+ for (i = 0; i < p->matches->len; i++) {
+ uid = p->matches->pdata[i];
+ printf(" %s\n", uid);
+ g_hash_table_insert(p->terminated, g_strdup(uid), (void *)1);
}
return NULL;
}
@@ -489,6 +475,12 @@ filter_driver_rule_get(FilterDriver *d, int n)
return g_list_nth_data(p->options, n);
}
+static void
+free_key (gpointer key, gpointer value, gpointer user_data)
+{
+ g_free(key);
+}
+
int
filter_driver_run(FilterDriver *d, CamelFolder *source, CamelFolder *inbox)
{
@@ -497,7 +489,7 @@ filter_driver_run(FilterDriver *d, CamelFolder *source, CamelFolder *inbox)
GList *options;
GString *s, *a;
GPtrArray *all;
- GList *m;
+ char *uid;
int i;
#warning "This must be made mega-robust"
@@ -507,6 +499,7 @@ filter_driver_run(FilterDriver *d, CamelFolder *source, CamelFolder *inbox)
p->folders = g_hash_table_new(g_str_hash, g_str_equal);
p->terminated = g_hash_table_new(g_str_hash, g_str_equal);
p->processed = g_hash_table_new(g_str_hash, g_str_equal);
+ p->copies = g_hash_table_new(g_str_hash, g_str_equal);
camel_exception_init(p->ex);
camel_folder_freeze(inbox);
@@ -519,17 +512,21 @@ filter_driver_run(FilterDriver *d, CamelFolder *source, CamelFolder *inbox)
a = g_string_new("");
filter_driver_expand_option(d, s, a, fo);
- p->matches = camel_folder_search_by_expression (p->source, s->str, p->ex);
+ p->matches = camel_folder_search_by_expression (p->source, s->str, p->ex);
/* remove uid's for which processing is complete ... */
- m = p->matches;
- while (m) {
- GList *n = m->next;
+ for (i = 0; i < p->matches->len; i++) {
+ uid = p->matches->pdata[i];
+
+ /* for all matching id's, so we can work out what to default */
+ if (g_hash_table_lookup(p->processed, uid) == NULL) {
+ g_hash_table_insert(p->processed, g_strdup(uid), (void *)1);
+ }
- if (g_hash_table_lookup(p->terminated, m->data)) {
- p->matches = g_list_remove_link(p->matches, m);
+ if (g_hash_table_lookup(p->terminated, uid)) {
+ g_ptr_array_remove_index_fast(p->matches, i);
+ i--;
}
- m = n;
}
e_sexp_input_text(p->eval, a->str, strlen(a->str));
@@ -540,35 +537,51 @@ filter_driver_run(FilterDriver *d, CamelFolder *source, CamelFolder *inbox)
g_string_free(s, TRUE);
g_string_free(a, TRUE);
- g_list_free(p->matches);
+ g_strfreev((char **)p->matches->pdata);
+ g_ptr_array_free(p->matches, FALSE);
options = g_list_next(options);
}
- /* apply the default of copying to an inbox, if we are given one, and make sure
- we delete everything as well */
+ /* Do any queued copies, and make sure everything is deleted from
+ * the source. If we have an inbox, anything that didn't get
+ * processed otherwise goes there.
+ */
all = camel_folder_get_uids(p->source, p->ex);
for (i = 0; i < all->len; i++) {
char *uid = all->pdata[i], *procuid;
+ GList *copies, *tmp;
CamelMimeMessage *mm;
+ copies = g_hash_table_lookup(p->copies, uid);
procuid = g_hash_table_lookup(p->processed, uid);
- if (procuid == NULL) {
- if (inbox) {
- printf("Applying default rule to message %s\n", uid);
- mm = camel_folder_get_message(p->source, uid, p->ex);
+ if (copies || !procuid) {
+ mm = camel_folder_get_message(p->source, uid, p->ex);
+
+ while (copies) {
+ camel_folder_append_message(copies->data, mm, p->ex);
+ tmp = copies->next;
+ g_list_free_1(copies);
+ copies = tmp;
+ }
+
+ if (!procuid) {
+ printf("Applying default rule to message %s\n", uid);
camel_folder_append_message(inbox, mm, p->ex);
- gtk_object_unref((GtkObject *)mm);
- camel_folder_delete_message(p->source, uid, p->ex);
}
- } else {
- camel_folder_delete_message(p->source, uid, p->ex);
+
+ gtk_object_unref((GtkObject *)mm);
}
+ camel_folder_delete_message(p->source, uid, p->ex);
}
camel_folder_free_uids(p->source, all);
+ g_hash_table_foreach(p->copies, free_key, NULL);
+ g_hash_table_destroy(p->copies);
+ g_hash_table_foreach(p->processed, free_key, NULL);
g_hash_table_destroy(p->processed);
+ g_hash_table_foreach(p->terminated, free_key, NULL);
g_hash_table_destroy(p->terminated);
close_folders(d);
g_hash_table_destroy(p->folders);