summaryrefslogtreecommitdiff
path: root/mail/msgset.y
diff options
context:
space:
mode:
Diffstat (limited to 'mail/msgset.y')
-rw-r--r--mail/msgset.y167
1 files changed, 140 insertions, 27 deletions
diff --git a/mail/msgset.y b/mail/msgset.y
index 6f31325dd..149f7c42b 100644
--- a/mail/msgset.y
+++ b/mail/msgset.y
@@ -40,7 +40,6 @@ static msgset_t *msgset_select (int (*sel) (mu_message_t, void *),
unsigned int max_matches);
static int select_header (mu_message_t msg, void *closure);
static int select_body (mu_message_t msg, void *closure);
-static int select_type (mu_message_t msg, void *closure);
static int select_sender (mu_message_t msg, void *closure);
static int select_deleted (mu_message_t msg, void *closure);
static int check_set (msgset_t **pset);
@@ -52,6 +51,9 @@ static int msgset_flags = MSG_NODELETED;
static size_t message_count;
static msgset_t *result;
static mu_opool_t tokpool;
+
+typedef int (*message_selector_t) (mu_message_t, void *);
+static message_selector_t find_type_selector (int type);
%}
%union {
@@ -166,12 +168,13 @@ msg : header REGEXP /* /.../ */
}
| TYPE /* :n, :d, etc */
{
- if (strchr ("dnorsTtu", $1) == NULL)
+ message_selector_t sel = find_type_selector ($1);
+ if (!sel)
{
yyerror (_("unknown message type"));
YYERROR;
}
- $$ = msgset_select (select_type, (void *)&$1, 0, 0);
+ $$ = msgset_select (sel, NULL, 0, 0);
if (!$$)
{
mu_error (_("No messages satisfy :%c"), $1);
@@ -573,7 +576,7 @@ msgset_expand (msgset_t *set, msgset_t *expand_by)
}
msgset_t *
-msgset_select (int (*sel) (mu_message_t, void *), void *closure, int rev,
+msgset_select (message_selector_t sel, void *closure, int rev,
unsigned int max_matches)
{
size_t i, match_count = 0;
@@ -727,37 +730,147 @@ select_sender (mu_message_t msg, void *closure)
free (sender);
return status;
}
+
+static int
+select_type_d (mu_message_t msg, void *unused MU_ARG_UNUSED)
+{
+ mu_attribute_t attr;
-int
-select_type (mu_message_t msg, void *closure)
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return mu_attribute_is_deleted (attr);
+ return 0;
+}
+
+static int
+select_type_n (mu_message_t msg, void *unused MU_ARG_UNUSED)
{
- int type = *(int*) closure;
- mu_attribute_t attr= NULL;
+ mu_attribute_t attr;
- mu_message_get_attribute (msg, &attr);
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return mu_attribute_is_recent (attr);
+ return 0;
+}
+
+static int
+select_type_o (mu_message_t msg, void *unused MU_ARG_UNUSED)
+{
+ mu_attribute_t attr;
+
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return mu_attribute_is_seen (attr);
+ return 0;
+}
- switch (type)
+static int
+select_type_r (mu_message_t msg, void *unused MU_ARG_UNUSED)
+{
+ mu_attribute_t attr;
+
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return mu_attribute_is_read (attr);
+ return 0;
+}
+
+static int
+select_type_s (mu_message_t msg, void *unused MU_ARG_UNUSED)
+{
+ mu_attribute_t attr;
+
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED);
+ return 0;
+}
+
+static int
+select_type_t (mu_message_t msg, void *unused MU_ARG_UNUSED)
+{
+ mu_attribute_t attr;
+
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED);
+ return 0;
+}
+
+static int
+select_type_T (mu_message_t msg, void *unused MU_ARG_UNUSED)
+{
+ mu_attribute_t attr;
+
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return !mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED);
+ return 0;
+}
+
+static int
+select_type_u (mu_message_t msg, void *unused MU_ARG_UNUSED)
+{
+ mu_attribute_t attr;
+
+ if (mu_message_get_attribute (msg, &attr) == 0)
+ return !mu_attribute_is_read (attr);
+ return 0;
+}
+
+struct type_selector
+{
+ int letter;
+ message_selector_t func;
+};
+
+static struct type_selector type_selector[] = {
+ { 'd', select_type_d },
+ { 'n', select_type_n },
+ { 'o', select_type_o },
+ { 'r', select_type_r },
+ { 's', select_type_s },
+ { 't', select_type_t },
+ { 'T', select_type_T },
+ { 'u', select_type_u },
+ { '/', NULL }, /* A pseudo-entry needed for msgtype_generator only */
+ { 0 }
+};
+
+static message_selector_t
+find_type_selector (int type)
+{
+ struct type_selector *p;
+ for (p = type_selector; p->func; p++)
{
- case 'd':
- return mu_attribute_is_deleted (attr);
- case 'n':
- return mu_attribute_is_recent (attr);
- case 'o':
- return mu_attribute_is_seen (attr);
- case 'r':
- return mu_attribute_is_read (attr);
- case 's':
- return mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED);
- case 't':
- return mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED);
- case 'T':
- return !mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED);
- case 'u':
- return !mu_attribute_is_read (attr);
+ if (p->letter == type)
+ return p->func;
}
- return 0;
+ return NULL;
}
+#ifdef WITH_READLINE
+char *
+msgtype_generator (const char *text, int state)
+{
+ /* Allowed message types, plus '/'. The latter can folow a colon,
+ meaning body lookup */
+ static int i;
+ char c;
+
+ if (!state)
+ {
+ i = 0;
+ }
+ while ((c = type_selector[i].letter))
+ {
+ i++;
+ if (!text[1] || text[1] == c)
+ {
+ char *s = mu_alloc (3);
+ s[0] = ':';
+ s[1] = c;
+ s[2] = 0;
+ return s;
+ }
+ }
+ return NULL;
+}
+#endif
+
int
select_deleted (mu_message_t msg, void *closure MU_ARG_UNUSED)
{

Return to:

Send suggestions and report system problems to the System administrator.