new_arg.match_not = FALSE;
if (!mail_search_arg_to_imap(dest, &new_arg, &error))
i_unreached();
- str_insert(dest, pos+1, " ");
- str_insert(dest, str_len(dest)-1, " ");
+ if (str_c(dest)[pos] == '(') {
+ str_insert(dest, pos+1, " ");
+ str_insert(dest, str_len(dest)-1, " ");
+ }
return;
}
case SEARCH_INTHREAD:
return TRUE;
}
+static void
+mail_search_arg_to_imap_flags(string_t *dest, enum mail_flags flags)
+{
+ static const char *flag_names[] = {
+ "ANSWERED", "FLAGGED", "DELETED", "SEEN", "DRAFT", "RECENT"
+ };
+ unsigned int count = 0, start_pos = str_len(dest);
+
+ str_append_c(dest, '(');
+ for (unsigned int i = 0; i < N_ELEMENTS(flag_names); i++) {
+ if ((flags & (1 << i)) != 0) {
+ str_append(dest, flag_names[i]);
+ str_append_c(dest, ' ');
+ count++;
+ }
+ }
+ i_assert(count > 0);
+
+ str_truncate(dest, str_len(dest)-1);
+ if (count == 1)
+ str_delete(dest, start_pos, 1);
+ else
+ str_append_c(dest, ')');
+}
+
bool mail_search_arg_to_imap(string_t *dest, const struct mail_search_arg *arg,
const char **error_r)
{
imap_write_seq_range(dest, &arg->value.seqset);
break;
case SEARCH_FLAGS:
- i_assert((arg->value.flags & MAIL_FLAGS_MASK) != 0);
- str_append_c(dest, '(');
- if ((arg->value.flags & MAIL_ANSWERED) != 0)
- str_append(dest, "ANSWERED ");
- if ((arg->value.flags & MAIL_FLAGGED) != 0)
- str_append(dest, "FLAGGED ");
- if ((arg->value.flags & MAIL_DELETED) != 0)
- str_append(dest, "DELETED ");
- if ((arg->value.flags & MAIL_SEEN) != 0)
- str_append(dest, "SEEN ");
- if ((arg->value.flags & MAIL_DRAFT) != 0)
- str_append(dest, "DRAFT ");
- if ((arg->value.flags & MAIL_RECENT) != 0)
- str_append(dest, "RECENT ");
- str_truncate(dest, str_len(dest)-1);
- str_append_c(dest, ')');
+ mail_search_arg_to_imap_flags(dest, arg->value.flags);
break;
case SEARCH_KEYWORDS: {
const struct mail_keywords *kw = arg->initialized.keywords;
const ARRAY_TYPE(keywords) *names_arr;
const char *const *namep;
- unsigned int i;
+ unsigned int i, count = 0;
+ size_t start_pos = str_len(dest);
if (kw == NULL) {
/* uninitialized */
if (i > 0)
str_append_c(dest, ' ');
str_printfa(dest, "KEYWORD %s", *namep);
+ count++;
}
- str_append_c(dest, ')');
+ if (count == 1)
+ str_delete(dest, start_pos, 1);
+ else
+ str_append_c(dest, ')');
break;
}
{ "1,5:6,10:15", NULL },
{ "UID 1,5:6,10:15", NULL },
{ "ANSWERED FLAGGED DELETED SEEN DRAFT RECENT",
- "(ANSWERED) (FLAGGED) (DELETED) (SEEN) (DRAFT) (RECENT)" },
+ "ANSWERED FLAGGED DELETED SEEN DRAFT RECENT" },
{ "KEYWORD foo KEYWORD bar", NULL },
{ "BEFORE 20-May-2015", "BEFORE \"20-May-2015\"" },
{ "ON 20-May-2015", "ON \"20-May-2015\"" },
{ "MODSEQ /flags/\\Seen all 0", NULL },
{ "MODSEQ /flags/\\Seen priv 0", NULL },
{ "MODSEQ /flags/\\Seen shared 0", NULL },
- { "INTHREAD REFERENCES seen", "INTHREAD REFERENCES ((SEEN))" },
- { "INTHREAD ORDEREDSUBJECT seen", "INTHREAD ORDEREDSUBJECT ((SEEN))" },
- { "INTHREAD REFS seen", "INTHREAD REFS ((SEEN))" },
+ { "INTHREAD REFERENCES seen", "INTHREAD REFERENCES (SEEN)" },
+ { "INTHREAD ORDEREDSUBJECT seen", "INTHREAD ORDEREDSUBJECT (SEEN)" },
+ { "INTHREAD REFS seen", "INTHREAD REFS (SEEN)" },
{ "INTHREAD REFS ( OR text foo OR keyword bar seen )",
- "INTHREAD REFS (((OR TEXT foo OR KEYWORD bar (SEEN))))" },
+ "INTHREAD REFS (((OR TEXT foo OR KEYWORD bar SEEN)))" },
{ "X-GUID foo", NULL },
{ "X-MAILBOX foo", NULL },
{ "X-REAL-UID 1,5:6,10:15", NULL },
{ "NOT ( TEXT foo TEXT bar )", "(OR NOT TEXT foo NOT TEXT bar)" },
{ "ANSWERED FLAGGED SEEN", "(ANSWERED FLAGGED SEEN)" },
- { "OR ( ANSWERED FLAGGED SEEN ) DRAFT", "(OR (ANSWERED FLAGGED SEEN) (DRAFT))" },
+ { "OR ( ANSWERED FLAGGED SEEN ) DRAFT", "(OR (ANSWERED FLAGGED SEEN) DRAFT)" },
{ "ANSWERED TEXT foo FLAGGED SEEN", "(ANSWERED FLAGGED SEEN) TEXT foo" },
{ "NOT ( ANSWERED FLAGGED SEEN )", "NOT (ANSWERED FLAGGED SEEN)" },
{ "OR NOT ANSWERED OR NOT FLAGGED NOT SEEN", "NOT (ANSWERED FLAGGED SEEN)" },
- { "ANSWERED NOT FLAGGED SEEN NOT DRAFT", "(ANSWERED SEEN) NOT (FLAGGED) NOT (DRAFT)" },
+ { "ANSWERED NOT FLAGGED SEEN NOT DRAFT", "(ANSWERED SEEN) NOT FLAGGED NOT DRAFT" },
{ "OR NOT ANSWERED NOT SEEN", "NOT (ANSWERED SEEN)" },
{ "KEYWORD foo", "KEYWORD foo" },