mail-search-args-simplify.c revision 8d3af185ae454653fad60e41c5f36edb1d45c868
/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "hash.h"
#include "mail-search.h"
struct mail_search_simplify_prev_arg {
struct {
enum mail_search_arg_type type;
bool match_not;
bool fuzzy;
} bin_mask;
const char *hdr_field_name_mask;
const char *str_mask;
struct mail_search_arg *prev_arg;
};
struct mail_search_simplify_ctx {
/* arg mask => prev_arg */
HASH_TABLE(struct mail_search_simplify_prev_arg *,
struct mail_search_simplify_prev_arg *) prev_args;
bool parent_and;
bool removals;
};
static int
const struct mail_search_simplify_prev_arg *arg2)
{
int ret;
if (ret == 0)
if (ret == 0)
return ret;
}
static unsigned int
{
unsigned int hash;
return hash;
}
struct mail_search_simplify_prev_arg *mask_r)
{
}
static struct mail_search_arg **
const struct mail_search_simplify_prev_arg *mask)
{
struct mail_search_simplify_prev_arg *prev_arg;
}
}
struct mail_search_arg *args)
{
struct mail_search_simplify_prev_arg mask;
struct mail_search_arg **prev_argp;
return FALSE;
return FALSE;
} else {
return TRUE;
}
}
struct mail_search_arg *args)
{
struct mail_search_simplify_prev_arg mask;
struct mail_search_arg **prev_argp;
return FALSE;
return FALSE;
} else {
return TRUE;
}
}
struct mail_search_arg *args)
{
struct mail_search_simplify_prev_arg mask;
return FALSE;
}
case SEARCH_BEFORE:
if (ctx->parent_and) {
/* prev_arg < 5 AND arg < 10 */
} else {
/* prev_arg < 10 AND arg < 5 */
}
} else {
/* prev_arg < 5 OR arg < 10 */
} else {
/* prev_arg < 10 OR arg < 5 */
}
}
return TRUE;
case SEARCH_ON:
return TRUE;
return FALSE;
case SEARCH_SINCE:
if (ctx->parent_and) {
/* prev_arg >= 5 AND arg >= 10 */
} else {
/* prev_arg >= 10 AND arg >= 5 */
}
} else {
/* prev_arg >= 5 OR arg >= 10 */
} else {
/* prev_arg >= 10 OR arg >= 5 */
}
}
return TRUE;
default:
break;
}
return FALSE;
}
struct mail_search_arg *args)
{
struct mail_search_simplify_prev_arg mask;
return FALSE;
}
case SEARCH_SMALLER:
if (ctx->parent_and) {
/* prev_arg < 5 AND arg < 10 */
} else {
/* prev_arg < 10 AND arg < 5 */
}
} else {
/* prev_arg < 5 OR arg < 10 */
} else {
/* prev_arg < 10 OR arg < 5 */
}
}
return TRUE;
case SEARCH_LARGER:
if (ctx->parent_and) {
/* prev_arg >= 5 AND arg >= 10 */
} else {
/* prev_arg >= 10 AND arg >= 5 */
}
} else {
/* prev_arg >= 5 OR arg >= 10 */
} else {
/* prev_arg >= 10 OR arg >= 5 */
}
}
return TRUE;
default:
break;
}
return FALSE;
}
struct mail_search_arg *args)
{
struct mail_search_simplify_prev_arg mask;
struct mail_search_arg **prev_argp;
return FALSE;
}
/* duplicate search word. */
return TRUE;
}
static bool
const struct mail_search_arg *wanted_arg)
{
const struct mail_search_arg *arg;
return TRUE;
}
return FALSE;
}
static bool
const struct mail_search_arg *wanted_arg,
bool check_subs)
{
struct mail_search_arg **argp;
} else if (check_subs) {
/* we already verified that this should have
existed. */
i_unreached();
}
else
} else {
}
}
return found;
}
static bool
const struct mail_search_arg *wanted_args)
{
const struct mail_search_arg *arg;
return FALSE;
}
return TRUE;
}
static unsigned int
{
unsigned int count;
return count;
}
static bool
bool and_arg)
{
/* find the arg which has the lowest number of child args */
lowest_arg = &one_arg;
break;
}
if (count < lowest_count) {
}
}
/* if there are any args that include lowest_arg, drop the arg since
it's redundant. (non-SUB duplicates are dropped elsewhere.) */
} else {
}
}
return ret;
}
static bool
{
/* find the first SEARCH_SUB */
break;
}
return FALSE;
/* check if sub_arg is found from all the args */
/* the whole arg matches */
/* exists as subarg */
} else {
break;
}
}
continue;
/* extract the arg and put it to common_args */
}
if (common_args == NULL)
return FALSE;
/* there are only common args */
} else {
/* replace OR arg with AND(common_args, OR(non_common_args)) */
*or_arg = *parent_arg;
}
return TRUE;
}
static bool
{
struct mail_search_simplify_ctx ctx;
bool merged;
/* neg(p and q and ..) == neg(p) or neg(q) or ..
neg(p or q or ..) == neg(p) and neg(q) and .. */
do {
}
/* p and (q and ..) == p and q and ..
p or (q or ..) == p or q or ..
(p) = p */
continue;
}
}
}
/* try to merge arguments */
case SEARCH_FLAGS:
break;
case SEARCH_SEQSET:
case SEARCH_UIDSET:
break;
case SEARCH_BEFORE:
case SEARCH_ON:
case SEARCH_SINCE:
break;
case SEARCH_SMALLER:
case SEARCH_LARGER:
break;
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
case SEARCH_BODY:
case SEARCH_TEXT:
break;
default:
break;
}
if (merged) {
continue;
}
}
}
static bool
struct mail_search_arg **argp,
bool parent_inthreads, bool parent_and)
{
case SEARCH_SUB:
case SEARCH_OR:
} else {
}
break;
case SEARCH_INTHREAD:
/* children converted to SEARCH_INTHREADs */
}
break;
default:
break;
}
}
return FALSE;
/* put all non-INTHREADs under a single INTHREAD */
}
}
if (!parent_and) {
/* We want to OR the args */
}
return TRUE;
}
{
bool removals;
/* we may have added some extra SUBs that could be dropped */
}
for (;;) {
if (!removals)
break;
}
}