diff options
-rw-r--r-- | filter/ChangeLog | 13 | ||||
-rw-r--r-- | filter/filter-message-search.c | 89 | ||||
-rw-r--r-- | filter/filtertypes.xml | 51 | ||||
-rw-r--r-- | filter/libfilter-i18n.h | 2 |
4 files changed, 149 insertions, 6 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog index f4bb2470bc..72b07bc94e 100644 --- a/filter/ChangeLog +++ b/filter/ChangeLog @@ -1,5 +1,18 @@ 2000-10-31 Jeffrey Stedfast <fejj@helixcode.com> + * filtertypes.xml: Updated to allow the user to select "sounds + like" or "does not sound like" (uses header-soundex). + + * filter-message-search.c (header_matches): Oops. Should be using + !g_strncasecmp. This should fix it so this filter match works + right. + (header_starts_with): Same. + (header_ends_with): Same. + (header_soundex): New filter callback for soundex matching (yes, + it's probably a bloated feature but hey, it was fun to code) + +2000-10-31 Jeffrey Stedfast <fejj@helixcode.com> + * filter-folder.c (validate): Override the default validate function to only return TRUE if a folder has been selected. diff --git a/filter/filter-message-search.c b/filter/filter-message-search.c index 81955671d1..2e09489843 100644 --- a/filter/filter-message-search.c +++ b/filter/filter-message-search.c @@ -39,6 +39,7 @@ static ESExpResult *header_matches (struct _ESExp *f, int argc, struct _ESExpRes static ESExpResult *header_starts_with (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *header_ends_with (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); 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 *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); @@ -66,6 +67,7 @@ static struct { { "header-starts-with", (ESExpFunc *) header_starts_with, 0 }, { "header-ends-with", (ESExpFunc *) header_ends_with, 0 }, { "header-exists", (ESExpFunc *) header_exists, 0 }, + { "header-soundex", (ESExpFunc *) header_soundex, 0 }, { "header-regex", (ESExpFunc *) header_regex, 0 }, { "user-tag", (ESExpFunc *) user_tag, 0 }, { "user-flag", (ESExpFunc *) user_flag, 0 }, @@ -130,10 +132,10 @@ header_matches (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMe } if (is_lowercase) { - if (g_strcasecmp (contents, match)) + if (!g_strcasecmp (contents, match)) matched = TRUE; } else { - if (strcmp (contents, match)) + if (!strcmp (contents, match)) matched = TRUE; } } @@ -174,10 +176,10 @@ header_starts_with (struct _ESExp *f, int argc, struct _ESExpResult **argv, Filt } if (is_lowercase) { - if (g_strncasecmp (contents, match, strlen (match))) + if (!g_strncasecmp (contents, match, strlen (match))) matched = TRUE; } else { - if (strncmp (contents, match, strlen (match))) + if (!strncmp (contents, match, strlen (match))) matched = TRUE; } } @@ -220,10 +222,10 @@ header_ends_with (struct _ESExp *f, int argc, struct _ESExpResult **argv, Filter end = (char *) contents + strlen (contents) - strlen (match); if (is_lowercase) { - if (g_strcasecmp (end, match)) + if (!g_strcasecmp (end, match)) matched = TRUE; } else { - if (strcmp (end, match)) + if (!strcmp (end, match)) matched = TRUE; } } @@ -257,6 +259,81 @@ header_exists (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMes return r; } +static unsigned char soundex_table[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 49, 50, 51, 0, 49, 50, 0, 0, 50, 50, 52, 53, 53, 0, + 49, 50, 54, 50, 51, 0, 49, 0, 50, 0, 50, 0, 0, 0, 0, 0, + 0, 0, 49, 50, 51, 0, 49, 50, 0, 0, 50, 50, 52, 53, 53, 0, + 49, 50, 54, 50, 51, 0, 49, 0, 50, 0, 50, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static void +soundexify (const gchar *sound, gchar code[5]) +{ + guchar *c, last = '\0'; + gint n; + + for (c = (guchar *) sound; *c && !isalpha (*c); c++); + code[0] = toupper (*c); + memset (code + 1, '0', 3); + for (n = 1; *c && n < 5; c++) { + guchar ch = soundex_table[*c]; + + if (ch && ch != last) { + code[n++] = ch; + last = ch; + } + } + code[4] = '\0'; +} + +static gint +soundexcmp (const gchar *sound1, const gchar *sound2) +{ + gchar code1[5], code2[5]; + + soundexify (sound1, code1); + soundexify (sound2, code2); + + return strcmp (code1, code2); +} + +static ESExpResult * +header_soundex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms) +{ + gboolean matched = FALSE; + ESExpResult *r; + + if (argc == 2) { + char *header = (argv[0])->value.string; + char *match = (argv[1])->value.string; + const char *contents; + + contents = camel_medium_get_header (CAMEL_MEDIUM (fms->message), header); + + if (contents) { + if (!soundexcmp (contents, match)) + matched = TRUE; + } + } + + r = e_sexp_result_new (ESEXP_RES_BOOL); + r->value.bool = matched; + + return r; +} + static ESExpResult * header_regex (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms) { diff --git a/filter/filtertypes.xml b/filter/filtertypes.xml index 9b6946c030..3fa396f57b 100644 --- a/filter/filtertypes.xml +++ b/filter/filtertypes.xml @@ -52,6 +52,18 @@ (match-all (not (header-ends-with "From" ${sender}))) </code> </option> + <option value="matches soundex"> + <title>sounds like</title> + <code> + (match-all (header-soundex "From" ${sender})) + </code> + </option> + <option value="not match soundex"> + <title>does not sound like</title> + <code> + (match-all (not (header-soundex "From" ${sender}))) + </code> + </option> <option value="matches regex"> <title>matches regex</title> <code> @@ -131,6 +143,21 @@ (header-ends-with "Cc" ${recipient})))) </code> </option> + <option value="matches soundex"> + <title>sounds like</title> + <code> + (match-all (or (header-soundex "To" ${recipient}) + (header-soundex "Cc" ${recipient}))) + </code> + </option> + <option value="not match soundex"> + <title>does not sound like</title> + <code> + (match-all (not (or + (header-soundex "To" ${recipient}) + (header-soundex "Cc" ${recipient})))) + </code> + </option> <option value="matches regex"> <title>matches regex</title> <code> @@ -201,6 +228,18 @@ (match-all (not (header-ends-with "Subject" ${subject})) </code> </option> + <option value="matches soundex"> + <title>sounds like</title> + <code> + (match-all (header-soundex "Subject" ${subject})) + </code> + </option> + <option value="not match soundex"> + <title>does not sound like</title> + <code> + (match-all (not (header-soundex "Subject" ${subject}))) + </code> + </option> <option value="matches regex"> <title>matches regex</title> <code> @@ -281,6 +320,18 @@ (match-all (not (header-exists ${header-field})) </code> </option> + <option value="matches soundex"> + <title>sounds like</title> + <code> + (match-all (header-soundex ${header-field} ${word})) + </code> + </option> + <option value="not match soundex"> + <title>does not sound like</title> + <code> + (match-all (not (header-soundex ${header-field} ${word}))) + </code> + </option> <option value="matches regex"> <title>matches regex</title> <code> diff --git a/filter/libfilter-i18n.h b/filter/libfilter-i18n.h index 3cac52183b..c725cb7bae 100644 --- a/filter/libfilter-i18n.h +++ b/filter/libfilter-i18n.h @@ -31,6 +31,7 @@ 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"); char *s = N_("exists"); @@ -41,6 +42,7 @@ 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"); char *s = N_("starts with"); char *s = N_("was after"); char *s = N_("was before"); |