[evolution-data-server] Bug #391472 - Add ability to match headers by words
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #391472 - Add ability to match headers by words
- Date: Tue, 7 Feb 2012 17:42:09 +0000 (UTC)
commit e3da65f2d5537d8d60e4d7009f03335552f1788f
Author: Milan Crha <mcrha redhat com>
Date: Tue Feb 7 18:41:12 2012 +0100
Bug #391472 - Add ability to match headers by words
camel/camel-filter-search.c | 11 +++++++
camel/camel-folder-search.c | 12 +++++++-
camel/camel-search-private.c | 61 +++++++++++++++++++++++++++++++++++++++++
camel/camel-search-private.h | 1 +
camel/camel-search-sql-sexp.c | 14 +++++++++-
5 files changed, 97 insertions(+), 2 deletions(-)
---
diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c
index 0e55982..668fb2f 100644
--- a/camel/camel-filter-search.c
+++ b/camel/camel-filter-search.c
@@ -70,6 +70,7 @@ typedef struct {
/* CamelSExp callbacks */
static CamelSExpResult *header_contains (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms);
+static CamelSExpResult *header_has_words (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms);
static CamelSExpResult *header_matches (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms);
static CamelSExpResult *header_starts_with (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms);
static CamelSExpResult *header_ends_with (struct _CamelSExp *f, gint argc, struct _CamelSExpResult **argv, FilterMessageSearch *fms);
@@ -103,6 +104,7 @@ static struct {
{ "body-contains", (CamelSExpFunc) body_contains, 0 },
{ "body-regex", (CamelSExpFunc) body_regex, 0 },
{ "header-contains", (CamelSExpFunc) header_contains, 0 },
+ { "header-has-words", (CamelSExpFunc) header_has_words, 0 },
{ "header-matches", (CamelSExpFunc) header_matches, 0 },
{ "header-starts-with", (CamelSExpFunc) header_starts_with, 0 },
{ "header-ends-with", (CamelSExpFunc) header_ends_with, 0 },
@@ -270,6 +272,15 @@ header_contains (struct _CamelSExp *f,
}
static CamelSExpResult *
+header_has_words (struct _CamelSExp *f,
+ gint argc,
+ struct _CamelSExpResult **argv,
+ FilterMessageSearch *fms)
+{
+ return check_header (f, argc, argv, fms, CAMEL_SEARCH_MATCH_WORD);
+}
+
+static CamelSExpResult *
header_matches (struct _CamelSExp *f,
gint argc,
struct _CamelSExpResult **argv,
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 973130a..4fa136f 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -573,7 +573,17 @@ static gboolean
do_search_in_memory (const gchar *expr)
{
/* if the expression contains any of these tokens, then perform a memory search, instead of the SQL one */
- const gchar *in_memory_tokens[] = { "body-contains", "body-regex", "match-threads", "message-location", "header-soundex", "header-regex", "header-full-regex", "header-contains", NULL };
+ const gchar *in_memory_tokens[] = {
+ "body-contains",
+ "body-regex",
+ "match-threads",
+ "message-location",
+ "header-soundex",
+ "header-regex",
+ "header-full-regex",
+ "header-contains",
+ "header-has-words",
+ NULL };
gint i;
if (!expr)
diff --git a/camel/camel-search-private.c b/camel/camel-search-private.c
index d196326..645a5a7 100644
--- a/camel/camel-search-private.c
+++ b/camel/camel-search-private.c
@@ -294,6 +294,65 @@ camel_ustrcasecmp (const gchar *ps1,
return 0;
}
+static gchar *
+depunct_string (const gchar *str)
+{
+ gchar *res;
+ gint ii;
+
+ g_return_val_if_fail (str != NULL, NULL);
+
+ res = g_strdup (str);
+ for (ii = 0; res[ii]; ii++) {
+ if (ispunct (res[ii]))
+ res[ii] = ' ';
+ }
+
+ return res;
+}
+
+static gboolean
+camel_uwordcase (const gchar *haystack,
+ const gchar *needle)
+{
+ struct _camel_search_words *hwords, *nwords;
+ gchar *copy_haystack, *copy_needle;
+ gboolean found_all;
+ gint ii, jj;
+
+ g_return_val_if_fail (haystack != NULL, FALSE);
+ g_return_val_if_fail (needle != NULL, FALSE);
+
+ if (!*needle)
+ return TRUE;
+ if (!*haystack)
+ return FALSE;
+
+ copy_haystack = depunct_string (haystack);
+ copy_needle = depunct_string (needle);
+ hwords = camel_search_words_split ((const guchar *) copy_haystack);
+ nwords = camel_search_words_split ((const guchar *) copy_needle);
+ g_free (copy_haystack);
+ g_free (copy_needle);
+
+ found_all = TRUE;
+ for (ii = 0; ii < nwords->len && found_all; ii++) {
+ found_all = FALSE;
+
+ for (jj = 0; jj < hwords->len; jj++) {
+ if (camel_ustrcasecmp (hwords->words[jj]->word, nwords->words[ii]->word) == 0) {
+ found_all = TRUE;
+ break;
+ }
+ }
+ }
+
+ camel_search_words_free (hwords);
+ camel_search_words_free (nwords);
+
+ return found_all;
+}
+
static gint
camel_ustrncasecmp (const gchar *ps1,
const gchar *ps2,
@@ -353,6 +412,8 @@ header_match (const gchar *value,
return camel_ustrcasecmp (value, match) == 0;
case CAMEL_SEARCH_MATCH_CONTAINS:
return camel_ustrstrcase (value, match) != NULL;
+ case CAMEL_SEARCH_MATCH_WORD:
+ return camel_uwordcase (value, match);
case CAMEL_SEARCH_MATCH_STARTS:
return camel_ustrncasecmp (value, match, mlen) == 0;
case CAMEL_SEARCH_MATCH_ENDS:
diff --git a/camel/camel-search-private.h b/camel/camel-search-private.h
index a6e4b81..8302ff9 100644
--- a/camel/camel-search-private.h
+++ b/camel/camel-search-private.h
@@ -41,6 +41,7 @@ typedef enum {
typedef enum {
CAMEL_SEARCH_MATCH_EXACT,
CAMEL_SEARCH_MATCH_CONTAINS,
+ CAMEL_SEARCH_MATCH_WORD,
CAMEL_SEARCH_MATCH_STARTS,
CAMEL_SEARCH_MATCH_ENDS,
CAMEL_SEARCH_MATCH_SOUNDEX
diff --git a/camel/camel-search-sql-sexp.c b/camel/camel-search-sql-sexp.c
index aac19a2..07f6146 100644
--- a/camel/camel-search-sql-sexp.c
+++ b/camel/camel-search-sql-sexp.c
@@ -384,7 +384,7 @@ check_header (struct _CamelSExp *f,
gchar *value = NULL, *tstr = NULL;
if (argv[i]->value.string[0] == 0)
continue;
- if (how == CAMEL_SEARCH_MATCH_CONTAINS) {
+ if (how == CAMEL_SEARCH_MATCH_CONTAINS || how == CAMEL_SEARCH_MATCH_WORD) {
tstr = g_strdup_printf ("%c%s%c", '%', argv[i]->value.string, '%');
value = get_db_safe_string (tstr);
g_free (tstr);
@@ -427,6 +427,17 @@ header_contains (struct _CamelSExp *f,
}
static CamelSExpResult *
+header_has_words (struct _CamelSExp *f,
+ gint argc,
+ struct _CamelSExpResult **argv,
+ gpointer data)
+{
+ d(printf("executing header-has-word: %d", argc));
+
+ return check_header (f, argc, argv, data, CAMEL_SEARCH_MATCH_WORD);
+}
+
+static CamelSExpResult *
header_matches (struct _CamelSExp *f,
gint argc,
struct _CamelSExpResult **argv,
@@ -675,6 +686,7 @@ static struct {
{ "match-threads", (CamelSExpFunc)match_threads, 1 },
/* { "body-contains", body_contains}, */ /* We don't store body on the db. */
{ "header-contains", header_contains, 0},
+ { "header-has-words", header_has_words, 0},
{ "header-matches", header_matches, 0},
{ "header-starts-with", header_starts_with, 0},
{ "header-ends-with", header_ends_with, 0},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]