changeset 1069:8024a2cdc406 HEAD

Several search fixes, mostly related to matching multiple conditions.
author Timo Sirainen <tss@iki.fi>
date Sat, 01 Feb 2003 13:24:17 +0200
parents be54621f4079
children 5c34c363a062
files src/lib-storage/index/index-search.c src/lib-storage/mail-search.c src/lib-storage/mail-search.h
diffstat 3 files changed, 59 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-search.c	Sat Feb 01 12:29:17 2003 +0200
+++ b/src/lib-storage/index/index-search.c	Sat Feb 01 13:24:17 2003 +0200
@@ -19,12 +19,6 @@
 #include <stdlib.h>
 #include <ctype.h>
 
-#define ARG_SET_RESULT(arg, res) \
-	STMT_START { \
-		(arg)->result = !(arg)->not ? (res) : \
-			(res) == -1 ? -1 : !(res); \
-	} STMT_END
-
 #define TXT_UNKNOWN_CHARSET "[BADCHARSET] Unknown charset"
 #define TXT_INVALID_SEARCH_KEY "Invalid search key"
 
@@ -211,7 +205,7 @@
 		/* unknown */
 		break;
 	case 0:
-		ARG_SET_RESULT(arg, -1);
+		ARG_SET_RESULT(arg, 0);
 		break;
 	default:
 		ARG_SET_RESULT(arg, 1);
@@ -280,7 +274,7 @@
 		/* unknown */
 		break;
 	case 0:
-		ARG_SET_RESULT(arg, -1);
+		ARG_SET_RESULT(arg, 0);
 		break;
 	default:
 		ARG_SET_RESULT(arg, 1);
@@ -450,7 +444,7 @@
 		/* unknown */
 		break;
 	case 0:
-		ARG_SET_RESULT(arg, -1);
+		ARG_SET_RESULT(arg, 0);
 		break;
 	default:
 		ARG_SET_RESULT(arg, 1);
@@ -543,7 +537,28 @@
 		t_pop();
 	}
 
-        ARG_SET_RESULT(arg, ret);
+	if (ret == 1 ||
+	    (arg->type != SEARCH_TEXT && arg->type != SEARCH_HEADER)) {
+		/* set only when we definitely know if it's a match */
+		ARG_SET_RESULT(arg, ret);
+	}
+}
+
+static void search_header_unmatch(struct mail_search_arg *arg,
+				  void *context __attr_unused__)
+{
+	switch (arg->type) {
+	case SEARCH_FROM:
+	case SEARCH_TO:
+	case SEARCH_CC:
+	case SEARCH_BCC:
+	case SEARCH_SUBJECT:
+	case SEARCH_HEADER:
+		ARG_SET_RESULT(arg, 0);
+		break;
+	default:
+		break;
+	}
 }
 
 static void search_header(struct message_part *part,
@@ -570,6 +585,9 @@
 
 		ctx->custom_header = FALSE;
 		mail_search_args_foreach(ctx->args, search_header_arg, ctx);
+	} else if (name_len == 0) {
+		/* last header, mark all unknown SEARCH_HEADERs unmatched */
+		mail_search_args_foreach(ctx->args, search_header_unmatch, ctx);
 	}
 }
 
--- a/src/lib-storage/mail-search.c	Sat Feb 01 12:29:17 2003 +0200
+++ b/src/lib-storage/mail-search.c	Sat Feb 01 13:24:17 2003 +0200
@@ -8,7 +8,7 @@
 	while (args != NULL) {
 		if (args->type == SEARCH_OR || args->type == SEARCH_SUB)
 			mail_search_args_reset(args->value.subargs);
-		args->result = 0;
+		args->result = -1;
 
 		args = args->next;
 	}
@@ -20,7 +20,7 @@
 {
 	struct mail_search_arg *subarg;
 
-	if (arg->result != 0)
+	if (arg->result != -1)
 		return;
 
 	if (arg->type == SEARCH_SUB) {
@@ -30,18 +30,17 @@
 		arg->result = 1;
 		subarg = arg->value.subargs;
 		while (subarg != NULL) {
-			if (subarg->result == 0)
+			if (subarg->result == -1)
 				search_arg_foreach(subarg, callback, context);
 
-			if (subarg->result == -1) {
-				/* failed */
+			if (subarg->result == -1)
 				arg->result = -1;
+			else if (subarg->result == arg->not) {
+				/* didn't match */
+				arg->result = 0;
 				break;
 			}
 
-			if (subarg->result == 0)
-				arg->result = 0;
-
 			subarg = subarg->next;
 		}
 	} else if (arg->type == SEARCH_OR) {
@@ -51,18 +50,19 @@
 		subarg = arg->value.subargs;
 		arg->result = -1;
 		while (subarg != NULL) {
-			if (subarg->result == 0)
+			if (subarg->result == -1)
 				search_arg_foreach(subarg, callback, context);
 
-			if (subarg->result == 1) {
-				/* matched */
-				arg->result = 1;
-				break;
+			if (subarg->result != -1) {
+				if (subarg->result == !arg->not) {
+					/* matched */
+					arg->result = 1;
+					break;
+				}
+
+				arg->result = 0;
 			}
 
-			if (subarg->result == 0)
-				arg->result = 0;
-
 			subarg = subarg->next;
 		}
 	} else {
@@ -81,13 +81,13 @@
 	for (; args != NULL; args = args->next) {
 		search_arg_foreach(args, callback, context);
 
-		if (args->result == -1) {
-			/* failed, abort */
-			return -1;
+		if (args->result == 0) {
+			/* didn't match */
+			return 0;
 		}
 
-		if (args->result == 0)
-			result = 0;
+		if (args->result == -1)
+			result = -1;
 	}
 
 	return result;
@@ -98,7 +98,7 @@
 {
 	struct mail_search_arg *subarg;
 
-	if (arg->result != 0)
+	if (arg->result != -1)
 		return;
 
 	switch (arg->type) {
@@ -106,7 +106,7 @@
 	case SEARCH_SUB:
 		subarg = arg->value.subargs;
 		while (subarg != NULL) {
-			if (subarg->result == 0) {
+			if (subarg->result == -1) {
 				search_arg_analyze(subarg, have_headers,
 						   have_body, have_text);
 			}
--- a/src/lib-storage/mail-search.h	Sat Feb 01 12:29:17 2003 +0200
+++ b/src/lib-storage/mail-search.h	Sat Feb 01 13:24:17 2003 +0200
@@ -61,9 +61,15 @@
 	const char *hdr_field_name; /* for SEARCH_HEADER */
 	unsigned int not:1;
 
-	int result;
+	int result; /* -1 = unknown, 0 = unmatched, 1 = matched */
 };
 
+#define ARG_SET_RESULT(arg, res) \
+	STMT_START { \
+		(arg)->result = !(arg)->not ? (res) : \
+			(res) == -1 ? -1 : !(res); \
+	} STMT_END
+
 typedef void (*mail_search_foreach_callback_t)(struct mail_search_arg *arg,
 					       void *context);
 
@@ -71,7 +77,7 @@
 void mail_search_args_reset(struct mail_search_arg *args);
 
 /* goes through arguments in list that don't have a result yet.
-   Returns 1 = search matched, -1 = search unmatched, 0 = don't know yet */
+   Returns 1 = search matched, 0 = search unmatched, -1 = don't know yet */
 int mail_search_args_foreach(struct mail_search_arg *args,
 			     mail_search_foreach_callback_t callback,
 			     void *context);