aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filter/ChangeLog33
-rw-r--r--filter/filter-datespec.c4
-rw-r--r--filter/filter-element.c10
-rw-r--r--filter/filter-element.h4
-rw-r--r--filter/filter-folder.c4
-rw-r--r--filter/filter-input.c10
-rw-r--r--filter/filter-message-search.c73
-rw-r--r--filter/filter-option.c15
-rw-r--r--filter/filter-part.c4
-rw-r--r--filter/filtertypes.xml89
-rw-r--r--filter/libfilter-i18n.h4
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, &regexpat, 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 (&regexpat);
+ } else {
+ if (contents) {
+ fltmatch = g_new0 (regmatch_t, regexpat.re_nsub);
+
+ if (!regexec (&regexpat, contents, regexpat.re_nsub, fltmatch, 0))
+ matched = TRUE;
+
+ g_free (fltmatch);
+ regfree (&regexpat);
+ }
+ }
+ }
+
+ 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 (&regexpat, 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, &regexpat, 0, 0);
+ regmsg = g_malloc0 (reglen + 1);
+ regerror (regerr, &regexpat, regmsg, reglen);
+ camel_exception_setv (fms->ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to perform regex search on message header: %s"),
regmsg);
g_free (regmsg);
regfree (&regexpat);
@@ -387,6 +457,7 @@ header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMess
regfree (&regexpat);
}
}
+ 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");