summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--imap4d/copy.c8
-rw-r--r--imap4d/fetch.c7
-rw-r--r--imap4d/search.c14
-rw-r--r--imap4d/store.c7
-rw-r--r--include/mailutils/msgset.h38
-rw-r--r--include/mailutils/sys/msgset.h5
-rw-r--r--libmailutils/msgset/Makefile.am9
-rw-r--r--libmailutils/msgset/add.c14
-rw-r--r--libmailutils/msgset/addset.c50
-rw-r--r--libmailutils/msgset/count.c48
-rw-r--r--libmailutils/msgset/foreachmsg.c72
-rw-r--r--libmailutils/msgset/foreachmsgno.c38
-rw-r--r--libmailutils/msgset/foreachnum.c85
-rw-r--r--libmailutils/msgset/foreachuid.c37
-rw-r--r--libmailutils/msgset/isempty.c28
-rw-r--r--libmailutils/msgset/negate.c25
-rw-r--r--libmailutils/msgset/parse.c26
-rw-r--r--libmailutils/msgset/sub.c19
-rw-r--r--libmailutils/msgset/subset.c50
-rw-r--r--libmailutils/msgset/trans.c99
-rw-r--r--libmailutils/tests/msgset.c73
-rw-r--r--libproto/imap/mbox.c29
-rw-r--r--mh/anno.c21
-rw-r--r--mh/burst.c83
-rw-r--r--mh/comp.c21
-rw-r--r--mh/folder.c39
-rw-r--r--mh/forw.c48
-rw-r--r--mh/mark.c10
-rw-r--r--mh/mh.h35
-rw-r--r--mh/mh_init.c39
-rw-r--r--mh/mh_msgset.c328
-rw-r--r--mh/mh_sequence.c189
-rw-r--r--mh/mhn.c30
-rw-r--r--mh/mhpath.c15
-rw-r--r--mh/mhseq.c19
-rw-r--r--mh/pick.c48
-rw-r--r--mh/refile.c11
-rw-r--r--mh/repl.c18
-rw-r--r--mh/rmm.c11
-rw-r--r--mh/scan.c19
-rw-r--r--mh/send.c46
-rw-r--r--mh/sortm.c83
-rw-r--r--mh/tests/mark.at6
-rw-r--r--mh/whatnowenv.c38
-rw-r--r--mu/imap.c4
-rw-r--r--testsuite/msgset.c148
46 files changed, 1319 insertions, 771 deletions
diff --git a/imap4d/copy.c b/imap4d/copy.c
index a96a1dcd0..63f262d53 100644
--- a/imap4d/copy.c
+++ b/imap4d/copy.c
@@ -211,7 +211,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
mu_mailbox_t cmbox = NULL;
int arg = IMAP4_ARG_1 + !!isuid;
int ns;
-
+
*err_text = NULL;
if (imap4d_tokbuf_argc (tok) != arg + 2)
{
@@ -221,14 +221,16 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
msgset_str = imap4d_tokbuf_getarg (tok, arg);
name = imap4d_tokbuf_getarg (tok, arg + 1);
- status = mu_msgset_create (&msgset, mbox, isuid ? MU_MSGSET_UID : 0);
+ status = mu_msgset_create (&msgset, mbox, MU_MSGSET_NUM);
if (!status)
{
*err_text = "Software error";
return RESP_BAD;
}
- status = mu_msgset_parse_imap (msgset, msgset_str, &end);
+ status = mu_msgset_parse_imap (msgset,
+ isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
+ msgset_str, &end);
if (status)
{
mu_msgset_free (msgset);
diff --git a/imap4d/fetch.c b/imap4d/fetch.c
index 7a4e50b51..a73d16966 100644
--- a/imap4d/fetch.c
+++ b/imap4d/fetch.c
@@ -1759,13 +1759,14 @@ fetch_thunk (imap4d_parsebuf_t pb)
mstr = imap4d_parsebuf_next (pb, 1);
- status = mu_msgset_create (&pclos->msgset, mbox,
- pclos->isuid ? MU_MSGSET_UID : 0);
+ status = mu_msgset_create (&pclos->msgset, mbox, MU_MSGSET_NUM);
if (status)
imap4d_parsebuf_exit (pb, "Software error");
/* Parse sequence numbers. */
- status = mu_msgset_parse_imap (pclos->msgset, mstr, &end);
+ status = mu_msgset_parse_imap (pclos->msgset,
+ pclos->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
+ mstr, &end);
if (status)
imap4d_parsebuf_exit (pb, "Failed to parse message set");
diff --git a/imap4d/search.c b/imap4d/search.c
index 244181038..69f4bae28 100644
--- a/imap4d/search.c
+++ b/imap4d/search.c
@@ -608,10 +608,11 @@ parse_simple_key (struct parsebuf *pb)
if (!condp->name)
{
- mu_msgset_t msgset = parse_msgset_create (pb, mbox,
- pb->isuid ? MU_MSGSET_UID : 0);
+ mu_msgset_t msgset = parse_msgset_create (pb, mbox, MU_MSGSET_NUM);
- if (mu_msgset_parse_imap (msgset, pb->token, NULL) == 0)
+ if (mu_msgset_parse_imap (msgset,
+ pb->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
+ pb->token, NULL) == 0)
{
struct search_node *np = parse_alloc (pb, sizeof *np);
np->type = node_value;
@@ -696,9 +697,10 @@ parse_simple_key (struct parsebuf *pb)
break;
case 'u': /* UID message set */
- arg->v.value.v.msgset = parse_msgset_create (pb, NULL, 0);
- if (mu_msgset_parse_imap (arg->v.value.v.msgset, pb->token,
- NULL))
+ arg->v.value.v.msgset = parse_msgset_create (pb, NULL,
+ MU_MSGSET_NUM);
+ if (mu_msgset_parse_imap (arg->v.value.v.msgset, MU_MSGSET_UID,
+ pb->token, NULL))
{
mu_msgset_free (arg->v.value.v.msgset);
pb->err_mesg = "Bogus number set";
diff --git a/imap4d/store.c b/imap4d/store.c
index 2ec35601b..21bc86a4a 100644
--- a/imap4d/store.c
+++ b/imap4d/store.c
@@ -69,13 +69,14 @@ store_thunk (imap4d_parsebuf_t p)
imap4d_parsebuf_exit (p, "Bogus data suffix");
}
- status = mu_msgset_create (&pclos->msgset, mbox,
- pclos->isuid ? MU_MSGSET_UID : 0);
+ status = mu_msgset_create (&pclos->msgset, mbox, MU_MSGSET_NUM);
if (status)
imap4d_parsebuf_exit (p, "Software error");
/* Get the message numbers in set[]. */
- status = mu_msgset_parse_imap (pclos->msgset, mstr, &end);
+ status = mu_msgset_parse_imap (pclos->msgset,
+ pclos->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
+ mstr, &end);
if (status)
imap4d_parsebuf_exit (p, "Failed to parse message set");
diff --git a/include/mailutils/msgset.h b/include/mailutils/msgset.h
index f6bb26a35..b6651431c 100644
--- a/include/mailutils/msgset.h
+++ b/include/mailutils/msgset.h
@@ -18,6 +18,8 @@
#ifndef _MAILUTILS_MSGSET_H
#define _MAILUTILS_MSGSET_H
+# include <mailutils/types.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -31,23 +33,26 @@ struct mu_msgrange
/* Message numbers start with 1. MU_MSGNO_LAST denotes the last
message. */
#define MU_MSGNO_LAST 0
-
-#define MU_MSGSET_UID 0x01 /* Message set operates on UIDs */
-int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int flags);
+#define MU_MSGSET_NUM 0 /* Message set operates on sequence numbers */
+#define MU_MSGSET_UID 1 /* Message set operates on UIDs */
+
+#define MU_MSGSET_MODE_MASK 0x0f
+
+int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int mode);
int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist);
int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr);
-int mu_msgset_add_range (mu_msgset_t list, size_t beg, size_t end);
-int mu_msgset_sub_range (mu_msgset_t list, size_t beg, size_t end);
- /*int mu_msgset_add_set (mu_msgset_t a, mu_msgset_t b);*/
- /*int mu_msgset_sub_set (mu_msgset_t a, mu_msgset_t b);*/
+int mu_msgset_add_range (mu_msgset_t set, size_t beg, size_t end, int mode);
+int mu_msgset_sub_range (mu_msgset_t set, size_t beg, size_t end, int mode);
+int mu_msgset_add (mu_msgset_t a, mu_msgset_t b);
+int mu_msgset_sub (mu_msgset_t a, mu_msgset_t b);
int mu_msgset_aggregate (mu_msgset_t set);
int mu_msgset_clear (mu_msgset_t set);
void mu_msgset_free (mu_msgset_t set);
void mu_msgset_destroy (mu_msgset_t *set);
-int mu_msgset_parse_imap (mu_msgset_t set, const char *s, char **end);
+int mu_msgset_parse_imap (mu_msgset_t set, int mode, const char *s, char **end);
int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset);
@@ -55,17 +60,34 @@ int mu_msgset_locate (mu_msgset_t msgset, size_t n,
struct mu_msgrange const **prange);
int mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset);
+
+int mu_msgset_count (mu_msgset_t mset, size_t *pcount);
+int mu_msgset_is_empty (mu_msgset_t mset);
typedef int (*mu_msgset_msgno_action_t) (size_t _n, void *_call_data);
typedef int (*mu_msgset_message_action_t) (size_t _n, mu_message_t _msg,
void *_call_data);
+#define MU_MSGSET_FOREACH_FORWARD 0x00
+#define MU_MSGSET_FOREACH_BACKWARD 0x10
+
+int mu_msgset_foreach_num (mu_msgset_t _msgset, int _flags,
+ mu_msgset_msgno_action_t _action,
+ void *_call_data);
+
int mu_msgset_foreach_dir_msgno (mu_msgset_t _msgset, int _dir,
mu_msgset_msgno_action_t _action,
void *_data);
int mu_msgset_foreach_msgno (mu_msgset_t _msgset,
mu_msgset_msgno_action_t _action,
void *_call_data);
+int mu_msgset_foreach_dir_msguid (mu_msgset_t _msgset, int _dir,
+ mu_msgset_msgno_action_t _action,
+ void *_data);
+int mu_msgset_foreach_msguid (mu_msgset_t _msgset,
+ mu_msgset_msgno_action_t _action,
+ void *_data);
+
int mu_msgset_foreach_dir_message (mu_msgset_t _msgset, int _dir,
mu_msgset_message_action_t _action,
void *_call_data);
diff --git a/include/mailutils/sys/msgset.h b/include/mailutils/sys/msgset.h
index 9ecb053a0..7de6d61cb 100644
--- a/include/mailutils/sys/msgset.h
+++ b/include/mailutils/sys/msgset.h
@@ -28,4 +28,9 @@ struct _mu_msgset
int flags; /* Message set flags */
};
+int _mu_msgset_translate_pair (mu_msgset_t mset, int mode,
+ size_t *beg, size_t *end);
+int _mu_msgset_translate_range (mu_msgset_t mset, int mode,
+ struct mu_msgrange *r);
+
#endif
diff --git a/libmailutils/msgset/Makefile.am b/libmailutils/msgset/Makefile.am
index dfe7f6c1c..56582e4eb 100644
--- a/libmailutils/msgset/Makefile.am
+++ b/libmailutils/msgset/Makefile.am
@@ -19,19 +19,26 @@ noinst_LTLIBRARIES = libmsgset.la
libmsgset_la_SOURCES = \
add.c\
+ addset.c\
aggr.c\
clear.c\
create.c\
+ count.c\
getitr.c\
getlist.c\
foreachnum.c\
+ foreachmsgno.c\
+ foreachuid.c\
foreachmsg.c\
free.c\
+ isempty.c\
locate.c\
negate.c\
parse.c\
print.c\
- sub.c
+ sub.c\
+ subset.c\
+ trans.c
INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
diff --git a/libmailutils/msgset/add.c b/libmailutils/msgset/add.c
index 9d9770735..3623768a3 100644
--- a/libmailutils/msgset/add.c
+++ b/libmailutils/msgset/add.c
@@ -23,18 +23,30 @@
#include <mailutils/sys/msgset.h>
int
-mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end)
+mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end, int mode)
{
int rc;
struct mu_msgrange *range;
if (!mset || beg == 0)
return EINVAL;
+ if (end && beg > end)
+ {
+ size_t t = end;
+ end = beg;
+ beg = t;
+ }
range = calloc (1, sizeof (*range));
if (!range)
return ENOMEM;
range->msg_beg = beg;
range->msg_end = end;
+ rc = _mu_msgset_translate_range (mset, mode, range);
+ if (rc)
+ {
+ free (range);
+ return rc;
+ }
rc = mu_list_append (mset->list, range);
if (rc)
free (range);
diff --git a/libmailutils/msgset/addset.c b/libmailutils/msgset/addset.c
new file mode 100644
index 000000000..e897a7e3b
--- /dev/null
+++ b/libmailutils/msgset/addset.c
@@ -0,0 +1,50 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <stdlib.h>
+#include <mailutils/types.h>
+#include <mailutils/errno.h>
+#include <mailutils/list.h>
+#include <mailutils/msgset.h>
+#include <mailutils/sys/msgset.h>
+
+struct add_closure
+{
+ int mode;
+ mu_msgset_t dest;
+};
+
+static int
+add_range (void *item, void *data)
+{
+ struct mu_msgrange *r = item;
+ struct add_closure *clos = data;
+ return mu_msgset_add_range (clos->dest, r->msg_beg, r->msg_end, clos->mode);
+}
+
+int
+mu_msgset_add (mu_msgset_t a, mu_msgset_t b)
+{
+ struct add_closure closure;
+ if (!a)
+ return EINVAL;
+ if (!b)
+ return 0;
+ closure.mode = b->flags;
+ closure.dest = a;
+ return mu_list_foreach (b->list, add_range, &closure);
+}
diff --git a/libmailutils/msgset/count.c b/libmailutils/msgset/count.c
new file mode 100644
index 000000000..2eefaa451
--- /dev/null
+++ b/libmailutils/msgset/count.c
@@ -0,0 +1,48 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <stdlib.h>
+#include <mailutils/types.h>
+#include <mailutils/errno.h>
+#include <mailutils/list.h>
+#include <mailutils/msgset.h>
+#include <mailutils/sys/msgset.h>
+
+static int
+count_messages (void *item, void *data)
+{
+ struct mu_msgrange *r = item;
+ size_t *count = data;
+ *count += r->msg_end - r->msg_beg + 1;
+ return 0;
+}
+
+int
+mu_msgset_count (mu_msgset_t mset, size_t *pcount)
+{
+ int rc;
+ size_t count = 0;
+
+ if (!mset)
+ return EINVAL;
+ if (!pcount)
+ return MU_ERR_OUT_PTR_NULL;
+ rc = mu_list_foreach (mset->list, count_messages, &count);
+ if (rc == 0)
+ *pcount = count;
+ return rc;
+}
diff --git a/libmailutils/msgset/foreachmsg.c b/libmailutils/msgset/foreachmsg.c
index 74880de40..f5fa981f0 100644
--- a/libmailutils/msgset/foreachmsg.c
+++ b/libmailutils/msgset/foreachmsg.c
@@ -32,49 +32,47 @@ struct action_closure
};
static int
+call_action (struct action_closure *clos, size_t i)
+{
+ int rc;
+ mu_message_t msg = NULL;
+ size_t n;
+
+ if (clos->msgset->flags == MU_MSGSET_UID)
+ {
+ rc = mu_mailbox_translate (clos->msgset->mbox, MU_MAILBOX_UID_TO_MSGNO,
+ i, &n);
+ if (rc == MU_ERR_NOENT)
+ return 0;
+ else if (rc)
+ return rc;
+ }
+ else
+ n = i;
+
+ rc = mu_mailbox_get_message (clos->msgset->mbox, n, &msg);
+ if (rc == MU_ERR_NOENT)
+ return 0;
+ else if (rc == 0)
+ rc = clos->action (i, msg, clos->data);
+ return rc;
+}
+
+static int
procrange (void *item, void *data)
{
struct mu_msgrange *mp = item;
struct action_closure *clos = data;
size_t i;
-
+ int rc = 0;
+
if (clos->dir)
- for (i = mp->msg_end; i >= mp->msg_beg; i--)
- {
- int rc;
- mu_message_t msg = NULL;
-
- if (clos->msgset->mbox)
- {
- rc = mu_mailbox_get_message (clos->msgset->mbox, i, &msg);
- if (rc == MU_ERR_NOENT)
- continue;
- else if (rc)
- return rc;
- }
- rc = clos->action (i, msg, clos->data);
- if (rc)
- return rc;
- }
+ for (i = mp->msg_end; rc == 0 && i >= mp->msg_beg; i--)
+ rc = call_action (clos, i);
else
for (i = mp->msg_beg; i <= mp->msg_end; i++)
- {
- int rc;
- mu_message_t msg = NULL;
-
- if (clos->msgset->mbox)
- {
- rc = mu_mailbox_get_message (clos->msgset->mbox, i, &msg);
- if (rc == MU_ERR_NOENT)
- continue;
- else if (rc)
- return rc;
- }
- rc = clos->action (i, msg, clos->data);
- if (rc)
- return rc;
- }
- return 0;
+ rc = call_action (clos, i);
+ return rc;
}
/* Apply ACTION to each message number from MSGSET. */
@@ -85,7 +83,9 @@ mu_msgset_foreach_dir_message (mu_msgset_t msgset, int dir,
{
int rc;
struct action_closure clos;
-
+
+ if (!msgset->mbox)
+ return MU_ERR_NOT_OPEN;
rc = mu_msgset_aggregate (msgset);
if (rc)
return rc;
diff --git a/libmailutils/msgset/foreachmsgno.c b/libmailutils/msgset/foreachmsgno.c
new file mode 100644
index 000000000..200a81fd3
--- /dev/null
+++ b/libmailutils/msgset/foreachmsgno.c
@@ -0,0 +1,38 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <mailutils/msgset.h>
+
+/* Apply ACTION to each message number from MSGSET. */
+int
+mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
+ mu_msgset_msgno_action_t action,
+ void *data)
+{
+ return mu_msgset_foreach_num (msgset,
+ (dir ? MU_MSGSET_FOREACH_BACKWARD : MU_MSGSET_FOREACH_FORWARD)|
+ MU_MSGSET_NUM,
+ action, data);
+}
+
+int
+mu_msgset_foreach_msgno (mu_msgset_t msgset,
+ mu_msgset_msgno_action_t action,
+ void *data)
+{
+ return mu_msgset_foreach_dir_msgno (msgset, 0, action, data);
+}
diff --git a/libmailutils/msgset/foreachnum.c b/libmailutils/msgset/foreachnum.c
index fd3e1875b..3bb231418 100644
--- a/libmailutils/msgset/foreachnum.c
+++ b/libmailutils/msgset/foreachnum.c
@@ -20,6 +20,7 @@
#include <mailutils/errno.h>
#include <mailutils/list.h>
#include <mailutils/msgset.h>
+#include <mailutils/mailbox.h>
#include <mailutils/sys/msgset.h>
struct action_closure
@@ -27,38 +28,67 @@ struct action_closure
mu_msgset_msgno_action_t action;
void *data;
mu_msgset_t msgset;
- int dir;
+ int flags;
};
static int
+call_action (struct action_closure *clos, size_t i)
+{
+ size_t n;
+ int cmd;
+
+ if (clos->msgset->flags != (clos->flags & MU_MSGSET_MODE_MASK))
+ {
+ int rc;
+
+ switch (clos->flags & MU_MSGSET_MODE_MASK)
+ {
+ case MU_MSGSET_NUM:
+ cmd = MU_MAILBOX_UID_TO_MSGNO;
+ break;
+
+ case MU_MSGSET_UID:
+ cmd = MU_MAILBOX_MSGNO_TO_UID;
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ rc = mu_mailbox_translate (clos->msgset->mbox, cmd, i, &n);
+ if (rc == MU_ERR_NOENT)
+ return 0;
+ if (rc)
+ return rc;
+ }
+ else
+ n = i;
+ return clos->action (n, clos->data);
+}
+
+
+static int
procrange (void *item, void *data)
{
struct mu_msgrange *mp = item;
struct action_closure *clos = data;
size_t i;
-
- if (clos->dir)
- for (i = mp->msg_end; i >= mp->msg_beg; i--)
- {
- int rc = clos->action (i, clos->data);
- if (rc)
- return rc;
- }
+ int rc = 0;
+
+ if (clos->flags & MU_MSGSET_FOREACH_BACKWARD)
+ for (i = mp->msg_end; rc == 0 && i >= mp->msg_beg; i--)
+ rc = call_action (clos, i);
else
- for (i = mp->msg_beg; i <= mp->msg_end; i++)
- {
- int rc = clos->action (i, clos->data);
- if (rc)
- return rc;
- }
- return 0;
+ for (i = mp->msg_beg; rc == 0 && i <= mp->msg_end; i++)
+ rc = call_action (clos, i);
+ return rc;
}
-/* Apply ACTION to each message number from MSGSET. */
+/* Apply ACTION to each message number or UID from MSGSET. */
int
-mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
- mu_msgset_msgno_action_t action,
- void *data)
+mu_msgset_foreach_num (mu_msgset_t msgset, int flags,
+ mu_msgset_msgno_action_t action,
+ void *data)
{
int rc;
struct action_closure clos;
@@ -68,14 +98,9 @@ mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
return rc;
clos.action = action;
clos.data = data;
- clos.dir = dir;
- return mu_list_foreach_dir (msgset->list, dir, procrange, &clos);
-}
-
-int
-mu_msgset_foreach_msgno (mu_msgset_t msgset,
- mu_msgset_msgno_action_t action,
- void *data)
-{
- return mu_msgset_foreach_dir_msgno (msgset, 0, action, data);
+ clos.flags = flags;
+ clos.msgset = msgset;
+ return mu_list_foreach_dir (msgset->list,
+ !!(flags & MU_MSGSET_FOREACH_BACKWARD),
+ procrange, &clos);
}
diff --git a/libmailutils/msgset/foreachuid.c b/libmailutils/msgset/foreachuid.c
new file mode 100644
index 000000000..7fc36ed33
--- /dev/null
+++ b/libmailutils/msgset/foreachuid.c
@@ -0,0 +1,37 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <mailutils/msgset.h>
+
+/* Apply ACTION to each message number from MSGSET. */
+int
+mu_msgset_foreach_dir_msguid (mu_msgset_t msgset, int dir,
+ mu_msgset_msgno_action_t action,
+ void *data)
+{
+ return mu_msgset_foreach_num (msgset,
+ (dir ? MU_MSGSET_FOREACH_BACKWARD : MU_MSGSET_FOREACH_FORWARD) |
+ MU_MSGSET_UID, action, data);
+}
+
+int
+mu_msgset_foreach_msguid (mu_msgset_t msgset,
+ mu_msgset_msgno_action_t action,
+ void *data)
+{
+ return mu_msgset_foreach_dir_msguid (msgset, 0, action, data);
+}
diff --git a/libmailutils/msgset/isempty.c b/libmailutils/msgset/isempty.c
new file mode 100644
index 000000000..c1e40520d
--- /dev/null
+++ b/libmailutils/msgset/isempty.c
@@ -0,0 +1,28 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <stdlib.h>
+#include <mailutils/types.h>
+#include <mailutils/list.h>
+#include <mailutils/msgset.h>
+#include <mailutils/sys/msgset.h>
+
+int
+mu_msgset_is_empty (mu_msgset_t mset)
+{
+ return mset == NULL || mu_list_is_empty (mset->list);
+}
diff --git a/libmailutils/msgset/negate.c b/libmailutils/msgset/negate.c
index acd2476bb..75a454d12 100644
--- a/libmailutils/msgset/negate.c
+++ b/libmailutils/msgset/negate.c
@@ -38,7 +38,9 @@ _invert_range (void *item, void *data)
if (clos->next_num < range->msg_beg - 1)
{
- rc = mu_msgset_add_range (clos->nset, clos->next_num, range->msg_beg - 1);
+ rc = mu_msgset_add_range (clos->nset,
+ clos->next_num, range->msg_beg - 1,
+ clos->nset->flags);
if (rc)
return rc;
}
@@ -66,7 +68,15 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
rc = mu_mailbox_messages_count (msgset->mbox, &total);
if (rc)
return rc;
- rc = mu_msgset_create (&clos.nset, NULL, 0);</