diff options
-rw-r--r-- | filter/ChangeLog | 33 | ||||
-rw-r--r-- | filter/filter-datespec.c | 4 | ||||
-rw-r--r-- | filter/filter-element.c | 10 | ||||
-rw-r--r-- | filter/filter-element.h | 4 | ||||
-rw-r--r-- | filter/filter-folder.c | 4 | ||||
-rw-r--r-- | filter/filter-input.c | 10 | ||||
-rw-r--r-- | filter/filter-message-search.c | 73 | ||||
-rw-r--r-- | filter/filter-option.c | 15 | ||||
-rw-r--r-- | filter/filter-part.c | 4 | ||||
-rw-r--r-- | filter/filtertypes.xml | 89 | ||||
-rw-r--r-- | filter/libfilter-i18n.h | 4 |
11 files changed, 143 insertions, 107 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog index 15f23b1762..a1cef8c4d5 100644 --- a/filter/ChangeLog +++ b/filter/ChangeLog @@ -1,5 +1,36 @@ -2000-11-21 Jeffrey Stedfast <fejj@helixcode.com> +2000-11-27 Jeffrey Stedfast <fejj@helixcode.com> + + * filtertypes.xml: Moved the regex filter rule around - we've + changed the format a bit. + + * filter-option.c (option_activate): Removed. + (get_widget): Don't connect the activate signal. + + * filter-folder.c (validate): Updated. + + * filter-datespec.c (validate): Updated. + + * filter-part.c (filter_part_validate): Updated. + + * filter-input.c (validate): Check the filter-input type - if it's + of type "regex", then check for regex validity. + * filter-element.c (filter_element_validate): No longer takes a + gpointer argument. + (filter_element_new_type_name): Allow type "regex" and create a + new filter-input with type "regex". + +2000-11-24 Michael Meeks <michael@helixcode.com> + + * filter-message-search.c (get_full_header): impl. + (header_full_regex): use it. + +2000-11-23 Michael Meeks <michael@helixcode.com> + + * filter-message-search.c (header_full_regex): impl. + +2000-11-21 Jeffrey Stedfast <fejj@helixcode.com> + * filter-message-search.c: took out some no longer needed printfs. diff --git a/filter/filter-datespec.c b/filter/filter-datespec.c index db98efd1ef..e5b24d56a9 100644 --- a/filter/filter-datespec.c +++ b/filter/filter-datespec.c @@ -28,7 +28,7 @@ #define d(x) -static gboolean validate (FilterElement *fe, gpointer data); +static gboolean validate (FilterElement *fe); static void xml_create (FilterElement *fe, xmlNodePtr node); static xmlNodePtr xml_encode (FilterElement *fe); static int xml_decode (FilterElement *fe, xmlNodePtr node); @@ -169,7 +169,7 @@ filter_datespec_new (void) } static gboolean -validate (FilterElement *fe, gpointer data) +validate (FilterElement *fe) { FilterDatespec *fds = (FilterDatespec *) fe; gboolean valid = TRUE; diff --git a/filter/filter-element.c b/filter/filter-element.c index 1084ca6ca0..5824eb09f9 100644 --- a/filter/filter-element.c +++ b/filter/filter-element.c @@ -31,7 +31,7 @@ #include "filter-folder.h" #include "filter-url.h" -static gboolean validate (FilterElement *fe, gpointer data); +static gboolean validate (FilterElement *fe); static void xml_create(FilterElement *fe, xmlNodePtr node); static FilterElement *clone(FilterElement *fe); @@ -124,9 +124,9 @@ filter_element_new (void) } gboolean -filter_element_validate (FilterElement *fe, gpointer data) +filter_element_validate (FilterElement *fe) { - return ((FilterElementClass *)((GtkObject *)fe)->klass)->validate (fe, data); + return ((FilterElementClass *)((GtkObject *)fe)->klass)->validate (fe); } /** @@ -262,6 +262,8 @@ filter_element_new_type_name (const char *type) return (FilterElement *)filter_score_new (); } else if (!strcmp (type, "url")) { return (FilterElement *)filter_url_new (); + } else if (!strcmp (type, "regex")) { + return (FilterElement *)filter_input_new_type_name (type); } else { g_warning("Unknown filter type '%s'", type); return 0; @@ -276,7 +278,7 @@ filter_element_set_data (FilterElement *fe, gpointer data) /* default implementations */ static gboolean -validate (FilterElement *fe, gpointer data) +validate (FilterElement *fe) { return TRUE; } diff --git a/filter/filter-element.h b/filter/filter-element.h index 63befc3969..2f784dfa36 100644 --- a/filter/filter-element.h +++ b/filter/filter-element.h @@ -45,7 +45,7 @@ struct _FilterElementClass { GtkObjectClass parent_class; /* virtual methods */ - gboolean (*validate)(FilterElement *fe, gpointer data); + gboolean (*validate)(FilterElement *fe); void (*xml_create)(FilterElement *, xmlNodePtr); xmlNodePtr (*xml_encode)(FilterElement *); @@ -68,7 +68,7 @@ FilterElement *filter_element_new_type_name (const char *type); void filter_element_set_data (FilterElement *fe, gpointer data); /* methods */ -gboolean filter_element_validate (FilterElement *fe, gpointer data); +gboolean filter_element_validate (FilterElement *fe); void filter_element_xml_create (FilterElement *fe, xmlNodePtr node); diff --git a/filter/filter-folder.c b/filter/filter-folder.c index 0fc02a34a1..1a29e31a5e 100644 --- a/filter/filter-folder.c +++ b/filter/filter-folder.c @@ -33,7 +33,7 @@ #define d(x) -static gboolean validate (FilterElement *fe, gpointer data); +static gboolean validate (FilterElement *fe); static void xml_create(FilterElement *fe, xmlNodePtr node); static xmlNodePtr xml_encode(FilterElement *fe); static int xml_decode(FilterElement *fe, xmlNodePtr node); @@ -131,7 +131,7 @@ filter_folder_new (void) } static gboolean -validate (FilterElement *fe, gpointer data) +validate (FilterElement *fe) { FilterFolder *ff = (FilterFolder *) fe; diff --git a/filter/filter-input.c b/filter/filter-input.c index fcee83a9eb..556b895ef1 100644 --- a/filter/filter-input.c +++ b/filter/filter-input.c @@ -29,7 +29,7 @@ #define d(x) -static gboolean validate (FilterElement *fe, gpointer data); +static gboolean validate (FilterElement *fe); static void xml_create(FilterElement *fe, xmlNodePtr node); static xmlNodePtr xml_encode(FilterElement *fe); static int xml_decode(FilterElement *fe, xmlNodePtr node); @@ -157,16 +157,12 @@ filter_input_set_value (FilterInput *fi, const char *value) } static gboolean -validate (FilterElement *fe, gpointer data) +validate (FilterElement *fe) { FilterInput *fi = (FilterInput *)fe; - gboolean is_regex = FALSE; gboolean valid = TRUE; - if (data) - is_regex = GPOINTER_TO_INT (data); - - if (is_regex) { + if (!strcmp (fi->type, "regex")) { regex_t regexpat; /* regex patern */ gint regerr; char *text; diff --git a/filter/filter-message-search.c b/filter/filter-message-search.c index a4db6c4373..d374422dfd 100644 --- a/filter/filter-message-search.c +++ b/filter/filter-message-search.c @@ -41,6 +41,7 @@ static ESExpResult *header_ends_with (struct _ESExp *f, int argc, struct _ESExpR static ESExpResult *header_exists (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *header_soundex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); +static ESExpResult *header_full_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *match_all (struct _ESExp *f, int argc, struct _ESExpTerm **argv, FilterMessageSearch *fms); static ESExpResult *body_contains (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *body_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); @@ -69,6 +70,7 @@ static struct { { "header-exists", (ESExpFunc *) header_exists, 0 }, { "header-soundex", (ESExpFunc *) header_soundex, 0 }, { "header-regex", (ESExpFunc *) header_regex, 0 }, + { "header-full-regex", (ESExpFunc *) header_full_regex, 0 }, { "user-tag", (ESExpFunc *) user_tag, 0 }, { "user-flag", (ESExpFunc *) user_flag, 0 }, { "get-sent-date", (ESExpFunc *) get_sent_date, 0 }, @@ -372,7 +374,75 @@ header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMess regmsg = g_malloc0 (reglen + 1); regerror (regerr, ®expat, regmsg, reglen); camel_exception_setv (fms->ex, CAMEL_EXCEPTION_SYSTEM, - "Failed to perform regex search on message body: %s", + _("Failed to perform regex search on message header: %s"), + regmsg); + g_free (regmsg); + regfree (®expat); + } else { + if (contents) { + fltmatch = g_new0 (regmatch_t, regexpat.re_nsub); + + if (!regexec (®expat, contents, regexpat.re_nsub, fltmatch, 0)) + matched = TRUE; + + g_free (fltmatch); + regfree (®expat); + } + } + } + + r = e_sexp_result_new (ESEXP_RES_BOOL); + r->value.bool = matched; + + return r; +} + +static gchar * +get_full_header (CamelMimeMessage *message) +{ + CamelMimePart *mp = CAMEL_MIME_PART (message); + GString *str = g_string_new (""); + char *ret; + struct _header_raw *h; + + for (h = mp->headers; h; h = h->next) { + if (h->value != NULL) + g_string_sprintfa (str, "%s%s%s\n", h->name, + isspace (h->value[0]) ? ":" : ": ", h->value); + } + + ret = str->str; + g_string_free (str, FALSE); + + return ret; +} + +static ESExpResult * +header_full_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms) +{ + gboolean matched = FALSE; + ESExpResult *r; + + if (argc == 1) { + char *match = (argv[0])->value.string; + regex_t regexpat; /* regex patern */ + regmatch_t *fltmatch; + gint regerr = 0; + size_t reglen = 0; + gchar *regmsg; + char *contents; + + contents = get_full_header (fms->message); + + regerr = regcomp (®expat, match, REG_EXTENDED | REG_NEWLINE | REG_ICASE); + if (regerr) { + /* regerror gets called twice to get the full error string + length to do proper posix error reporting */ + reglen = regerror (regerr, ®expat, 0, 0); + regmsg = g_malloc0 (reglen + 1); + regerror (regerr, ®expat, regmsg, reglen); + camel_exception_setv (fms->ex, CAMEL_EXCEPTION_SYSTEM, + _("Failed to perform regex search on message header: %s"), regmsg); g_free (regmsg); regfree (®expat); @@ -387,6 +457,7 @@ header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMess regfree (®expat); } } + g_free (contents); } r = e_sexp_result_new (ESEXP_RES_BOOL); diff --git a/filter/filter-option.c b/filter/filter-option.c index bdac9288d3..a6bcaad8c1 100644 --- a/filter/filter-option.c +++ b/filter/filter-option.c @@ -231,20 +231,6 @@ xml_decode (FilterElement *fe, xmlNodePtr node) return 0; } -static void -option_activate (GtkMenuItem *item, FilterOption *fo) -{ - FilterElement *fe = (FilterElement *) fo; - gboolean is_regex; - - fo->current = gtk_object_get_data (GTK_OBJECT (item), "option"); - d(printf ("option changed to %s\n", fo->current->title)); - - /* FIXME: there's probably a better way to do this */ - is_regex = !(!strstr (fo->current->title, "regex")); - fe->data = GINT_TO_POINTER (is_regex); -} - static GtkWidget * get_widget (FilterElement *fe) { @@ -261,7 +247,6 @@ get_widget (FilterElement *fe) op = l->data; item = gtk_menu_item_new_with_label (_(op->title)); gtk_object_set_data (GTK_OBJECT (item), "option", op); - gtk_signal_connect (GTK_OBJECT (item), "activate", option_activate, fo); gtk_menu_append (GTK_MENU (menu), item); gtk_widget_show (item); if (op == fo->current) { diff --git a/filter/filter-part.c b/filter/filter-part.c index f32ed517c7..dcd55ac92c 100644 --- a/filter/filter-part.c +++ b/filter/filter-part.c @@ -117,16 +117,14 @@ gboolean filter_part_validate (FilterPart *fp) { gboolean correct = TRUE; - FilterElement *last = NULL; GList *l; l = fp->elements; while (l && correct) { FilterElement *fe = l->data; - correct = filter_element_validate (fe, last ? last->data : NULL); + correct = filter_element_validate (fe); - last = fe; l = l->next; } diff --git a/filter/filtertypes.xml b/filter/filtertypes.xml index 3fa396f57b..3014d453df 100644 --- a/filter/filtertypes.xml +++ b/filter/filtertypes.xml @@ -64,18 +64,6 @@ (match-all (not (header-soundex "From" ${sender}))) </code> </option> - <option value="matches regex"> - <title>matches regex</title> - <code> - (match-all (header-regex "From" ${sender})) - </code> - </option> - <option value="not match regex"> - <title>does not match regex</title> - <code> - (match-all (not (header-regex "From" ${sender}))) - </code> - </option> </input> <input type="string" name="sender"/> </part> @@ -158,21 +146,6 @@ (header-soundex "Cc" ${recipient})))) </code> </option> - <option value="matches regex"> - <title>matches regex</title> - <code> - (match-all (or (header-regex "To" ${recipient}) - (header-regex "Cc" ${recipient}))) - </code> - </option> - <option value="not match regex"> - <title>does not match regex</title> - <code> - (match-all (not (or - (header-regex "To" ${recipient}) - (header-regex "Cc" ${recipient})))) - </code> - </option> </input> <input type="address" name="recipient"/> </part> @@ -240,18 +213,6 @@ (match-all (not (header-soundex "Subject" ${subject}))) </code> </option> - <option value="matches regex"> - <title>matches regex</title> - <code> - (match-all (header-regex "Subject" ${subject})) - </code> - </option> - <option value="not match regex"> - <title>does not match regex</title> - <code> - (match-all (not (header-regex "Subject" ${subject})) - </code> - </option> </input> <input type="string" name="subject"/> </part> @@ -332,18 +293,6 @@ (match-all (not (header-soundex ${header-field} ${word}))) </code> </option> - <option value="matches regex"> - <title>matches regex</title> - <code> - (match-all (header-regex ${header-field} ${word})) - </code> - </option> - <option value="not match regex"> - <title>does not match regex</title> - <code> - (match-all (not (header-regex ${header-field} ${word})) - </code> - </option> </input> <input type="string" name="word"/> </part> @@ -363,18 +312,6 @@ (not (body-contains ${word})) </code> </option> - <option value="matches regex"> - <title>matches regex</title> - <code> - (body-regex ${word}) - </code> - </option> - <option value="not match regex"> - <title>does not match regex</title> - <code> - (not (body-regex ${word})) - </code> - </option> </input> <input type="string" name="word"/> </part> @@ -412,8 +349,7 @@ </code> </option> </input> - <input type="datespec" name="versus"> - </input> + <input type="datespec" name="versus"/> </part> <part name="recv-date"> @@ -444,8 +380,7 @@ </code> </option> </input> - <input type="datespec" name="versus"> - </input> + <input type="datespec" name="versus"/> </part> <part name="score"> @@ -476,8 +411,26 @@ </code> </option> </input> - <input type="score" name="versus"> + <input type="score" name="versus"/> + </part> + + <part name="regex"> + <title>Regex Match</title> + <input type="optionlist" name="match-type"> + <option value="header"> + <title>Message Header</title> + <code> + (match-all (header-full-regex ${expression})) + </code> + </option> + <option value="body"> + <title>Message Body</title> + <code> + (match-all (body-regex ${expression})) + </code> + </option> </input> + <input type="regex" name="expression"/> </part> <part name="source"> diff --git a/filter/libfilter-i18n.h b/filter/libfilter-i18n.h index c725cb7bae..a74bcadd31 100644 --- a/filter/libfilter-i18n.h +++ b/filter/libfilter-i18n.h @@ -12,11 +12,13 @@ char *s = N_("Expression"); char *s = N_("Flagged"); char *s = N_("Forward to Address"); char *s = N_("Message Body"); +char *s = N_("Message Header"); char *s = N_("Message was received"); char *s = N_("Message was sent"); char *s = N_("Move to Folder"); char *s = N_("Priority"); char *s = N_("Recipients"); +char *s = N_("Regex Match"); char *s = N_("Seen"); char *s = N_("Sender"); char *s = N_("Set Flag"); @@ -30,7 +32,6 @@ char *s = N_("contains"); char *s = N_("does not contain"); char *s = N_("does not end with"); char *s = N_("does not exist"); -char *s = N_("does not match regex"); char *s = N_("does not sound like"); char *s = N_("does not start with"); char *s = N_("ends with"); @@ -39,7 +40,6 @@ char *s = N_("is greater than"); char *s = N_("is less than"); char *s = N_("is not"); char *s = N_("is"); -char *s = N_("matches regex"); char *s = N_("on or after"); char *s = N_("on or before"); char *s = N_("sounds like"); |