Updated to allow the user to select "sounds like" or "does not sound like"
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) svn path=/trunk/; revision=6302
This commit is contained in:
committed by
Jeffrey Stedfast
parent
92fd4e32e4
commit
1d60c5cc02
@ -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.
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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");
|
||||
|
||||
Reference in New Issue
Block a user