Commit a01bb419 a01bb419262e90164a558075e3607fb3b0514443 by Sergey Poznyakoff

Improve msgset interface. Use it in MH.

* libmailutils/msgset/Makefile.am (libmsgset_la_SOURCES): Add new files.
* libmailutils/msgset/addset.c: New file.
* libmailutils/msgset/count.c: New file.
* libmailutils/msgset/foreachmsgno.c: New file.
* libmailutils/msgset/foreachuid.c: New file.
* libmailutils/msgset/isempty.c: New file.
* libmailutils/msgset/subset.c: New file.
* libmailutils/msgset/trans.c: New file.
* libmailutils/msgset/add.c (mu_msgset_add_range): Take fourth argument
specifying the conversion mode. Translate numbers as necessary.
* libmailutils/msgset/foreachmsg.c: Translate numbers as necessary.
* libmailutils/msgset/foreachnum.c: Rewrite.
* libmailutils/msgset/negate.c (_invert_range)
(mu_msgset_add_range): Update calls to mu_msgset_add_range.
* libmailutils/msgset/parse.c (parse_msgnum_env)<mode>: New member.
(parse_msgrange): Update calls to mu_msgset_add_range.
(mu_msgset_parse_imap): Change signature. All callers updated.
* libmailutils/msgset/sub.c (mu_msgset_sub_range): Take fourth argument
specifying the conversion mode. Translate numbers as necessary.

* imap4d/copy.c (imap4d_copy0): Update calls to mu_msgset_create
and mu_msgset_parse_imap.
* imap4d/fetch.c (fetch_thunk): Likewise.
* imap4d/search.c (parse_simple_key): Likewise.
* imap4d/store.c (store_thunk): Likewise.
* include/mailutils/msgset.h (MU_MSGSET_NUM,MU_MSGSET_UID): New defines.
(mu_msgset_add,mu_msgset_sub): New protos.
(mu_msgset_add_range,mu_msgset_sub_range): Take 4 arguments. All callers
changed.
* include/mailutils/sys/msgset.h (_mu_msgset_translate_pair)
(_mu_msgset_translate_range): New protos.

* libmailutils/tests/msgset.c: Reflect the above changes.
* testsuite/msgset.c: Likewise.
* libproto/imap/mbox.c: Update calls to mu_msgset functions.

* mh/mh.h (mh_msgset_t): Remove.
(mh_iterator_fp): Remove typedef.
(mh_msgset_parse): Change signature.
(mh_msgset_member,mh_msgset_reverse,mh_msgset_negate)
(mh_msgset_current,mh_msgset_free,mh_msgset_uids): Remove protos.
(mh_msgset_parse_string): New proto.
(mh_msgset_first_current,mh_msgset_first): New proto.
(mh_iterate: Remove proto. Use mu_msgset_foreach* functions instead.
(mh_seq_add,mh_seq_delete): Change signatures.
* mh/mh_init.c (mh_iterate): Remove.
* mh/mh_msgset.c: Rewrite using mu_msgset_t.
* mh/mh_sequence.c: Likewise.

* mh/anno.c: Use new msgset functions.
* mh/burst.c: Likewise.
* mh/comp.c: Likewise.
* mh/folder.c: Likewise.
* mh/forw.c: Likewise.
* mh/mark.c: Likewise.
* mh/mhn.c: Likewise.
* mh/mhpath.c: Likewise.
* mh/mhseq.c: Likewise.
* mh/pick.c: Likewise.
* mh/refile.c: Likewise.
* mh/repl.c: Likewise.
* mh/rmm.c: Likewise.
* mh/scan.c: Likewise.
* mh/send.c: Likewise.
* mh/sortm.c: Likewise.
* mh/whatnowenv.c: Likewise.
* mh/tests/mark.at: Reflect changes in the format of the saved
sequences, which may contain ranges now.

* mu/imap.c: Update calls to mu_msgset functions.
1 parent 26cfa219
...@@ -211,7 +211,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) ...@@ -211,7 +211,7 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
211 mu_mailbox_t cmbox = NULL; 211 mu_mailbox_t cmbox = NULL;
212 int arg = IMAP4_ARG_1 + !!isuid; 212 int arg = IMAP4_ARG_1 + !!isuid;
213 int ns; 213 int ns;
214 214
215 *err_text = NULL; 215 *err_text = NULL;
216 if (imap4d_tokbuf_argc (tok) != arg + 2) 216 if (imap4d_tokbuf_argc (tok) != arg + 2)
217 { 217 {
...@@ -221,14 +221,16 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) ...@@ -221,14 +221,16 @@ imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
221 221
222 msgset_str = imap4d_tokbuf_getarg (tok, arg); 222 msgset_str = imap4d_tokbuf_getarg (tok, arg);
223 name = imap4d_tokbuf_getarg (tok, arg + 1); 223 name = imap4d_tokbuf_getarg (tok, arg + 1);
224 status = mu_msgset_create (&msgset, mbox, isuid ? MU_MSGSET_UID : 0); 224 status = mu_msgset_create (&msgset, mbox, MU_MSGSET_NUM);
225 if (!status) 225 if (!status)
226 { 226 {
227 *err_text = "Software error"; 227 *err_text = "Software error";
228 return RESP_BAD; 228 return RESP_BAD;
229 } 229 }
230 230
231 status = mu_msgset_parse_imap (msgset, msgset_str, &end); 231 status = mu_msgset_parse_imap (msgset,
232 isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
233 msgset_str, &end);
232 if (status) 234 if (status)
233 { 235 {
234 mu_msgset_free (msgset); 236 mu_msgset_free (msgset);
......
...@@ -1759,13 +1759,14 @@ fetch_thunk (imap4d_parsebuf_t pb) ...@@ -1759,13 +1759,14 @@ fetch_thunk (imap4d_parsebuf_t pb)
1759 1759
1760 mstr = imap4d_parsebuf_next (pb, 1); 1760 mstr = imap4d_parsebuf_next (pb, 1);
1761 1761
1762 status = mu_msgset_create (&pclos->msgset, mbox, 1762 status = mu_msgset_create (&pclos->msgset, mbox, MU_MSGSET_NUM);
1763 pclos->isuid ? MU_MSGSET_UID : 0);
1764 if (status) 1763 if (status)
1765 imap4d_parsebuf_exit (pb, "Software error"); 1764 imap4d_parsebuf_exit (pb, "Software error");
1766 1765
1767 /* Parse sequence numbers. */ 1766 /* Parse sequence numbers. */
1768 status = mu_msgset_parse_imap (pclos->msgset, mstr, &end); 1767 status = mu_msgset_parse_imap (pclos->msgset,
1768 pclos->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
1769 mstr, &end);
1769 if (status) 1770 if (status)
1770 imap4d_parsebuf_exit (pb, "Failed to parse message set"); 1771 imap4d_parsebuf_exit (pb, "Failed to parse message set");
1771 1772
......
...@@ -608,10 +608,11 @@ parse_simple_key (struct parsebuf *pb) ...@@ -608,10 +608,11 @@ parse_simple_key (struct parsebuf *pb)
608 608
609 if (!condp->name) 609 if (!condp->name)
610 { 610 {
611 mu_msgset_t msgset = parse_msgset_create (pb, mbox, 611 mu_msgset_t msgset = parse_msgset_create (pb, mbox, MU_MSGSET_NUM);
612 pb->isuid ? MU_MSGSET_UID : 0);
613 612
614 if (mu_msgset_parse_imap (msgset, pb->token, NULL) == 0) 613 if (mu_msgset_parse_imap (msgset,
614 pb->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
615 pb->token, NULL) == 0)
615 { 616 {
616 struct search_node *np = parse_alloc (pb, sizeof *np); 617 struct search_node *np = parse_alloc (pb, sizeof *np);
617 np->type = node_value; 618 np->type = node_value;
...@@ -696,9 +697,10 @@ parse_simple_key (struct parsebuf *pb) ...@@ -696,9 +697,10 @@ parse_simple_key (struct parsebuf *pb)
696 break; 697 break;
697 698
698 case 'u': /* UID message set */ 699 case 'u': /* UID message set */
699 arg->v.value.v.msgset = parse_msgset_create (pb, NULL, 0); 700 arg->v.value.v.msgset = parse_msgset_create (pb, NULL,
700 if (mu_msgset_parse_imap (arg->v.value.v.msgset, pb->token, 701 MU_MSGSET_NUM);
701 NULL)) 702 if (mu_msgset_parse_imap (arg->v.value.v.msgset, MU_MSGSET_UID,
703 pb->token, NULL))
702 { 704 {
703 mu_msgset_free (arg->v.value.v.msgset); 705 mu_msgset_free (arg->v.value.v.msgset);
704 pb->err_mesg = "Bogus number set"; 706 pb->err_mesg = "Bogus number set";
......
...@@ -69,13 +69,14 @@ store_thunk (imap4d_parsebuf_t p) ...@@ -69,13 +69,14 @@ store_thunk (imap4d_parsebuf_t p)
69 imap4d_parsebuf_exit (p, "Bogus data suffix"); 69 imap4d_parsebuf_exit (p, "Bogus data suffix");
70 } 70 }
71 71
72 status = mu_msgset_create (&pclos->msgset, mbox, 72 status = mu_msgset_create (&pclos->msgset, mbox, MU_MSGSET_NUM);
73 pclos->isuid ? MU_MSGSET_UID : 0);
74 if (status) 73 if (status)
75 imap4d_parsebuf_exit (p, "Software error"); 74 imap4d_parsebuf_exit (p, "Software error");
76 75
77 /* Get the message numbers in set[]. */ 76 /* Get the message numbers in set[]. */
78 status = mu_msgset_parse_imap (pclos->msgset, mstr, &end); 77 status = mu_msgset_parse_imap (pclos->msgset,
78 pclos->isuid ? MU_MSGSET_UID : MU_MSGSET_NUM,
79 mstr, &end);
79 if (status) 80 if (status)
80 imap4d_parsebuf_exit (p, "Failed to parse message set"); 81 imap4d_parsebuf_exit (p, "Failed to parse message set");
81 82
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
18 #ifndef _MAILUTILS_MSGSET_H 18 #ifndef _MAILUTILS_MSGSET_H
19 #define _MAILUTILS_MSGSET_H 19 #define _MAILUTILS_MSGSET_H
20 20
21 # include <mailutils/types.h>
22
21 #ifdef __cplusplus 23 #ifdef __cplusplus
22 extern "C" { 24 extern "C" {
23 #endif 25 #endif
...@@ -31,23 +33,26 @@ struct mu_msgrange ...@@ -31,23 +33,26 @@ struct mu_msgrange
31 /* Message numbers start with 1. MU_MSGNO_LAST denotes the last 33 /* Message numbers start with 1. MU_MSGNO_LAST denotes the last
32 message. */ 34 message. */
33 #define MU_MSGNO_LAST 0 35 #define MU_MSGNO_LAST 0
34
35 #define MU_MSGSET_UID 0x01 /* Message set operates on UIDs */
36 36
37 int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int flags); 37 #define MU_MSGSET_NUM 0 /* Message set operates on sequence numbers */
38 #define MU_MSGSET_UID 1 /* Message set operates on UIDs */
39
40 #define MU_MSGSET_MODE_MASK 0x0f
41
42 int mu_msgset_create (mu_msgset_t *pmsgset, mu_mailbox_t mbox, int mode);
38 int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist); 43 int mu_msgset_get_list (mu_msgset_t msgset, mu_list_t *plist);
39 int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr); 44 int mu_msgset_get_iterator (mu_msgset_t msgset, mu_iterator_t *pitr);
40 45
41 int mu_msgset_add_range (mu_msgset_t list, size_t beg, size_t end); 46 int mu_msgset_add_range (mu_msgset_t set, size_t beg, size_t end, int mode);
42 int mu_msgset_sub_range (mu_msgset_t list, size_t beg, size_t end); 47 int mu_msgset_sub_range (mu_msgset_t set, size_t beg, size_t end, int mode);
43 /*int mu_msgset_add_set (mu_msgset_t a, mu_msgset_t b);*/ 48 int mu_msgset_add (mu_msgset_t a, mu_msgset_t b);
44 /*int mu_msgset_sub_set (mu_msgset_t a, mu_msgset_t b);*/ 49 int mu_msgset_sub (mu_msgset_t a, mu_msgset_t b);
45 int mu_msgset_aggregate (mu_msgset_t set); 50 int mu_msgset_aggregate (mu_msgset_t set);
46 int mu_msgset_clear (mu_msgset_t set); 51 int mu_msgset_clear (mu_msgset_t set);
47 void mu_msgset_free (mu_msgset_t set); 52 void mu_msgset_free (mu_msgset_t set);
48 void mu_msgset_destroy (mu_msgset_t *set); 53 void mu_msgset_destroy (mu_msgset_t *set);
49 54
50 int mu_msgset_parse_imap (mu_msgset_t set, const char *s, char **end); 55 int mu_msgset_parse_imap (mu_msgset_t set, int mode, const char *s, char **end);
51 56
52 int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset); 57 int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset);
53 58
...@@ -55,17 +60,34 @@ int mu_msgset_locate (mu_msgset_t msgset, size_t n, ...@@ -55,17 +60,34 @@ int mu_msgset_locate (mu_msgset_t msgset, size_t n,
55 struct mu_msgrange const **prange); 60 struct mu_msgrange const **prange);
56 61
57 int mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset); 62 int mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset);
63
64 int mu_msgset_count (mu_msgset_t mset, size_t *pcount);
65 int mu_msgset_is_empty (mu_msgset_t mset);
58 66
59 typedef int (*mu_msgset_msgno_action_t) (size_t _n, void *_call_data); 67 typedef int (*mu_msgset_msgno_action_t) (size_t _n, void *_call_data);
60 typedef int (*mu_msgset_message_action_t) (size_t _n, mu_message_t _msg, 68 typedef int (*mu_msgset_message_action_t) (size_t _n, mu_message_t _msg,
61 void *_call_data); 69 void *_call_data);
62 70
71 #define MU_MSGSET_FOREACH_FORWARD 0x00
72 #define MU_MSGSET_FOREACH_BACKWARD 0x10
73
74 int mu_msgset_foreach_num (mu_msgset_t _msgset, int _flags,
75 mu_msgset_msgno_action_t _action,
76 void *_call_data);
77
63 int mu_msgset_foreach_dir_msgno (mu_msgset_t _msgset, int _dir, 78 int mu_msgset_foreach_dir_msgno (mu_msgset_t _msgset, int _dir,
64 mu_msgset_msgno_action_t _action, 79 mu_msgset_msgno_action_t _action,
65 void *_data); 80 void *_data);
66 int mu_msgset_foreach_msgno (mu_msgset_t _msgset, 81 int mu_msgset_foreach_msgno (mu_msgset_t _msgset,
67 mu_msgset_msgno_action_t _action, 82 mu_msgset_msgno_action_t _action,
68 void *_call_data); 83 void *_call_data);
84 int mu_msgset_foreach_dir_msguid (mu_msgset_t _msgset, int _dir,
85 mu_msgset_msgno_action_t _action,
86 void *_data);
87 int mu_msgset_foreach_msguid (mu_msgset_t _msgset,
88 mu_msgset_msgno_action_t _action,
89 void *_data);
90
69 int mu_msgset_foreach_dir_message (mu_msgset_t _msgset, int _dir, 91 int mu_msgset_foreach_dir_message (mu_msgset_t _msgset, int _dir,
70 mu_msgset_message_action_t _action, 92 mu_msgset_message_action_t _action,
71 void *_call_data); 93 void *_call_data);
......
...@@ -28,4 +28,9 @@ struct _mu_msgset ...@@ -28,4 +28,9 @@ struct _mu_msgset
28 int flags; /* Message set flags */ 28 int flags; /* Message set flags */
29 }; 29 };
30 30
31 int _mu_msgset_translate_pair (mu_msgset_t mset, int mode,
32 size_t *beg, size_t *end);
33 int _mu_msgset_translate_range (mu_msgset_t mset, int mode,
34 struct mu_msgrange *r);
35
31 #endif 36 #endif
......
...@@ -19,19 +19,26 @@ noinst_LTLIBRARIES = libmsgset.la ...@@ -19,19 +19,26 @@ noinst_LTLIBRARIES = libmsgset.la
19 19
20 libmsgset_la_SOURCES = \ 20 libmsgset_la_SOURCES = \
21 add.c\ 21 add.c\
22 addset.c\
22 aggr.c\ 23 aggr.c\
23 clear.c\ 24 clear.c\
24 create.c\ 25 create.c\
26 count.c\
25 getitr.c\ 27 getitr.c\
26 getlist.c\ 28 getlist.c\
27 foreachnum.c\ 29 foreachnum.c\
30 foreachmsgno.c\
31 foreachuid.c\
28 foreachmsg.c\ 32 foreachmsg.c\
29 free.c\ 33 free.c\
34 isempty.c\
30 locate.c\ 35 locate.c\
31 negate.c\ 36 negate.c\
32 parse.c\ 37 parse.c\
33 print.c\ 38 print.c\
34 sub.c 39 sub.c\
40 subset.c\
41 trans.c
35 42
36 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils 43 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
37 44
......
...@@ -23,18 +23,30 @@ ...@@ -23,18 +23,30 @@
23 #include <mailutils/sys/msgset.h> 23 #include <mailutils/sys/msgset.h>
24 24
25 int 25 int
26 mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end) 26 mu_msgset_add_range (mu_msgset_t mset, size_t beg, size_t end, int mode)
27 { 27 {
28 int rc; 28 int rc;
29 struct mu_msgrange *range; 29 struct mu_msgrange *range;
30 30
31 if (!mset || beg == 0) 31 if (!mset || beg == 0)
32 return EINVAL; 32 return EINVAL;
33 if (end && beg > end)
34 {
35 size_t t = end;
36 end = beg;
37 beg = t;
38 }
33 range = calloc (1, sizeof (*range)); 39 range = calloc (1, sizeof (*range));
34 if (!range) 40 if (!range)
35 return ENOMEM; 41 return ENOMEM;
36 range->msg_beg = beg; 42 range->msg_beg = beg;
37 range->msg_end = end; 43 range->msg_end = end;
44 rc = _mu_msgset_translate_range (mset, mode, range);
45 if (rc)
46 {
47 free (range);
48 return rc;
49 }
38 rc = mu_list_append (mset->list, range); 50 rc = mu_list_append (mset->list, range);
39 if (rc) 51 if (rc)
40 free (range); 52 free (range);
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h>
23 #include <mailutils/sys/msgset.h>
24
25 struct add_closure
26 {
27 int mode;
28 mu_msgset_t dest;
29 };
30
31 static int
32 add_range (void *item, void *data)
33 {
34 struct mu_msgrange *r = item;
35 struct add_closure *clos = data;
36 return mu_msgset_add_range (clos->dest, r->msg_beg, r->msg_end, clos->mode);
37 }
38
39 int
40 mu_msgset_add (mu_msgset_t a, mu_msgset_t b)
41 {
42 struct add_closure closure;
43 if (!a)
44 return EINVAL;
45 if (!b)
46 return 0;
47 closure.mode = b->flags;
48 closure.dest = a;
49 return mu_list_foreach (b->list, add_range, &closure);
50 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h>
23 #include <mailutils/sys/msgset.h>
24
25 static int
26 count_messages (void *item, void *data)
27 {
28 struct mu_msgrange *r = item;
29 size_t *count = data;
30 *count += r->msg_end - r->msg_beg + 1;
31 return 0;
32 }
33
34 int
35 mu_msgset_count (mu_msgset_t mset, size_t *pcount)
36 {
37 int rc;
38 size_t count = 0;
39
40 if (!mset)
41 return EINVAL;
42 if (!pcount)
43 return MU_ERR_OUT_PTR_NULL;
44 rc = mu_list_foreach (mset->list, count_messages, &count);
45 if (rc == 0)
46 *pcount = count;
47 return rc;
48 }
...@@ -32,49 +32,47 @@ struct action_closure ...@@ -32,49 +32,47 @@ struct action_closure
32 }; 32 };
33 33
34 static int 34 static int
35 call_action (struct action_closure *clos, size_t i)
36 {
37 int rc;
38 mu_message_t msg = NULL;
39 size_t n;
40
41 if (clos->msgset->flags == MU_MSGSET_UID)
42 {
43 rc = mu_mailbox_translate (clos->msgset->mbox, MU_MAILBOX_UID_TO_MSGNO,
44 i, &n);
45 if (rc == MU_ERR_NOENT)
46 return 0;
47 else if (rc)
48 return rc;
49 }
50 else
51 n = i;
52
53 rc = mu_mailbox_get_message (clos->msgset->mbox, n, &msg);
54 if (rc == MU_ERR_NOENT)
55 return 0;
56 else if (rc == 0)
57 rc = clos->action (i, msg, clos->data);
58 return rc;
59 }
60
61 static int
35 procrange (void *item, void *data) 62 procrange (void *item, void *data)
36 { 63 {
37 struct mu_msgrange *mp = item; 64 struct mu_msgrange *mp = item;
38 struct action_closure *clos = data; 65 struct action_closure *clos = data;
39 size_t i; 66 size_t i;
40 67 int rc = 0;
68
41 if (clos->dir) 69 if (clos->dir)
42 for (i = mp->msg_end; i >= mp->msg_beg; i--) 70 for (i = mp->msg_end; rc == 0 && i >= mp->msg_beg; i--)
43 { 71 rc = call_action (clos, i);
44 int rc;
45 mu_message_t msg = NULL;
46
47 if (clos->msgset->mbox)
48 {
49 rc = mu_mailbox_get_message (clos->msgset->mbox, i, &msg);
50 if (rc == MU_ERR_NOENT)
51 continue;
52 else if (rc)
53 return rc;
54 }
55 rc = clos->action (i, msg, clos->data);
56 if (rc)
57 return rc;
58 }
59 else 72 else
60 for (i = mp->msg_beg; i <= mp->msg_end; i++) 73 for (i = mp->msg_beg; i <= mp->msg_end; i++)
61 { 74 rc = call_action (clos, i);
62 int rc; 75 return rc;
63 mu_message_t msg = NULL;
64
65 if (clos->msgset->mbox)
66 {
67 rc = mu_mailbox_get_message (clos->msgset->mbox, i, &msg);
68 if (rc == MU_ERR_NOENT)
69 continue;
70 else if (rc)
71 return rc;
72 }
73 rc = clos->action (i, msg, clos->data);
74 if (rc)
75 return rc;
76 }
77 return 0;
78 } 76 }
79 77
80 /* Apply ACTION to each message number from MSGSET. */ 78 /* Apply ACTION to each message number from MSGSET. */
...@@ -85,7 +83,9 @@ mu_msgset_foreach_dir_message (mu_msgset_t msgset, int dir, ...@@ -85,7 +83,9 @@ mu_msgset_foreach_dir_message (mu_msgset_t msgset, int dir,
85 { 83 {
86 int rc; 84 int rc;
87 struct action_closure clos; 85 struct action_closure clos;
88 86
87 if (!msgset->mbox)
88 return MU_ERR_NOT_OPEN;
89 rc = mu_msgset_aggregate (msgset); 89 rc = mu_msgset_aggregate (msgset);
90 if (rc) 90 if (rc)
91 return rc; 91 return rc;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <mailutils/msgset.h>
19
20 /* Apply ACTION to each message number from MSGSET. */
21 int
22 mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
23 mu_msgset_msgno_action_t action,
24 void *data)
25 {
26 return mu_msgset_foreach_num (msgset,
27 (dir ? MU_MSGSET_FOREACH_BACKWARD : MU_MSGSET_FOREACH_FORWARD)|
28 MU_MSGSET_NUM,
29 action, data);
30 }
31
32 int
33 mu_msgset_foreach_msgno (mu_msgset_t msgset,
34 mu_msgset_msgno_action_t action,
35 void *data)
36 {
37 return mu_msgset_foreach_dir_msgno (msgset, 0, action, data);
38 }
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #include <mailutils/errno.h> 20 #include <mailutils/errno.h>
21 #include <mailutils/list.h> 21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h> 22 #include <mailutils/msgset.h>
23 #include <mailutils/mailbox.h>
23 #include <mailutils/sys/msgset.h> 24 #include <mailutils/sys/msgset.h>
24 25
25 struct action_closure 26 struct action_closure
...@@ -27,38 +28,67 @@ struct action_closure ...@@ -27,38 +28,67 @@ struct action_closure
27 mu_msgset_msgno_action_t action; 28 mu_msgset_msgno_action_t action;
28 void *data; 29 void *data;
29 mu_msgset_t msgset; 30 mu_msgset_t msgset;
30 int dir; 31 int flags;
31 }; 32 };
32 33
33 static int 34 static int
35 call_action (struct action_closure *clos, size_t i)
36 {
37 size_t n;
38 int cmd;
39
40 if (clos->msgset->flags != (clos->flags & MU_MSGSET_MODE_MASK))
41 {
42 int rc;
43
44 switch (clos->flags & MU_MSGSET_MODE_MASK)
45 {
46 case MU_MSGSET_NUM:
47 cmd = MU_MAILBOX_UID_TO_MSGNO;
48 break;
49
50 case MU_MSGSET_UID:
51 cmd = MU_MAILBOX_MSGNO_TO_UID;
52 break;
53
54 default:
55 return EINVAL;
56 }
57
58 rc = mu_mailbox_translate (clos->msgset->mbox, cmd, i, &n);
59 if (rc == MU_ERR_NOENT)
60 return 0;
61 if (rc)
62 return rc;
63 }
64 else
65 n = i;
66 return clos->action (n, clos->data);
67 }
68
69
70 static int
34 procrange (void *item, void *data) 71 procrange (void *item, void *data)
35 { 72 {
36 struct mu_msgrange *mp = item; 73 struct mu_msgrange *mp = item;
37 struct action_closure *clos = data; 74 struct action_closure *clos = data;
38 size_t i; 75 size_t i;
39 76 int rc = 0;
40 if (clos->dir) 77
41 for (i = mp->msg_end; i >= mp->msg_beg; i--) 78 if (clos->flags & MU_MSGSET_FOREACH_BACKWARD)
42 { 79 for (i = mp->msg_end; rc == 0 && i >= mp->msg_beg; i--)
43 int rc = clos->action (i, clos->data); 80 rc = call_action (clos, i);
44 if (rc)
45 return rc;
46 }
47 else 81 else
48 for (i = mp->msg_beg; i <= mp->msg_end; i++) 82 for (i = mp->msg_beg; rc == 0 && i <= mp->msg_end; i++)
49 { 83 rc = call_action (clos, i);
50 int rc = clos->action (i, clos->data); 84 return rc;
51 if (rc)
52 return rc;
53 }
54 return 0;
55 } 85 }
56 86
57 /* Apply ACTION to each message number from MSGSET. */ 87 /* Apply ACTION to each message number or UID from MSGSET. */
58 int 88 int
59 mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir, 89 mu_msgset_foreach_num (mu_msgset_t msgset, int flags,
60 mu_msgset_msgno_action_t action, 90 mu_msgset_msgno_action_t action,
61 void *data) 91 void *data)
62 { 92 {
63 int rc; 93 int rc;
64 struct action_closure clos; 94 struct action_closure clos;
...@@ -68,14 +98,9 @@ mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir, ...@@ -68,14 +98,9 @@ mu_msgset_foreach_dir_msgno (mu_msgset_t msgset, int dir,
68 return rc; 98 return rc;
69 clos.action = action; 99 clos.action = action;
70 clos.data = data; 100 clos.data = data;
71 clos.dir = dir; 101 clos.flags = flags;
72 return mu_list_foreach_dir (msgset->list, dir, procrange, &clos); 102 clos.msgset = msgset;
73 } 103 return mu_list_foreach_dir (msgset->list,
74 104 !!(flags & MU_MSGSET_FOREACH_BACKWARD),
75 int 105 procrange, &clos);
76 mu_msgset_foreach_msgno (mu_msgset_t msgset,
77 mu_msgset_msgno_action_t action,
78 void *data)
79 {
80 return mu_msgset_foreach_dir_msgno (msgset, 0, action, data);
81 } 106 }
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <mailutils/msgset.h>
19
20 /* Apply ACTION to each message number from MSGSET. */
21 int
22 mu_msgset_foreach_dir_msguid (mu_msgset_t msgset, int dir,
23 mu_msgset_msgno_action_t action,
24 void *data)
25 {
26 return mu_msgset_foreach_num (msgset,
27 (dir ? MU_MSGSET_FOREACH_BACKWARD : MU_MSGSET_FOREACH_FORWARD) |
28 MU_MSGSET_UID, action, data);
29 }
30
31 int
32 mu_msgset_foreach_msguid (mu_msgset_t msgset,
33 mu_msgset_msgno_action_t action,
34 void *data)
35 {
36 return mu_msgset_foreach_dir_msguid (msgset, 0, action, data);
37 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/list.h>
21 #include <mailutils/msgset.h>
22 #include <mailutils/sys/msgset.h>
23
24 int
25 mu_msgset_is_empty (mu_msgset_t mset)
26 {
27 return mset == NULL || mu_list_is_empty (mset->list);
28 }
...@@ -38,7 +38,9 @@ _invert_range (void *item, void *data) ...@@ -38,7 +38,9 @@ _invert_range (void *item, void *data)
38 38
39 if (clos->next_num < range->msg_beg - 1) 39 if (clos->next_num < range->msg_beg - 1)
40 { 40 {
41 rc = mu_msgset_add_range (clos->nset, clos->next_num, range->msg_beg - 1); 41 rc = mu_msgset_add_range (clos->nset,
42 clos->next_num, range->msg_beg - 1,
43 clos->nset->flags);
42 if (rc) 44 if (rc)
43 return rc; 45 return rc;
44 } 46 }
...@@ -66,7 +68,15 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset) ...@@ -66,7 +68,15 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
66 rc = mu_mailbox_messages_count (msgset->mbox, &total); 68 rc = mu_mailbox_messages_count (msgset->mbox, &total);
67 if (rc) 69 if (rc)
68 return rc; 70 return rc;
69 rc = mu_msgset_create (&clos.nset, NULL, 0); 71 if (msgset->flags == MU_MSGSET_UID)
72 {
73 rc = mu_mailbox_translate (msgset->mbox,
74 MU_MAILBOX_MSGNO_TO_UID,
75 total, &total);
76 if (rc)
77 return rc;
78 }
79 rc = mu_msgset_create (&clos.nset, msgset->mbox, msgset->flags);
70 if (rc) 80 if (rc)
71 return rc; 81 return rc;
72 clos.next_num = 1; 82 clos.next_num = 1;
...@@ -74,15 +84,14 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset) ...@@ -74,15 +84,14 @@ mu_msgset_negate (mu_msgset_t msgset, mu_msgset_t *pnset)
74 if (rc == 0) 84 if (rc == 0)
75 { 85 {
76 if (clos.next_num < total) 86 if (clos.next_num < total)
77 rc = mu_msgset_add_range (clos.nset, clos.next_num, total); 87 rc = mu_msgset_add_range (clos.nset, clos.next_num, total,
88 clos.nset->flags);
78 } 89 }
79 90
80 if (rc) 91 if (rc)
81 mu_msgset_free (clos.nset); 92 mu_msgset_free (clos.nset);
82 else 93 else
83 { 94 *pnset = clos.nset;
84 clos.nset->mbox = msgset->mbox; 95
85 *pnset = clos.nset; 96 return rc;
86 }
87 return 0;
88 } 97 }
......
...@@ -33,6 +33,7 @@ struct parse_msgnum_env ...@@ -33,6 +33,7 @@ struct parse_msgnum_env
33 size_t minval; /* Min. sequence number or UID */ 33 size_t minval; /* Min. sequence number or UID */
34 size_t maxval; /* Max. sequence number or UID */ 34 size_t maxval; /* Max. sequence number or UID */
35 mu_msgset_t msgset; /* Message set being built. */ 35 mu_msgset_t msgset; /* Message set being built. */
36 int mode; /* Operation mode (num/uid) */
36 }; 37 };
37 38
38 /* Get a single message number/UID from env->s and store it into *PN. 39 /* Get a single message number/UID from env->s and store it into *PN.
...@@ -95,20 +96,8 @@ parse_msgrange (struct parse_msgnum_env *env) ...@@ -95,20 +96,8 @@ parse_msgrange (struct parse_msgnum_env *env)
95 msgrange.msg_beg = tmp; 96 msgrange.msg_beg = tmp;
96 } 97 }
97 98
98 if ((env->msgset->flags & MU_MSGSET_UID) && env->msgset->mbox) 99 return mu_msgset_add_range (env->msgset, msgrange.msg_beg, msgrange.msg_end,
99 { 100 env->mode);
100 int rc;
101
102 rc = mu_mailbox_translate (env->msgset->mbox,
103 MU_MAILBOX_UID_TO_MSGNO,
104 msgrange.msg_end, &msgrange.msg_end);
105 if (rc == MU_ERR_NOENT)
106 msgrange.msg_end = env->maxval;
107 else if (rc)
108 return rc;
109 }
110
111 return mu_msgset_add_range (env->msgset, msgrange.msg_beg, msgrange.msg_end);
112 } 101 }
113 102
114 /* Parse IMAP-style message set specification S. 103 /* Parse IMAP-style message set specification S.
...@@ -117,13 +106,15 @@ parse_msgrange (struct parse_msgnum_env *env) ...@@ -117,13 +106,15 @@ parse_msgrange (struct parse_msgnum_env *env)
117 On error, return error code and point END to the position in the input 106 On error, return error code and point END to the position in the input
118 string where parsing has failed. */ 107 string where parsing has failed. */
119 int 108 int
120 mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end) 109 mu_msgset_parse_imap (mu_msgset_t mset, int mode, const char *s, char **end)
121 { 110 {
122 int rc; 111 int rc;
123 struct parse_msgnum_env env; 112 struct parse_msgnum_env env;
124 113
125 if (!s || !mset) 114 if (!s || !mset)
126 return EINVAL; 115 return EINVAL;
116 if (end)
117 *end = (char*) s;
127 if (!*s) 118 if (!*s)
128 return MU_ERR_PARSE; 119 return MU_ERR_PARSE;
129 120
...@@ -131,9 +122,8 @@ mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end) ...@@ -131,9 +122,8 @@ mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end)
131 env.s = s; 122 env.s = s;
132 env.msgset = mset; 123 env.msgset = mset;
133 env.minval = 1; 124 env.minval = 1;
125 env.mode = mode;
134 126
135 if (end)
136 *end = (char*) s;
137 if (mset->mbox) 127 if (mset->mbox)
138 { 128 {
139 size_t lastmsgno; /* Max. sequence number. */ 129 size_t lastmsgno; /* Max. sequence number. */
...@@ -141,7 +131,7 @@ mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end) ...@@ -141,7 +131,7 @@ mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end)
141 rc = mu_mailbox_messages_count (mset->mbox, &lastmsgno); 131 rc = mu_mailbox_messages_count (mset->mbox, &lastmsgno);
142 if (rc == 0) 132 if (rc == 0)
143 { 133 {
144 if (mset->flags & MU_MSGSET_UID) 134 if (mode == MU_MSGSET_UID)
145 { 135 {
146 rc = mu_mailbox_translate (mset->mbox, MU_MAILBOX_MSGNO_TO_UID, 136 rc = mu_mailbox_translate (mset->mbox, MU_MAILBOX_MSGNO_TO_UID,
147 lastmsgno, &env.maxval); 137 lastmsgno, &env.maxval);
......
...@@ -112,7 +112,7 @@ sub_msgno_last (mu_msgset_t mset, size_t beg) ...@@ -112,7 +112,7 @@ sub_msgno_last (mu_msgset_t mset, size_t beg)
112 } 112 }
113 113
114 int 114 int
115 mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end) 115 mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end, int mode)
116 { 116 {
117 int rc; 117 int rc;
118 mu_iterator_t itr; 118 mu_iterator_t itr;
...@@ -122,6 +122,19 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end) ...@@ -122,6 +122,19 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
122 return EINVAL; 122 return EINVAL;
123 if (mu_list_is_empty (mset->list)) 123 if (mu_list_is_empty (mset->list))
124 return MU_ERR_NOENT; 124 return MU_ERR_NOENT;
125 if (end && beg > end)
126 {
127 size_t t = end;
128 end = beg;
129 beg = t;
130 }
131
132 rc = _mu_msgset_translate_pair (mset, mode, &beg, &end);
133 if (rc == MU_ERR_NOENT)
134 return 0;
135 else if (rc)
136 return rc;
137
125 rc = mu_msgset_aggregate (mset); 138 rc = mu_msgset_aggregate (mset);
126 if (rc) 139 if (rc)
127 return rc; 140 return rc;
...@@ -138,8 +151,6 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end) ...@@ -138,8 +151,6 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
138 if (beg < mr->msg_beg) 151 if (beg < mr->msg_beg)
139 beg = mr->msg_beg; 152 beg = mr->msg_beg;
140 153
141 if (rc)
142 return rc;
143 rc = mu_list_tail (mset->list, (void**) &mr); 154 rc = mu_list_tail (mset->list, (void**) &mr);
144 if (mr->msg_end != MU_MSGNO_LAST) 155 if (mr->msg_end != MU_MSGNO_LAST)
145 { 156 {
...@@ -148,7 +159,7 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end) ...@@ -148,7 +159,7 @@ mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end)
148 if (end > mr->msg_end) 159 if (end > mr->msg_end)
149 end = mr->msg_end; 160 end = mr->msg_end;
150 } 161 }
151 162
152 rc = mu_list_get_iterator (mset->list, &itr); 163 rc = mu_list_get_iterator (mset->list, &itr);
153 if (rc) 164 if (rc)
154 return rc; 165 return rc;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h>
23 #include <mailutils/sys/msgset.h>
24
25 struct sub_closure
26 {
27 int mode;
28 mu_msgset_t dest;
29 };
30
31 static int
32 sub_range (void *item, void *data)
33 {
34 struct mu_msgrange *r = item;
35 struct sub_closure *clos = data;
36 return mu_msgset_sub_range (clos->dest, r->msg_beg, r->msg_end, clos->mode);
37 }
38
39 int
40 mu_msgset_sub (mu_msgset_t a, mu_msgset_t b)
41 {
42 struct sub_closure closure;
43 if (!a)
44 return EINVAL;
45 if (!b)
46 return 0;
47 closure.mode = b->flags;
48 closure.dest = a;
49 return mu_list_foreach (b->list, sub_range, &closure);
50 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdlib.h>
19 #include <mailutils/types.h>
20 #include <mailutils/errno.h>
21 #include <mailutils/list.h>
22 #include <mailutils/msgset.h>
23 #include <mailutils/mailbox.h>
24 #include <mailutils/sys/msgset.h>
25
26 int
27 _mu_msgset_translate_pair (mu_msgset_t mset, int mode,
28 size_t *pbeg, size_t *pend)
29 {
30 if (mode != mset->flags && mset->mbox)
31 {
32 int cmd, rc;
33 size_t n;
34 size_t beg = *pbeg;
35 size_t end = *pend;
36
37 switch (mset->flags)
38 {
39 case MU_MSGSET_NUM:
40 cmd = MU_MAILBOX_UID_TO_MSGNO;
41 break;
42
43 case MU_MSGSET_UID:
44 cmd = MU_MAILBOX_MSGNO_TO_UID;
45 break;
46
47 default:
48 return EINVAL;
49 }
50
51 rc = mu_mailbox_translate (mset->mbox, cmd, beg, &n);
52 if (rc)
53 {
54 if (rc == MU_ERR_NOENT && cmd == MU_MAILBOX_UID_TO_MSGNO)
55 {
56 size_t x;
57
58 if (end == MU_MSGNO_LAST)
59 {
60 rc = mu_mailbox_uidnext (mset->mbox, &x);
61 if (rc)
62 return rc;
63 }
64 else
65 x = end;
66 for (; rc == MU_ERR_NOENT && beg < x; beg++)
67 rc = mu_mailbox_translate (mset->mbox, cmd, beg, &n);
68 }
69 if (rc)
70 return rc;
71 }
72
73 *pbeg = n;
74
75 if (beg == end)
76 *pend = n;
77 else if (end != MU_MSGNO_LAST)
78 {
79 rc = mu_mailbox_translate (mset->mbox, cmd, end, &n);
80 if (rc == MU_ERR_NOENT && cmd == MU_MAILBOX_UID_TO_MSGNO)
81 {
82 for (; rc == MU_ERR_NOENT && beg < end; end--)
83 rc = mu_mailbox_translate (mset->mbox, cmd, end, &n);
84
85 }
86 if (rc)
87 return rc;
88 *pend = n;
89 }
90 }
91 return 0;
92 }
93
94 int
95 _mu_msgset_translate_range (mu_msgset_t mset, int mode, struct mu_msgrange *r)
96 {
97 return _mu_msgset_translate_pair (mset, mode, &r->msg_beg, &r->msg_end);
98 }
99
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 #include <mailutils/mailutils.h> 19 #include <mailutils/mailutils.h>
20 20
21 static void 21 static void
22 parse_msgset (char *arg, struct mu_msgrange *range) 22 parse_msgrange (char *arg, struct mu_msgrange *range)
23 { 23 {
24 size_t msgnum; 24 size_t msgnum;
25 char *p; 25 char *p;
...@@ -52,13 +52,33 @@ parse_msgset (char *arg, struct mu_msgrange *range) ...@@ -52,13 +52,33 @@ parse_msgset (char *arg, struct mu_msgrange *range)
52 range->msg_end = msgnum; 52 range->msg_end = msgnum;
53 } 53 }
54 54
55 mu_msgset_t
56 parse_msgset (const char *arg)
57 {
58 int rc;
59 mu_msgset_t msgset;
60 char *end;
61
62 MU_ASSERT (mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM));
63 if (arg)
64 {
65 rc = mu_msgset_parse_imap (msgset, MU_MSGSET_NUM, arg, &end);
66 if (rc)
67 {
68 mu_error ("mu_msgset_parse_imap: %s near %s",
69 mu_strerror (rc), end);
70 exit (1);
71 }
72 }
73 return msgset;
74 }
75
55 int 76 int
56 main (int argc, char **argv) 77 main (int argc, char **argv)
57 { 78 {
58 int i; 79 int i;
59 char *msgset_string = NULL; 80 char *msgset_string = NULL;
60 mu_msgset_t msgset; 81 mu_msgset_t msgset;
61 int rc;
62 82
63 mu_set_program_name (argv[0]); 83 mu_set_program_name (argv[0]);
64 for (i = 1; i < argc; i++) 84 for (i = 1; i < argc; i++)
...@@ -67,7 +87,8 @@ main (int argc, char **argv) ...@@ -67,7 +87,8 @@ main (int argc, char **argv)
67 87
68 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) 88 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
69 { 89 {
70 mu_printf ("usage: %s [-msgset=SET] [-add X[:Y]] [-del X:[Y]]...\n", 90 mu_printf ("usage: %s [-msgset=SET] [-add=X[:Y]] [-del=X[:Y]] "
91 "[-addset=SET] [-delset=SET] ...\n",
71 mu_program_name); 92 mu_program_name);
72 return 0; 93 return 0;
73 } 94 }
...@@ -77,18 +98,7 @@ main (int argc, char **argv) ...@@ -77,18 +98,7 @@ main (int argc, char **argv)
77 break; 98 break;
78 } 99 }
79 100
80 MU_ASSERT (mu_msgset_create (&msgset, NULL, 0)); 101 msgset = parse_msgset (msgset_string);
81 if (msgset_string)
82 {
83 char *end;
84 rc = mu_msgset_parse_imap (msgset, msgset_string, &end);
85 if (rc)
86 {
87 mu_error ("mu_msgset_parse_imap: %s near %s",
88 mu_strerror (rc), end);
89 return 1;
90 }
91 }
92 102
93 for (; i < argc; i++) 103 for (; i < argc; i++)
94 { 104 {
...@@ -97,15 +107,40 @@ main (int argc, char **argv) ...@@ -97,15 +107,40 @@ main (int argc, char **argv)
97 107
98 if (strncmp (arg, "-add=", 5) == 0) 108 if (strncmp (arg, "-add=", 5) == 0)
99 { 109 {
100 parse_msgset (arg + 5, &range); 110 parse_msgrange (arg + 5, &range);
101 MU_ASSERT (mu_msgset_add_range (msgset, range.msg_beg, 111 MU_ASSERT (mu_msgset_add_range (msgset, range.msg_beg,
102 range.msg_end)); 112 range.msg_end, MU_MSGSET_NUM));
103 } 113 }
104 else if (strncmp (arg, "-sub=", 5) == 0) 114 else if (strncmp (arg, "-sub=", 5) == 0)
105 { 115 {
106 parse_msgset (arg + 5, &range); 116 parse_msgrange (arg + 5, &range);
107 MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg, 117 MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg,
108 range.msg_end)); 118 range.msg_end, MU_MSGSET_NUM));
119 }
120 else if (strncmp (arg, "-addset=", 8) == 0)
121 {
122 mu_msgset_t tset = parse_msgset (arg + 8);
123 if (!msgset)
124 msgset = tset;
125 else
126 {
127 MU_ASSERT (mu_msgset_add (msgset, tset));
128 mu_msgset_free (tset);
129 }
130 }
131 else if (strncmp (arg, "-subset=", 8) == 0)
132 {
133 mu_msgset_t tset = parse_msgset (arg + 8);
134 if (!msgset)
135 {
136 mu_error ("no initial message set");
137 exit (1);
138 }
139 else
140 {
141 MU_ASSERT (mu_msgset_sub (msgset, tset));
142 mu_msgset_free (tset);
143 }
109 } 144 }
110 else 145 else
111 { 146 {
......
...@@ -175,7 +175,7 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno, ...@@ -175,7 +175,7 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno,
175 if (rc) 175 if (rc)
176 return rc; 176 return rc;
177 177
178 rc = mu_msgset_create (&msgset, NULL, 0); 178 rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
179 if (rc == 0) 179 if (rc == 0)
180 { 180 {
181 struct save_closure clos; 181 struct save_closure clos;
...@@ -183,7 +183,7 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno, ...@@ -183,7 +183,7 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno,
183 clos.imsg = imsg; 183 clos.imsg = imsg;
184 clos.save_stream = imbx->cache; 184 clos.save_stream = imbx->cache;
185 185
186 rc = mu_msgset_add_range (msgset, msgno, msgno); 186 rc = mu_msgset_add_range (msgset, msgno, msgno, MU_MSGSET_NUM);
187 if (rc == 0) 187 if (rc == 0)
188 { 188 {
189 _imap_mbx_clrerr (imbx); 189 _imap_mbx_clrerr (imbx);
...@@ -370,10 +370,10 @@ _imap_hdr_fill (void *data, char **pbuf, size_t *plen) ...@@ -370,10 +370,10 @@ _imap_hdr_fill (void *data, char **pbuf, size_t *plen)
370 unsigned long msgno = _imap_msg_no (imsg); 370 unsigned long msgno = _imap_msg_no (imsg);
371 int rc; 371 int rc;
372 372
373 rc = mu_msgset_create (&msgset, NULL, 0); 373 rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
374 if (rc == 0) 374 if (rc == 0)
375 { 375 {
376 rc = mu_msgset_add_range (msgset, msgno, msgno); 376 rc = mu_msgset_add_range (msgset, msgno, msgno, MU_MSGSET_NUM);
377 if (rc == 0) 377 if (rc == 0)
378 { 378 {
379 clos.imsg = imsg; 379 clos.imsg = imsg;
...@@ -619,11 +619,11 @@ _imap_msg_bodystructure (mu_message_t msg, struct mu_bodystructure **pbs) ...@@ -619,11 +619,11 @@ _imap_msg_bodystructure (mu_message_t msg, struct mu_bodystructure **pbs)
619 int rc; 619 int rc;
620 mu_msgset_t msgset; 620 mu_msgset_t msgset;
621 621
622 rc = mu_msgset_create (&msgset, NULL, 0); 622 rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
623 if (rc == 0) 623 if (rc == 0)
624 { 624 {
625 size_t msgno = _imap_msg_no (imsg); 625 size_t msgno = _imap_msg_no (imsg);
626 rc = mu_msgset_add_range (msgset, msgno, msgno); 626 rc = mu_msgset_add_range (msgset, msgno, msgno, MU_MSGSET_NUM);
627 if (rc == 0) 627 if (rc == 0)
628 rc = _imap_fetch_with_callback (imap, msgset, "BODYSTRUCTURE", 628 rc = _imap_fetch_with_callback (imap, msgset, "BODYSTRUCTURE",
629 _imap_bodystructure_callback, pbs); 629 _imap_bodystructure_callback, pbs);
...@@ -949,7 +949,7 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel) ...@@ -949,7 +949,7 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
949 struct attr_tab *tab; 949 struct attr_tab *tab;
950 size_t count; 950 size_t count;
951 951
952 rc = mu_msgset_create (&msgset, NULL, 0); 952 rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
953 if (rc) 953 if (rc)
954 return rc; 954 return rc;
955 955
...@@ -962,7 +962,7 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel) ...@@ -962,7 +962,7 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
962 if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG) 962 if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG)
963 { 963 {
964 mu_msgset_clear (msgset); 964 mu_msgset_clear (msgset);
965 mu_msgset_add_range (msgset, i + 1, i + 1); 965 mu_msgset_add_range (msgset, i + 1, i + 1, MU_MSGSET_NUM);
966 if (rc) 966 if (rc)
967 break; 967 break;
968 rc = mu_imap_store_flags (imap, 0, msgset, 968 rc = mu_imap_store_flags (imap, 0, msgset,
...@@ -994,12 +994,13 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel) ...@@ -994,12 +994,13 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
994 } 994 }
995 } 995 }
996 if (tab[i].end == tab[i].start) 996 if (tab[i].end == tab[i].start)
997 rc = mu_msgset_add_range (msgset, tab[i].start + 1, 997 rc = mu_msgset_add_range (msgset,
998 tab[i].start + 1); 998 tab[i].start + 1, tab[i].start + 1,
999 MU_MSGSET_NUM);
999 else 1000 else
1000 rc = mu_msgset_add_range (msgset, 1001 rc = mu_msgset_add_range (msgset,
1001 tab[i].start + 1, 1002 tab[i].start + 1, tab[i].end + 1,
1002 tab[i].end + 1); 1003 MU_MSGSET_NUM);
1003 if (rc) 1004 if (rc)
1004 break; 1005 break;
1005 } 1006 }
...@@ -1192,10 +1193,10 @@ _imap_mbx_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) ...@@ -1192,10 +1193,10 @@ _imap_mbx_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
1192 1193
1193 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1, 1194 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
1194 (_("scanning mailbox %s"), mu_url_to_string (mbox->url))); 1195 (_("scanning mailbox %s"), mu_url_to_string (mbox->url)));
1195 rc = mu_msgset_create (&msgset, NULL, 0); 1196 rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
1196 if (rc) 1197 if (rc)
1197 return rc; 1198 return rc;
1198 rc = mu_msgset_add_range (msgset, msgno, MU_MSGNO_LAST); 1199 rc = mu_msgset_add_range (msgset, msgno, MU_MSGNO_LAST, MU_MSGSET_NUM);
1199 if (rc) 1200 if (rc)
1200 { 1201 {
1201 mu_msgset_free (msgset); 1202 mu_msgset_free (msgset);
......
...@@ -95,10 +95,11 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -95,10 +95,11 @@ opt_handler (int key, char *arg, struct argp_state *state)
95 return 0; 95 return 0;
96 } 96 }
97 97
98 void 98 int
99 anno (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 99 anno (size_t n, mu_message_t msg, void *call_data)
100 { 100 {
101 mh_annotate (msg, component, anno_text, anno_date); 101 mh_annotate (msg, component, anno_text, anno_date);
102 return 0;
102 } 103 }
103 104
104 int 105 int
...@@ -107,7 +108,7 @@ main (int argc, char **argv) ...@@ -107,7 +108,7 @@ main (int argc, char **argv)
107 int rc; 108 int rc;
108 int index; 109 int index;
109 mu_mailbox_t mbox; 110 mu_mailbox_t mbox;
110 mh_msgset_t msgset; 111 mu_msgset_t msgset;
111 size_t len; 112 size_t len;
112 113
113 MU_APP_INIT_NLS (); 114 MU_APP_INIT_NLS ();
...@@ -154,10 +155,16 @@ main (int argc, char **argv) ...@@ -154,10 +155,16 @@ main (int argc, char **argv)
154 argc -= index; 155 argc -= index;
155 argv += index; 156 argv += index;
156 157
157 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 158 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
158 rc = mh_iterate (mbox, &msgset, anno, NULL); 159 rc = mu_msgset_foreach_message (msgset, anno, NULL);
159 160 if (rc)
160 mh_msgset_current (mbox, &msgset, 0); 161 {
162 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_foreach_message", NULL, rc);
163 exit (1);
164 }
165
166 mh_msgset_first_current (mbox, msgset);
167 mu_msgset_free (msgset);
161 mh_global_save_state (); 168 mh_global_save_state ();
162 mu_mailbox_sync (mbox); 169 mu_mailbox_sync (mbox);
163 mu_mailbox_close (mbox); 170 mu_mailbox_close (mbox);
......
...@@ -578,8 +578,8 @@ burst_or_copy (mu_message_t msg, int recursive, int copy) ...@@ -578,8 +578,8 @@ burst_or_copy (mu_message_t msg, int recursive, int copy)
578 return 1; 578 return 1;
579 } 579 }
580 580
581 void 581 int
582 burst (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 582 burst (size_t num, mu_message_t msg, void *data)
583 { 583 {
584 memset (&map, 0, sizeof (map)); 584 memset (&map, 0, sizeof (map));
585 mh_message_number (msg, &map.msgno); 585 mh_message_number (msg, &map.msgno);
...@@ -599,36 +599,38 @@ burst (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) ...@@ -599,36 +599,38 @@ burst (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
599 } 599 }
600 else if (!quiet) 600 else if (!quiet)
601 mu_error (_("message %s not in digest format"), mu_umaxtostr (0, num)); 601 mu_error (_("message %s not in digest format"), mu_umaxtostr (0, num));
602 return 0;
602 } 603 }
603 604
604 605
605 /* Inplace handling */ 606 /* Inplace handling */
607 struct rename_env
608 {
609 size_t lastuid;
610 size_t idx;
611 };
606 612
607 void 613
608 burst_rename (mh_msgset_t *ms, size_t lastuid) 614 static int
615 _rename (size_t msgno, void *data)
609 { 616 {
610 size_t i, j; 617 struct rename_env *rp = data;
618
619 if (msgno == burst_map[rp->idx].msgno)
620 {
621 rp->lastuid -= burst_map[rp->idx].count;
622 burst_map[rp->idx].msgno = rp->lastuid;
623 rp->idx--;
624 }
611 625
612 VERBOSE ((_("Renaming messages"))); 626 if (msgno != rp->lastuid)
613 j = burst_count - 1;
614 for (i = ms->count; i > 0; i--)
615 { 627 {
616 const char *from; 628 const char *from;
617 const char *to; 629 const char *to;
618 630
619 if (ms->list[i-1] == burst_map[j].msgno) 631 from = mu_umaxtostr (0, msgno);
620 { 632 to = mu_umaxtostr (1, rp->lastuid);
621 lastuid -= burst_map[j].count; 633 --rp->lastuid;
622 burst_map[j].msgno = lastuid;
623 j--;
624 }
625
626 if (ms->list[i-1] == lastuid)
627 continue;
628
629 from = mu_umaxtostr (0, ms->list[i-1]);
630 to = mu_umaxtostr (1, lastuid);
631 --lastuid;
632 634
633 VERBOSE((_("message %s becomes message %s"), from, to)); 635 VERBOSE((_("message %s becomes message %s"), from, to));
634 636
...@@ -639,6 +641,18 @@ burst_rename (mh_msgset_t *ms, size_t lastuid) ...@@ -639,6 +641,18 @@ burst_rename (mh_msgset_t *ms, size_t lastuid)
639 exit (1); 641 exit (1);
640 } 642 }
641 } 643 }
644 return 0;
645 }
646
647 void
648 burst_rename (mu_msgset_t ms, size_t lastuid)
649 {
650 struct rename_env renv;
651
652 VERBOSE ((_("Renaming messages")));
653 renv.lastuid = lastuid;
654 renv.idx = burst_count - 1;
655 mu_msgset_foreach_dir_msguid (ms, 1, _rename, &renv);
642 } 656 }
643 657
644 void 658 void
...@@ -705,7 +719,7 @@ main (int argc, char **argv) ...@@ -705,7 +719,7 @@ main (int argc, char **argv)
705 { 719 {
706 int index, rc; 720 int index, rc;
707 mu_mailbox_t mbox; 721 mu_mailbox_t mbox;
708 mh_msgset_t msgset; 722 mu_msgset_t msgset;
709 const char *tempfolder = mh_global_profile_get ("Temp-Folder", ".temp"); 723 const char *tempfolder = mh_global_profile_get ("Temp-Folder", ".temp");
710 724
711 /* Native Language Support */ 725 /* Native Language Support */
...@@ -720,7 +734,7 @@ main (int argc, char **argv) ...@@ -720,7 +734,7 @@ main (int argc, char **argv)
720 734
721 VERBOSE ((_("Opening folder `%s'"), mh_current_folder ())); 735 VERBOSE ((_("Opening folder `%s'"), mh_current_folder ()));
722 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 736 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
723 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 737 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
724 738
725 if (inplace) 739 if (inplace)
726 { 740 {
...@@ -744,7 +758,7 @@ main (int argc, char **argv) ...@@ -744,7 +758,7 @@ main (int argc, char **argv)
744 else 758 else
745 tmpbox = mbox; 759 tmpbox = mbox;
746 760
747 rc = mh_iterate (mbox, &msgset, burst, NULL); 761 rc = mu_msgset_foreach_message (msgset, burst, NULL);
748 if (rc) 762 if (rc)
749 return rc; 763 return rc;
750 764
...@@ -752,8 +766,8 @@ main (int argc, char **argv) ...@@ -752,8 +766,8 @@ main (int argc, char **argv)
752 { 766 {
753 mu_url_t dst_url = NULL; 767 mu_url_t dst_url = NULL;
754 size_t i, next_uid, last_uid; 768 size_t i, next_uid, last_uid;
755 mh_msgset_t ms; 769 mu_msgset_t ms;
756 char *xargv[2]; 770 size_t count;
757 const char *dir; 771 const char *dir;
758 772
759 burst_map = obstack_finish (&stk); 773 burst_map = obstack_finish (&stk);
...@@ -763,11 +777,14 @@ main (int argc, char **argv) ...@@ -763,11 +777,14 @@ main (int argc, char **argv)
763 last_uid += burst_map[i].count; 777 last_uid += burst_map[i].count;
764 VERBOSE ((_("Estimated last UID: %s"), mu_umaxtostr (0, last_uid))); 778 VERBOSE ((_("Estimated last UID: %s"), mu_umaxtostr (0, last_uid)));
765 779
766 mu_asprintf (&xargv[0], "%s-last", mu_umaxtostr (0, burst_map[0].msgno)); 780 rc = mu_msgset_create (&ms, mbox, MU_MSGSET_NUM);
767 xargv[1] = NULL; 781 if (rc)
768 mh_msgset_parse (mbox, &ms, 1, xargv, NULL); 782 {
769 free (xargv[0]); 783 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc);
770 mh_msgset_uids (mbox, &ms); 784 exit (1);
785 }
786 mu_mailbox_messages_count (mbox, &count);
787 mu_msgset_add_range (ms, burst_map[0].msgno, count, MU_MSGSET_NUM);
771 788
772 mu_mailbox_get_url (mbox, &dst_url); 789 mu_mailbox_get_url (mbox, &dst_url);
773 mu_url_sget_path (dst_url, &dir); 790 mu_url_sget_path (dst_url, &dir);
...@@ -779,8 +796,8 @@ main (int argc, char **argv) ...@@ -779,8 +796,8 @@ main (int argc, char **argv)
779 } 796 }
780 mu_mailbox_close (mbox); 797 mu_mailbox_close (mbox);
781 798
782 burst_rename (&ms, last_uid); 799 burst_rename (ms, last_uid);
783 mh_msgset_free (&ms); 800 mu_msgset_free (ms);
784 801
785 finalize_inplace (last_uid); 802 finalize_inplace (last_uid);
786 803
......
...@@ -246,22 +246,21 @@ main (int argc, char **argv) ...@@ -246,22 +246,21 @@ main (int argc, char **argv)
246 `-draftfolder +folder' treat this arguments as `msg'. */ 246 `-draftfolder +folder' treat this arguments as `msg'. */
247 if (use_draft || index < argc) 247 if (use_draft || index < argc)
248 { 248 {
249 mh_msgset_t msgset; 249 mu_msgset_t msgset;
250 mu_mailbox_t mbox; 250 mu_mailbox_t mbox;
251 251
252 mbox = mh_open_folder (draftfolder, 252 mbox = mh_open_folder (draftfolder,
253 MU_STREAM_RDWR|MU_STREAM_CREAT); 253 MU_STREAM_RDWR|MU_STREAM_CREAT);
254 mh_msgset_parse (mbox, &msgset, 254 mh_msgset_parse (&msgset, mbox,
255 argc - index, argv + index, 255 argc - index, argv + index,
256 use_draft ? "cur" : "new"); 256 use_draft ? "cur" : "new");
257 mh_msgset_uids (mbox, &msgset); 257 if (!mh_msgset_single_message (msgset))
258 if (msgset.count != 1)
259 { 258 {
260 mu_error (_("only one message at a time!")); 259 mu_error (_("only one message at a time!"));
261 return 1; 260 return 1;
262 } 261 }
263 draftmessage = mu_umaxtostr (0, msgset.list[0]); 262 draftmessage = mu_umaxtostr (0, mh_msgset_first_uid (msgset));
264 mh_msgset_free (&msgset); 263 mu_msgset_free (msgset);
265 mu_mailbox_destroy (&mbox); 264 mu_mailbox_destroy (&mbox);
266 } 265 }
267 if (mh_draft_message (draftfolder, draftmessage, 266 if (mh_draft_message (draftfolder, draftmessage,
...@@ -273,20 +272,20 @@ main (int argc, char **argv) ...@@ -273,20 +272,20 @@ main (int argc, char **argv)
273 272
274 if (folder_set && index < argc) 273 if (folder_set && index < argc)
275 { 274 {
276 mh_msgset_t msgset; 275 mu_msgset_t msgset;
277 mu_mailbox_t mbox; 276 mu_mailbox_t mbox;
278 277
279 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); 278 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
280 mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur"); 279 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
281 if (msgset.count != 1) 280 if (!mh_msgset_single_message (msgset))
282 { 281 {
283 mu_error (_("only one message at a time!")); 282 mu_error (_("only one message at a time!"));
284 return 1; 283 return 1;
285 } 284 }
286 unlink (wh_env.file); 285 unlink (wh_env.file);
287 copy_message (mbox, msgset.list[0], wh_env.file); 286 copy_message (mbox, mh_msgset_first (msgset), wh_env.file);
288 mu_mailbox_destroy (&mbox); 287 mu_mailbox_destroy (&mbox);
289 mh_msgset_free (&msgset); 288 mu_msgset_free (msgset);
290 } 289 }
291 else 290 else
292 { 291 {
......
...@@ -773,9 +773,10 @@ pack_xlate (struct pack_tab *pack_tab, size_t count, size_t n) ...@@ -773,9 +773,10 @@ pack_xlate (struct pack_tab *pack_tab, size_t count, size_t n)
773 static int 773 static int
774 _fixup (const char *name, const char *value, struct fixup_data *fd, int flags) 774 _fixup (const char *name, const char *value, struct fixup_data *fd, int flags)
775 { 775 {
776 size_t i, j; 776 size_t i;
777 int rc;
777 struct mu_wordsplit ws; 778 struct mu_wordsplit ws;
778 mh_msgset_t msgset; 779 mu_msgset_t msgset;
779 780
780 if (verbose) 781 if (verbose)
781 fprintf (stderr, "Sequence `%s'...\n", name); 782 fprintf (stderr, "Sequence `%s'...\n", name);
...@@ -787,20 +788,32 @@ _fixup (const char *name, const char *value, struct fixup_data *fd, int flags) ...@@ -787,20 +788,32 @@ _fixup (const char *name, const char *value, struct fixup_data *fd, int flags)
787 return 0; 788 return 0;
788 } 789 }
789 790
790 msgset.list = xcalloc (ws.ws_wordc, sizeof msgset.list[0]); 791 rc = mu_msgset_create (&msgset, NULL, MU_MSGSET_UID);
791 for (i = j = 0; i < ws.ws_wordc; i++) 792 if (rc)
793 {
794 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc);
795 exit (1);
796 }
797
798 for (i = 0; i < ws.ws_wordc; i++)
792 { 799 {
793 size_t n = pack_xlate (fd->pack_tab, fd->count, 800 size_t n = pack_xlate (fd->pack_tab, fd->count,
794 strtoul (ws.ws_wordv[i], NULL, 0)); 801 strtoul (ws.ws_wordv[i], NULL, 0));
795 if (n) 802 if (n)
796 msgset.list[j++] = n; 803 {
804 rc = mu_msgset_add_range (msgset, n, n, MU_MSGSET_UID);
805 if (rc)
806 {
807 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_add_range", NULL, rc);
808 exit (1);
809 }
810 }
797 } 811 }
798 msgset.count = j;
799 812
800 mu_wordsplit_free (&ws); 813 mu_wordsplit_free (&ws);
801 814
802 mh_seq_add (fd->mbox, name, &msgset, flags | SEQ_ZERO); 815 mh_seq_add (fd->mbox, name, msgset, flags | SEQ_ZERO);
803 free (msgset.list); 816 mu_msgset_free (msgset);
804 817
805 if (verbose) 818 if (verbose)
806 { 819 {
...@@ -944,7 +957,7 @@ int ...@@ -944,7 +957,7 @@ int
944 main (int argc, char **argv) 957 main (int argc, char **argv)
945 { 958 {
946 int index = 0; 959 int index = 0;
947 mh_msgset_t msgset; 960 mu_msgset_t msgset;
948 961
949 /* Native Language Support */ 962 /* Native Language Support */
950 MU_APP_INIT_NLS (); 963 MU_APP_INIT_NLS ();
...@@ -971,9 +984,11 @@ main (int argc, char **argv) ...@@ -971,9 +984,11 @@ main (int argc, char **argv)
971 984
972 if (argc - index == 1) 985 if (argc - index == 1)
973 { 986 {
974 mu_mailbox_t mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 987 mu_mailbox_t mbox = mh_open_folder (mh_current_folder (),
975 mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur"); 988 MU_STREAM_RDWR);
976 mh_msgset_current (mbox, &msgset, 0); 989 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
990 mh_msgset_first_current (mbox, msgset);
991 mu_msgset_free (msgset);
977 mh_global_save_state (); 992 mh_global_save_state ();
978 mu_mailbox_close (mbox); 993 mu_mailbox_close (mbox);
979 mu_mailbox_destroy (&mbox); 994 mu_mailbox_destroy (&mbox);
......
...@@ -116,7 +116,7 @@ static char *draftmessage = "new"; ...@@ -116,7 +116,7 @@ static char *draftmessage = "new";
116 static const char *draftfolder = NULL; 116 static const char *draftfolder = NULL;
117 static char *input_file; /* input file name (--file option) */ 117 static char *input_file; /* input file name (--file option) */
118 118
119 static mh_msgset_t msgset; 119 static mu_msgset_t msgset;
120 static mu_mailbox_t mbox; 120 static mu_mailbox_t mbox;
121 121
122 static int 122 static int
...@@ -331,15 +331,27 @@ format_message (mu_stream_t outstr, mu_message_t msg, int num, ...@@ -331,15 +331,27 @@ format_message (mu_stream_t outstr, mu_message_t msg, int num,
331 } 331 }
332 } 332 }
333 333
334 void 334 int
335 format_message_itr (mu_mailbox_t mbox MU_ARG_UNUSED, 335 format_message_itr (size_t num, mu_message_t msg, void *data)
336 mu_message_t msg, size_t num, void *data)
337 { 336 {
338 struct format_data *fp = data; 337 struct format_data *fp = data;
339 338
340 format_message (fp->stream, msg, fp->num, fp->format); 339 format_message (fp->stream, msg, fp->num, fp->format);
341 if (fp->num) 340 if (fp->num)
342 fp->num++; 341 fp->num++;
342 return 0;
343 }
344
345 static int
346 _proc_forwards (size_t n, mu_message_t msg, void *call_data)
347 {
348 mu_stream_t stream = call_data;
349 size_t num;
350
351 if (annotate)
352 mu_list_append (wh_env.anno_list, msg);
353 mh_message_number (msg, &num);
354 return mu_stream_printf (stream, " %lu", (unsigned long) num);
343 } 355 }
344 356
345 void 357 void
...@@ -411,36 +423,22 @@ finish_draft () ...@@ -411,36 +423,22 @@ finish_draft ()
411 { 423 {
412 mu_url_t url; 424 mu_url_t url;
413 const char *mbox_path; 425 const char *mbox_path;
414 const char *p;
415 size_t i;
416 426
417 mu_mailbox_get_url (mbox, &url); 427 mu_mailbox_get_url (mbox, &url);
418 mu_url_sget_path (url, &mbox_path); 428 mu_url_sget_path (url, &mbox_path);
419 mu_asprintf (&str, "#forw [] +%s", mbox_path); 429 mu_asprintf (&str, "#forw [] +%s", mbox_path);
420 rc = mu_stream_write (stream, str, strlen (str), NULL); 430 rc = mu_stream_write (stream, str, strlen (str), NULL);
421 free (str); 431 free (str);
422 for (i = 0; rc == 0 && i < msgset.count; i++) 432 mu_msgset_foreach_message (msgset, _proc_forwards, stream);
423 {
424 mu_message_t msg;
425 size_t num;
426
427 mu_mailbox_get_message (mbox, msgset.list[i], &msg);
428 if (annotate)
429 mu_list_append (wh_env.anno_list, msg);
430 mh_message_number (msg, &num);
431 p = mu_umaxtostr (0, num);
432 rc = mu_stream_write (stream, " ", 1, NULL);
433 if (rc)
434 break;
435 rc = mu_stream_write (stream, p, strlen (p), NULL);
436 }
437 } 433 }
438 else 434 else
439 { 435 {
436 int single_message = mh_msgset_single_message (msgset);
437
440 str = "\n------- "; 438 str = "\n------- ";
441 rc = mu_stream_write (stream, str, strlen (str), NULL); 439 rc = mu_stream_write (stream, str, strlen (str), NULL);
442 440
443 if (msgset.count == 1) 441 if (single_message)
444 { 442 {
445 fd.num = 0; 443 fd.num = 0;
446 str = (char*) _("Forwarded message\n"); 444 str = (char*) _("Forwarded message\n");
...@@ -454,12 +452,12 @@ finish_draft () ...@@ -454,12 +452,12 @@ finish_draft ()
454 rc = mu_stream_write (stream, str, strlen (str), NULL); 452 rc = mu_stream_write (stream, str, strlen (str), NULL);
455 fd.stream = stream; 453 fd.stream = stream;
456 fd.format = format; 454 fd.format = format;
457 rc = mh_iterate (mbox, &msgset, format_message_itr, &fd); 455 rc = mu_msgset_foreach_message (msgset, format_message_itr, &fd);
458 456
459 str = "\n------- "; 457 str = "\n------- ";
460 rc = mu_stream_write (stream, str, strlen (str), NULL); 458 rc = mu_stream_write (stream, str, strlen (str), NULL);
461 459
462 if (msgset.count == 1) 460 if (single_message)
463 str = (char*) _("End of Forwarded message"); 461 str = (char*) _("End of Forwarded message");
464 else 462 else
465 str = (char*) _("End of Forwarded messages"); 463 str = (char*) _("End of Forwarded messages");
...@@ -504,7 +502,7 @@ main (int argc, char **argv) ...@@ -504,7 +502,7 @@ main (int argc, char **argv)
504 else 502 else
505 { 503 {
506 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 504 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
507 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 505 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
508 } 506 }
509 507
510 if (build_only || !draftfolder) 508 if (build_only || !draftfolder)
......
...@@ -121,7 +121,7 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -121,7 +121,7 @@ opt_handler (int key, char *arg, struct argp_state *state)
121 struct mark_closure 121 struct mark_closure
122 { 122 {
123 mu_mailbox_t mbox; 123 mu_mailbox_t mbox;
124 mh_msgset_t *msgset; 124 mu_msgset_t msgset;
125 }; 125 };
126 126
127 static int 127 static int
...@@ -191,7 +191,7 @@ int ...@@ -191,7 +191,7 @@ int
191 main (int argc, char **argv) 191 main (int argc, char **argv)
192 { 192 {
193 int index; 193 int index;
194 mh_msgset_t msgset; 194 mu_msgset_t msgset;
195 mu_mailbox_t mbox; 195 mu_mailbox_t mbox;
196 mu_url_t url; 196 mu_url_t url;
197 struct mark_closure clos; 197 struct mark_closure clos;
...@@ -209,11 +209,11 @@ main (int argc, char **argv) ...@@ -209,11 +209,11 @@ main (int argc, char **argv)
209 209
210 argc -= index; 210 argc -= index;
211 argv += index; 211 argv += index;
212 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 212 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
213 mh_msgset_uids (mbox, &msgset);
214 213
215 clos.mbox = mbox; 214 clos.mbox = mbox;
216 clos.msgset = &msgset; 215 clos.msgset = msgset;
216 //FIXME: msgset operates on UIDs but there's no way to inform it about that.
217 switch (action) 217 switch (action)
218 { 218 {
219 case ARG_ADD: 219 case ARG_ADD:
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
60 #include <mailutils/mh.h> 60 #include <mailutils/mh.h>
61 #include <mailutils/stdstream.h> 61 #include <mailutils/stdstream.h>
62 #include <mailutils/datetime.h> 62 #include <mailutils/datetime.h>
63 #include <mailutils/msgset.h>
63 64
64 #include <mu_umaxtostr.h> 65 #include <mu_umaxtostr.h>
65 66
...@@ -194,19 +195,6 @@ typedef struct ...@@ -194,19 +195,6 @@ typedef struct
194 mu_header_t header; 195 mu_header_t header;
195 } mh_context_t; 196 } mh_context_t;
196 197
197 #define MH_MSGSET_UID 0x01
198
199 typedef struct
200 {
201 int flags;
202 size_t *list;
203 size_t count;
204 size_t size;
205 } mh_msgset_t;
206
207 typedef void (*mh_iterator_fp) (mu_mailbox_t mbox, mu_message_t msg,
208 size_t num, void *data);
209
210 /* Recipient masks */ 198 /* Recipient masks */
211 #define RCPT_NONE 0 199 #define RCPT_NONE 0
212 #define RCPT_TO 0x0001 200 #define RCPT_TO 0x0001
...@@ -303,14 +291,14 @@ int mh_message_number (mu_message_t msg, size_t *pnum); ...@@ -303,14 +291,14 @@ int mh_message_number (mu_message_t msg, size_t *pnum);
303 291
304 mu_mailbox_t mh_open_folder (const char *folder, int flags); 292 mu_mailbox_t mh_open_folder (const char *folder, int flags);
305 293
306 void mh_msgset_parse (mu_mailbox_t mbox, mh_msgset_t *msgset, 294 void mh_msgset_parse (mu_msgset_t *msgset, mu_mailbox_t mbox,
307 int argc, char **argv, char *def); 295 int argc, char **argv, char *def);
308 int mh_msgset_member (mh_msgset_t *msgset, size_t num); 296 void mh_msgset_parse_string (mu_msgset_t *msgset, mu_mailbox_t mbox,
309 void mh_msgset_reverse (mh_msgset_t *msgset); 297 const char *string, char *def);
310 void mh_msgset_negate (mu_mailbox_t mbox, mh_msgset_t *msgset); 298 void mh_msgset_first_current (mu_mailbox_t mbox, mu_msgset_t msgset);
311 void mh_msgset_current (mu_mailbox_t mbox, mh_msgset_t *msgset, int index); 299 size_t mh_msgset_first (mu_msgset_t msgset);
312 void mh_msgset_free (mh_msgset_t *msgset); 300 size_t mh_msgset_first_uid (mu_msgset_t msgset);
313 void mh_msgset_uids (mu_mailbox_t mbox, mh_msgset_t *msgset); 301 int mh_msgset_single_message (mu_msgset_t msgset);
314 302
315 char *mh_get_dir (void); 303 char *mh_get_dir (void);
316 int mh_find_file (const char *name, char **resolved_name); 304 int mh_find_file (const char *name, char **resolved_name);
...@@ -323,9 +311,6 @@ void mh_expand_aliases (mu_message_t msg, mu_address_t *addr_to, ...@@ -323,9 +311,6 @@ void mh_expand_aliases (mu_message_t msg, mu_address_t *addr_to,
323 int mh_is_my_name (const char *name); 311 int mh_is_my_name (const char *name);
324 char * mh_my_email (void); 312 char * mh_my_email (void);
325 313
326 int mh_iterate (mu_mailbox_t mbox, mh_msgset_t *msgset,
327 mh_iterator_fp itr, void *data);
328
329 size_t mh_get_message (mu_mailbox_t mbox, size_t seqno, mu_message_t *mesg); 314 size_t mh_get_message (mu_mailbox_t mbox, size_t seqno, mu_message_t *mesg);
330 315
331 int mh_decode_rcpt_flag (const char *arg); 316 int mh_decode_rcpt_flag (const char *arg);
...@@ -372,9 +357,9 @@ int mhl_format_run (mu_list_t fmt, int width, int length, int flags, ...@@ -372,9 +357,9 @@ int mhl_format_run (mu_list_t fmt, int width, int length, int flags,
372 mu_message_t msg, mu_stream_t output); 357 mu_message_t msg, mu_stream_t output);
373 void mhl_format_destroy (mu_list_t *fmt); 358 void mhl_format_destroy (mu_list_t *fmt);
374 359
375 void mh_seq_add (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset, 360 void mh_seq_add (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
376 int flags); 361 int flags);
377 int mh_seq_delete (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset, 362 int mh_seq_delete (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
378 int flags); 363 int flags);
379 const char *mh_seq_read (mu_mailbox_t mbox, const char *name, int flags); 364 const char *mh_seq_read (mu_mailbox_t mbox, const char *name, int flags);
380 365
......
...@@ -577,32 +577,6 @@ mh_find_file (const char *name, char **resolved_name) ...@@ -577,32 +577,6 @@ mh_find_file (const char *name, char **resolved_name)
577 } 577 }
578 578
579 int 579 int
580 mh_iterate (mu_mailbox_t mbox, mh_msgset_t *msgset,
581 mh_iterator_fp itr, void *data)
582 {
583 int rc;
584 size_t i;
585
586 for (i = 0; i < msgset->count; i++)
587 {
588 mu_message_t msg;
589 size_t num;
590
591 num = msgset->list[i];
592 if ((rc = mu_mailbox_get_message (mbox, num, &msg)) != 0)
593 {
594 mu_error (_("cannot get message %lu: %s"),
595 (unsigned long) num, mu_strerror (rc));
596 return 1;
597 }
598
599 itr (mbox, msg, num, data);
600 }
601
602 return 0;
603 }
604
605 int
606 mh_spawnp (const char *prog, const char *file) 580 mh_spawnp (const char *prog, const char *file)
607 { 581 {
608 struct mu_wordsplit ws; 582 struct mu_wordsplit ws;
...@@ -1039,19 +1013,16 @@ mh_draft_message (const char *name, const char *msgspec, char **pname) ...@@ -1039,19 +1013,16 @@ mh_draft_message (const char *name, const char *msgspec, char **pname)
1039 else 1013 else
1040 { 1014 {
1041 char *argv[2]; 1015 char *argv[2];
1042 mh_msgset_t msgset; 1016 mu_msgset_t msgset;
1043 1017
1044 argv[0] = (char*) msgspec; 1018 argv[0] = (char*) msgspec;
1045 argv[1] = NULL; 1019 argv[1] = NULL;
1046 mh_msgset_parse (mbox, &msgset, 1, argv, "cur"); 1020 mh_msgset_parse (&msgset, mbox, 1, argv, "cur");
1047 if (msgset.count > 1) 1021 if (!mh_msgset_single_message (msgset))
1048 mu_error (_("only one message at a time!")); 1022 mu_error (_("only one message at a time!"));
1049 else 1023 else
1050 { 1024 uid = mh_msgset_first_uid (msgset);
1051 mh_msgset_uids (mbox, &msgset); 1025 mu_msgset_free (msgset);
1052 uid = msgset.list[0];
1053 }
1054 mh_msgset_free (&msgset);
1055 } 1026 }
1056 1027
1057 mu_url_sget_path (url, &path); 1028 mu_url_sget_path (url, &path);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ 16 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
17 17
18 #include <mh.h> 18 #include <mh.h>
19 #include <mailutils/sys/msgset.h>
19 20
20 static char * 21 static char *
21 private_sequence_name (const char *name) 22 private_sequence_name (const char *name)
...@@ -62,118 +63,124 @@ delete_sequence (mu_mailbox_t mbox, const char *name, int private) ...@@ -62,118 +63,124 @@ delete_sequence (mu_mailbox_t mbox, const char *name, int private)
62 write_sequence (mbox, name, NULL, private); 63 write_sequence (mbox, name, NULL, private);
63 } 64 }
64 65
65 void 66 struct format_closure
66 mh_seq_add (mu_mailbox_t mbox, const char *name, mh_msgset_t *mset, int flags)
67 { 67 {
68 const char *value = mh_seq_read (mbox, name, flags); 68 mu_stream_t stream;
69 char *new_value, *p; 69 mu_mailbox_t mailbox;
70 const char *buf; 70 };
71 size_t i, len;
72 71
73 delete_sequence (mbox, name, !(flags & SEQ_PRIVATE)); 72 static int
73 format_sequence (void *item, void *data)
74 {
75 struct mu_msgrange *r = item;
76 struct format_closure *clos = data;
77 int rc;
78 size_t beg, end;
74 79
75 if (flags & SEQ_ZERO) 80 if (clos->mailbox)
76 value = NULL; 81 {
77 82 rc = mu_mailbox_translate (clos->mailbox,
78 if (value) 83 MU_MAILBOX_MSGNO_TO_UID,
79 len = strlen (value); 84 r->msg_beg, &beg);
85 if (rc)
86 return rc;
87 }
88 else
89 beg = r->msg_beg;
90 if (r->msg_beg == r->msg_end)
91 rc = mu_stream_printf (clos->stream, " %lu", (unsigned long) beg);
80 else 92 else
81 len = 0;
82 len++;
83 for (i = 0; i < mset->count; i++)
84 { 93 {
85 buf = mu_umaxtostr (0, mset->list[i]); 94 if (clos->mailbox)
86 len += strlen (buf) + 1; 95 {
96 rc = mu_mailbox_translate (clos->mailbox,
97 MU_MAILBOX_MSGNO_TO_UID,
98 r->msg_end, &end);
99 if (rc)
100 return rc;
101 }
102 else
103 end = r->msg_end;
104 if (beg + 1 == end)
105 rc = mu_stream_printf (clos->stream, " %lu %lu",
106 (unsigned long) beg,
107 (unsigned long) end);
108 else
109 rc = mu_stream_printf (clos->stream, " %lu-%lu",
110 (unsigned long) beg,
111 (unsigned long) end);
87 } 112 }
113 return rc;
114 }
88 115
89 new_value = xmalloc (len + 1); 116 static void
90 if (value) 117 save_sequence (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
91 strcpy (new_value, value); 118 int flags)
119 {
120 mu_list_t list;
121
122 mu_msgset_get_list (mset, &list);
123 if (mu_list_is_empty (list))
124 write_sequence (mset->mbox, name, NULL, flags & SEQ_PRIVATE);
92 else 125 else
93 new_value[0] = 0;
94 p = new_value + strlen (new_value);
95 *p++ = ' ';
96 for (i = 0; i < mset->count; i++)
97 { 126 {
98 p += sprintf (p, "%s", mu_umaxtostr (0, mset->list[i])); 127 struct format_closure clos;
99 *p++ = ' '; 128 int rc;
129 mu_transport_t trans[2];
130
131 rc = mu_memory_stream_create (&clos.stream, MU_STREAM_RDWR);
132 if (rc)
133 {
134 mu_diag_funcall (MU_DIAG_ERROR, "mu_memory_stream_create", NULL, rc);
135 exit (1);
136 }
137
138 clos.mailbox = mset->mbox;
139 rc = mu_list_foreach (list, format_sequence, &clos);
140 if (rc)
141 {
142 mu_diag_funcall (MU_DIAG_ERROR, "mu_list_foreach", NULL, rc);
143 exit (1);
144 }
145 mu_stream_write (clos.stream, "", 1, NULL);
146 mu_stream_ioctl (clos.stream, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
147 trans);
148 write_sequence (mbox, name, (char*)trans[0], flags & SEQ_PRIVATE);
149 mu_stream_unref (clos.stream);
100 } 150 }
101 *p = 0;
102 write_sequence (mbox, name, new_value, flags & SEQ_PRIVATE);
103 /* FIXME
104 if (mu_c_strcasecmp (name, "cur") == 0)
105 current_message = strtoul (new_value, NULL, 0);
106 */
107 free (new_value);
108 } 151 }
109 152
110 static int 153 void
111 cmp_msgnum (const void *a, const void *b) 154 mh_seq_add (mu_mailbox_t mbox, const char *name, mu_msgset_t mset, int flags)
112 { 155 {
113 const size_t *as = a; 156 const char *value = mh_seq_read (mbox, name, flags);
114 const size_t *bs = b; 157
115 158 delete_sequence (mbox, name, !(flags & SEQ_PRIVATE));
116 if (*as < *bs) 159 if (value && !(flags & SEQ_ZERO))
117 return -1; 160 {
118 if (*as > *bs) 161 mu_msgset_t oldset;
119 return 1; 162 mh_msgset_parse_string (&oldset, mbox, value, "cur");
120 return 0; 163 mu_msgset_add (oldset, mset);
164 save_sequence (mbox, name, oldset, flags);
165 mu_msgset_free (oldset);
166 }
167 else
168 save_sequence (mbox, name, mset, flags);
121 } 169 }
122 170
123 int 171 int
124 mh_seq_delete (mu_mailbox_t mbox, const char *name, 172 mh_seq_delete (mu_mailbox_t mbox, const char *name,
125 mh_msgset_t *mset, int flags) 173 mu_msgset_t mset, int flags)
126 { 174 {
127 const char *value = mh_seq_read (mbox, name, flags); 175 const char *value = mh_seq_read (mbox, name, flags);
128 char *new_val; 176 mu_msgset_t oldset;
129 char *p; 177
130 size_t i, count;
131 struct mu_wordsplit ws;
132
133 if (!value) 178 if (!value)
134 return 0; 179 return 0;
135 180 mh_msgset_parse_string (&oldset, mbox, value, "cur");
136 if (mu_wordsplit (value, &ws, MU_WRDSF_DEFFLAGS)) 181 mu_msgset_sub (oldset, mset);
137 { 182 save_sequence (mbox, name, oldset, flags);
138 mu_error (_("cannot split line `%s': %s"), value, 183 mu_msgset_free (oldset);
139 mu_wordsplit_strerror (&ws));
140 return 0;
141 }
142
143 for (i = 0; i < ws.ws_wordc; i++)
144 {
145 char *p;
146 size_t num = strtoul (ws.ws_wordv[i], &p, 10);
147
148 if (*p)
149 continue;
150
151 if (bsearch (&num, mset->list, mset->count, sizeof (mset->list[0]),
152 cmp_msgnum))
153 {
154 free (ws.ws_wordv[i]);
155 ws.ws_wordv[i] = NULL;
156 }
157 }
158
159 new_val = xstrdup (value);
160 p = new_val;
161 count = 0;
162 for (i = 0; i < ws.ws_wordc; i++)
163 {
164 if (ws.ws_wordv[i])
165 {
166 strcpy (p, ws.ws_wordv[i]);
167 p += strlen (p);
168 *p++ = ' ';
169 count++;
170 }
171 }
172 *p = 0;
173 write_sequence (mbox, name, count > 0 ? new_val : NULL, flags & SEQ_PRIVATE);
174 mu_wordsplit_free (&ws);
175 free (new_val);
176
177 return 0; 184 return 0;
178 } 185 }
179 186
......
...@@ -158,7 +158,7 @@ static int width = 80; ...@@ -158,7 +158,7 @@ static int width = 80;
158 static char *charset; /* Charset for output file names. NULL means 158 static char *charset; /* Charset for output file names. NULL means
159 no recoding is necessary. */ 159 no recoding is necessary. */
160 160
161 static mh_msgset_t msgset; 161 static mu_msgset_t msgset;
162 static mu_mailbox_t mbox; 162 static mu_mailbox_t mbox;
163 static mu_message_t message; 163 static mu_message_t message;
164 static msg_part_t req_part; 164 static msg_part_t req_part;
...@@ -1369,7 +1369,7 @@ list_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, ...@@ -1369,7 +1369,7 @@ list_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
1369 } 1369 }
1370 1370
1371 int 1371 int
1372 list_message (mu_message_t msg, size_t num) 1372 list_message (mu_message_t msg)
1373 { 1373 {
1374 size_t uid; 1374 size_t uid;
1375 msg_part_t part; 1375 msg_part_t part;
...@@ -1381,10 +1381,10 @@ list_message (mu_message_t msg, size_t num) ...@@ -1381,10 +1381,10 @@ list_message (mu_message_t msg, size_t num)
1381 return 0; 1381 return 0;
1382 } 1382 }
1383 1383
1384 void 1384 int
1385 list_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 1385 list_iterator (size_t num, mu_message_t msg, void *data)
1386 { 1386 {
1387 list_message (msg, num); 1387 return list_message (msg);
1388 } 1388 }
1389 1389
1390 int 1390 int
...@@ -1396,9 +1396,9 @@ mhn_list () ...@@ -1396,9 +1396,9 @@ mhn_list ()
1396 printf (_(" msg part type/subtype size description\n")); 1396 printf (_(" msg part type/subtype size description\n"));
1397 1397
1398 if (message) 1398 if (message)
1399 rc = list_message (message, 0); 1399 rc = list_message (message);
1400 else 1400 else
1401 rc = mh_iterate (mbox, &msgset, list_iterator, NULL); 1401 rc = mu_msgset_foreach_message (msgset, list_iterator, NULL);
1402 return rc; 1402 return rc;
1403 } 1403 }
1404 1404
...@@ -1609,8 +1609,8 @@ show_message (mu_message_t msg, size_t num, void *data) ...@@ -1609,8 +1609,8 @@ show_message (mu_message_t msg, size_t num, void *data)
1609 return 0; 1609 return 0;
1610 } 1610 }
1611 1611
1612 void 1612 int
1613 show_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 1613 show_iterator (size_t num, mu_message_t msg, void *data)
1614 { 1614 {
1615 msg_part_t part; 1615 msg_part_t part;
1616 1616
...@@ -1618,6 +1618,7 @@ show_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) ...@@ -1618,6 +1618,7 @@ show_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
1618 part = msg_part_create (num); 1618 part = msg_part_create (num);
1619 show_message (msg, num, data); 1619 show_message (msg, num, data);
1620 msg_part_destroy (part); 1620 msg_part_destroy (part);
1621 return 0;
1621 } 1622 }
1622 1623
1623 int 1624 int
...@@ -1630,7 +1631,7 @@ mhn_show () ...@@ -1630,7 +1631,7 @@ mhn_show ()
1630 if (message) 1631 if (message)
1631 rc = show_message (message, 0, mu_strout); 1632 rc = show_message (message, 0, mu_strout);
1632 else 1633 else
1633 rc = mh_iterate (mbox, &msgset, show_iterator, mu_strout); 1634 rc = mu_msgset_foreach_message (msgset, show_iterator, mu_strout);
1634 mu_stream_flush (mu_strout); 1635 mu_stream_flush (mu_strout);
1635 return rc; 1636 return rc;
1636 } 1637 }
...@@ -1855,10 +1856,11 @@ store_message (mu_message_t msg, void *data) ...@@ -1855,10 +1856,11 @@ store_message (mu_message_t msg, void *data)
1855 msg_part_destroy (part); 1856 msg_part_destroy (part);
1856 } 1857 }
1857 1858
1858 void 1859 int
1859 store_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 1860 store_iterator (size_t num, mu_message_t msg, void *data)
1860 { 1861 {
1861 store_message (msg, data); 1862 store_message (msg, data);
1863 return 0;
1862 } 1864 }
1863 1865
1864 int 1866 int
...@@ -1876,7 +1878,7 @@ mhn_store () ...@@ -1876,7 +1878,7 @@ mhn_store ()
1876 store_message (message, p); 1878 store_message (message, p);
1877 } 1879 }
1878 else 1880 else
1879 rc = mh_iterate (mbox, &msgset, store_iterator, NULL); 1881 rc = mu_msgset_foreach_message (msgset, store_iterator, NULL);
1880 return rc; 1882 return rc;
1881 } 1883 }
1882 1884
...@@ -2982,7 +2984,7 @@ main (int argc, char **argv) ...@@ -2982,7 +2984,7 @@ main (int argc, char **argv)
2982 else 2984 else
2983 { 2985 {
2984 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); 2986 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
2985 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 2987 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
2986 } 2988 }
2987 2989
2988 switch (mode) 2990 switch (mode)
......
...@@ -50,13 +50,14 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -50,13 +50,14 @@ opt_handler (int key, char *arg, struct argp_state *state)
50 return 0; 50 return 0;
51 } 51 }
52 52
53 void 53 static int
54 mhpath (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 54 mhpath (size_t num, mu_message_t msg, void *data)
55 { 55 {
56 size_t uid; 56 size_t uid;
57 57
58 mh_message_number (msg, &uid); 58 mh_message_number (msg, &uid);
59 printf ("%s/%s\n", (char*) data, mu_umaxtostr (0, uid)); 59 printf ("%s/%s\n", (char*) data, mu_umaxtostr (0, uid));
60 return 0;
60 } 61 }
61 62
62 int 63 int
...@@ -67,7 +68,7 @@ main (int argc, char **argv) ...@@ -67,7 +68,7 @@ main (int argc, char **argv)
67 mu_url_t url = NULL; 68 mu_url_t url = NULL;
68 char *mhdir; 69 char *mhdir;
69 size_t total; 70 size_t total;
70 mh_msgset_t msgset; 71 mu_msgset_t msgset;
71 int status; 72 int status;
72 const char *current_folder; 73 const char *current_folder;
73 74
...@@ -125,9 +126,9 @@ main (int argc, char **argv) ...@@ -125,9 +126,9 @@ main (int argc, char **argv)
125 /* Mhpath expands and sorts the message list `msgs' and 126 /* Mhpath expands and sorts the message list `msgs' and
126 writes the full pathnames of the messages to the standard 127 writes the full pathnames of the messages to the standard
127 output separated by newlines. */ 128 output separated by newlines. */
128 mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur"); 129 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
129 status = mh_iterate (mbox, &msgset, mhpath, mhdir); 130 status = mu_msgset_foreach_message (msgset, mhpath, mhdir);
130 mu_mailbox_close (mbox); 131 mu_mailbox_close (mbox);
131 mu_mailbox_destroy (&mbox); 132 mu_mailbox_destroy (&mbox);
132 return status; 133 return status != 0;
133 } 134 }
......
...@@ -63,13 +63,19 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -63,13 +63,19 @@ opt_handler (int key, char *arg, struct argp_state *state)
63 return 0; 63 return 0;
64 } 64 }
65 65
66 static int
67 _print_number (size_t n, void *data)
68 {
69 printf ("%lu\n", (unsigned long) n);
70 return 0;
71 }
72
66 int 73 int
67 main (int argc, char **argv) 74 main (int argc, char **argv)
68 { 75 {
69 int index; 76 int index;
70 mu_mailbox_t mbox; 77 mu_mailbox_t mbox;
71 mh_msgset_t msgset; 78 mu_msgset_t msgset;
72 size_t i;
73 79
74 /* Native Language Support */ 80 /* Native Language Support */
75 MU_APP_INIT_NLS (); 81 MU_APP_INIT_NLS ();
...@@ -82,12 +88,11 @@ main (int argc, char **argv) ...@@ -82,12 +88,11 @@ main (int argc, char **argv)
82 argv += index; 88 argv += index;
83 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); 89 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
84 90
85 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 91 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
86 if (uid_option) 92 if (uid_option)
87 mh_msgset_uids (mbox, &msgset); 93 mu_msgset_foreach_msguid (msgset, _print_number, NULL);
88 94 else
89 for (i = 0; i < msgset.count; i++) 95 mu_msgset_foreach_msgno (msgset, _print_number, NULL);
90 printf ("%lu\n", (unsigned long) msgset.list[i]);
91 return 0; 96 return 0;
92 } 97 }
93 98
......
...@@ -21,9 +21,6 @@ ...@@ -21,9 +21,6 @@
21 #include <regex.h> 21 #include <regex.h>
22 #include <pick.h> 22 #include <pick.h>
23 #include <pick-gram.h> 23 #include <pick-gram.h>
24 #define obstack_chunk_alloc malloc
25 #define obstack_chunk_free free
26 #include <obstack.h>
27 24
28 static char doc[] = N_("GNU MH pick")"\v" 25 static char doc[] = N_("GNU MH pick")"\v"
29 N_("Compatibility syntax for picking a matching component is:\n\ 26 N_("Compatibility syntax for picking a matching component is:\n\
...@@ -146,8 +143,7 @@ static mu_list_t seq_list; /* List of sequence names to operate upon */ ...@@ -146,8 +143,7 @@ static mu_list_t seq_list; /* List of sequence names to operate upon */
146 143
147 static mu_list_t lexlist; /* List of input tokens */ 144 static mu_list_t lexlist; /* List of input tokens */
148 145
149 static struct obstack msgno_stk; /* Stack of selected message numbers */ 146 static mu_msgset_t picked_message_uids;
150 static size_t msgno_count; /* Number of items on the stack */
151 147
152 static void 148 static void
153 add_sequence (char *name) 149 add_sequence (char *name)
...@@ -282,34 +278,26 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -282,34 +278,26 @@ opt_handler (int key, char *arg, struct argp_state *state)
282 return 0; 278 return 0;
283 } 279 }
284 280
285 void 281 static int
286 pick_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 282 pick_message (size_t num, mu_message_t msg, void *data)
287 { 283 {
288 if (pick_eval (msg)) 284 if (pick_eval (msg))
289 { 285 {
290 mh_message_number (msg, &num); 286 mh_message_number (msg, &num);
291 if (list) 287 if (list)
292 printf ("%s\n", mu_umaxtostr (0, num)); 288 printf ("%s\n", mu_umaxtostr (0, num));
293 if (seq_list) 289 if (picked_message_uids)
294 { 290 mu_msgset_add_range (picked_message_uids, num, num, MU_MSGSET_UID);
295 obstack_grow (&msgno_stk, &num, sizeof (num));
296 msgno_count++;
297 }
298 } 291 }
292 return 0;
299 } 293 }
300 294
301 295
302 struct pick_closure
303 {
304 mu_mailbox_t mbox;
305 mh_msgset_t *msgset;
306 };
307
308 static int 296 static int
309 action_add (void *item, void *data) 297 action_add (void *item, void *data)
310 { 298 {
311 struct pick_closure *clos = data; 299 mu_mailbox_t mbox = data;
312 mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags); 300 mh_seq_add (mbox, (char *)item, picked_message_uids, seq_flags);
313 return 0; 301 return 0;
314 } 302 }
315 303
...@@ -356,7 +344,7 @@ main (int argc, char **argv) ...@@ -356,7 +344,7 @@ main (int argc, char **argv)
356 int status; 344 int status;
357 int index; 345 int index;
358 mu_mailbox_t mbox; 346 mu_mailbox_t mbox;
359 mh_msgset_t msgset; 347 mu_msgset_t msgset;
360 int interactive = mh_interactive_mode_p (); 348 int interactive = mh_interactive_mode_p ();
361 349
362 MU_APP_INIT_NLS (); 350 MU_APP_INIT_NLS ();
...@@ -397,21 +385,13 @@ main (int argc, char **argv) ...@@ -397,21 +385,13 @@ main (int argc, char **argv)
397 argv += index; 385 argv += index;
398 386
399 if (seq_list) 387 if (seq_list)
400 obstack_init (&msgno_stk); 388 mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID);
401 389
402 mh_msgset_parse (mbox, &msgset, argc, argv, "all"); 390 mh_msgset_parse (&msgset, mbox, argc, argv, "all");
403 status = mh_iterate (mbox, &msgset, pick_message, NULL); 391 status = mu_msgset_foreach_message (msgset, pick_message, NULL);
404 392
405 if (seq_list) 393 if (picked_message_uids)
406 { 394 mu_list_foreach (seq_list, action_add, mbox);
407 struct pick_closure clos;
408 mh_msgset_t msgset;
409 msgset.count = msgno_count;
410 msgset.list = obstack_finish (&msgno_stk);
411 clos.mbox = mbox;
412 clos.msgset = &msgset;
413 mu_list_foreach (seq_list, action_add, &clos);
414 }
415 395
416 mh_global_save_state (); 396 mh_global_save_state ();
417 mu_mailbox_close (mbox); 397 mu_mailbox_close (mbox);
......
...@@ -201,8 +201,8 @@ refile (mu_message_t msg) ...@@ -201,8 +201,8 @@ refile (mu_message_t msg)
201 enumerate_folders (refile_folder, msg); 201 enumerate_folders (refile_folder, msg);
202 } 202 }
203 203
204 void 204 int
205 refile_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 205 refile_iterator (size_t num, mu_message_t msg, void *data)
206 { 206 {
207 enumerate_folders (refile_folder, msg); 207 enumerate_folders (refile_folder, msg);
208 if (!link_flag) 208 if (!link_flag)
...@@ -211,13 +211,14 @@ refile_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) ...@@ -211,13 +211,14 @@ refile_iterator (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
211 mu_message_get_attribute (msg, &attr); 211 mu_message_get_attribute (msg, &attr);
212 mu_attribute_set_deleted (attr); 212 mu_attribute_set_deleted (attr);
213 } 213 }
214 return 0;
214 } 215 }
215 216
216 int 217 int
217 main (int argc, char **argv) 218 main (int argc, char **argv)
218 { 219 {
219 int index; 220 int index;
220 mh_msgset_t msgset; 221 mu_msgset_t msgset;
221 mu_mailbox_t mbox; 222 mu_mailbox_t mbox;
222 int status, i, j; 223 int status, i, j;
223 224
...@@ -262,9 +263,9 @@ main (int argc, char **argv) ...@@ -262,9 +263,9 @@ main (int argc, char **argv)
262 else 263 else
263 { 264 {
264 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 265 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
265 mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); 266 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
266 267
267 status = mh_iterate (mbox, &msgset, refile_iterator, NULL); 268 status = mu_msgset_foreach_message (msgset, refile_iterator, NULL);
268 269
269 mu_mailbox_expunge (mbox); 270 mu_mailbox_expunge (mbox);
270 mu_mailbox_close (mbox); 271 mu_mailbox_close (mbox);
......
...@@ -112,7 +112,7 @@ static int width = 80; ...@@ -112,7 +112,7 @@ static int width = 80;
112 struct mh_whatnow_env wh_env = { 0 }; 112 struct mh_whatnow_env wh_env = { 0 };
113 static int initial_edit = 1; 113 static int initial_edit = 1;
114 static const char *whatnowproc; 114 static const char *whatnowproc;
115 static mh_msgset_t msgset; 115 static mu_msgset_t msgset;
116 static mu_mailbox_t mbox; 116 static mu_mailbox_t mbox;
117 static int build_only = 0; /* --build flag */ 117 static int build_only = 0; /* --build flag */
118 static int query_mode = 0; /* --query flag */ 118 static int query_mode = 0; /* --query flag */
...@@ -281,6 +281,7 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) ...@@ -281,6 +281,7 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
281 int rc; 281 int rc;
282 mu_message_t msg; 282 mu_message_t msg;
283 struct stat st; 283 struct stat st;
284 size_t msgno;
284 285
285 /* First check if the draft exists */ 286 /* First check if the draft exists */
286 if (!build_only && stat (wh->draftfile, &st) == 0) 287 if (!build_only && stat (wh->draftfile, &st) == 0)
...@@ -309,12 +310,13 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) ...@@ -309,12 +310,13 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
309 unlink (wh->draftfile); 310 unlink (wh->draftfile);
310 break; 311 break;
311 } 312 }
312 313
313 rc = mu_mailbox_get_message (mbox, msgset.list[0], &msg); 314 msgno = mh_msgset_first (msgset);
315 rc = mu_mailbox_get_message (mbox, msgno, &msg);
314 if (rc) 316 if (rc)
315 { 317 {
316 mu_error (_("cannot read message %s: %s"), 318 mu_error (_("cannot read message %s: %s"),
317 mu_umaxtostr (0, msgset.list[0]), 319 mu_umaxtostr (0, msgno),
318 mu_strerror (rc)); 320 mu_strerror (rc));
319 exit (1); 321 exit (1);
320 } 322 }
...@@ -349,11 +351,11 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) ...@@ -349,11 +351,11 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
349 mu_message_get_header (tmp_msg, &hdr); 351 mu_message_get_header (tmp_msg, &hdr);
350 text = obstack_finish (&fcc_stack); 352 text = obstack_finish (&fcc_stack);
351 mu_header_set_value (hdr, MU_HEADER_FCC, text, 0); 353 mu_header_set_value (hdr, MU_HEADER_FCC, text, 0);
352 mh_format (&format, tmp_msg, msgset.list[0], width, &buf); 354 mh_format (&format, tmp_msg, msgno, width, &buf);
353 mu_message_destroy (&tmp_msg, NULL); 355 mu_message_destroy (&tmp_msg, NULL);
354 } 356 }
355 else 357 else
356 mh_format (&format, msg, msgset.list[0], width, &buf); 358 mh_format (&format, msg, msgno, width, &buf);
357 359
358 mu_stream_write (str, buf, strlen (buf), NULL); 360 mu_stream_write (str, buf, strlen (buf), NULL);
359 361
...@@ -409,8 +411,8 @@ main (int argc, char **argv) ...@@ -409,8 +411,8 @@ main (int argc, char **argv)
409 } 411 }
410 412
411 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 413 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
412 mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur"); 414 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
413 if (msgset.count != 1) 415 if (!mh_msgset_single_message (msgset))
414 { 416 {
415 mu_error (_("only one message at a time!")); 417 mu_error (_("only one message at a time!"));
416 return 1; 418 return 1;
......
...@@ -50,12 +50,13 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -50,12 +50,13 @@ opt_handler (int key, char *arg, struct argp_state *state)
50 return 0; 50 return 0;
51 } 51 }
52 52
53 void 53 static int
54 rmm (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 54 rmm (size_t num, mu_message_t msg, void *data)
55 { 55 {
56 mu_attribute_t attr; 56 mu_attribute_t attr;
57 mu_message_get_attribute (msg, &attr); 57 mu_message_get_attribute (msg, &attr);
58 mu_attribute_set_deleted (attr); 58 mu_attribute_set_deleted (attr);
59 return 0;
59 } 60 }
60 61
61 int 62 int
...@@ -63,7 +64,7 @@ main (int argc, char **argv) ...@@ -63,7 +64,7 @@ main (int argc, char **argv)
63 { 64 {
64 int index = 0; 65 int index = 0;
65 mu_mailbox_t mbox; 66 mu_mailbox_t mbox;
66 mh_msgset_t msgset; 67 mu_msgset_t msgset;
67 int status; 68 int status;
68 69
69 /* Native Language Support */ 70 /* Native Language Support */
...@@ -75,9 +76,9 @@ main (int argc, char **argv) ...@@ -75,9 +76,9 @@ main (int argc, char **argv)
75 76
76 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 77 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
77 78
78 mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur"); 79 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
79 80
80 status = mh_iterate (mbox, &msgset, rmm, NULL); 81 status = mu_msgset_foreach_message (msgset, rmm, NULL);
81 82
82 mu_mailbox_expunge (mbox); 83 mu_mailbox_expunge (mbox);
83 mu_mailbox_close (mbox); 84 mu_mailbox_close (mbox);
......
...@@ -75,9 +75,9 @@ static int header; ...@@ -75,9 +75,9 @@ static int header;
75 75
76 static mh_format_t format; 76 static mh_format_t format;
77 77
78 static mh_msgset_t msgset; 78 static mu_msgset_t msgset;
79 79
80 void list_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data); 80 static int list_message (size_t num, mu_message_t msg, void *data);
81 void print_header (mu_mailbox_t mbox); 81 void print_header (mu_mailbox_t mbox);
82 void clear_screen (void); 82 void clear_screen (void);
83 83
...@@ -153,7 +153,7 @@ action (mu_observer_t o, size_t type, void *data, void *action_data) ...@@ -153,7 +153,7 @@ action (mu_observer_t o, size_t type, void *data, void *action_data)
153 counter++; 153 counter++;
154 mu_mailbox_get_message (mbox, counter, &msg); 154 mu_mailbox_get_message (mbox, counter, &msg);
155 mh_message_number (msg, &num); 155 mh_message_number (msg, &num);
156 list_message (mbox, msg, num, NULL); 156 list_message (num, msg, NULL);
157 } 157 }
158 return 0; 158 return 0;
159 } 159 }
...@@ -201,13 +201,11 @@ main (int argc, char **argv) ...@@ -201,13 +201,11 @@ main (int argc, char **argv)
201 else 201 else
202 { 202 {
203 mu_mailbox_messages_count (mbox, &total); 203 mu_mailbox_messages_count (mbox, &total);
204 mh_msgset_parse (mbox, &msgset, argc, argv, "all"); 204 mh_msgset_parse (&msgset, mbox, argc, argv, "all");
205
206 if (reverse)
207 mh_msgset_reverse (&msgset);
208 205
209 print_header (mbox); 206 print_header (mbox);
210 status = mh_iterate (mbox, &msgset, list_message, NULL); 207 status = mu_msgset_foreach_dir_message (msgset, reverse,
208 list_message, NULL);
211 } 209 }
212 210
213 if (total == 0) 211 if (total == 0)
...@@ -282,8 +280,8 @@ clear_screen () ...@@ -282,8 +280,8 @@ clear_screen ()
282 } 280 }
283 } 281 }
284 282
285 void 283 static int
286 list_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) 284 list_message (size_t num, mu_message_t msg, void *data)
287 { 285 {
288 char *buffer; 286 char *buffer;
289 int len; 287 int len;
...@@ -294,4 +292,5 @@ list_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data) ...@@ -294,4 +292,5 @@ list_message (mu_mailbox_t mbox, mu_message_t msg, size_t num, void *data)
294 if (len > 0 && buffer[len-1] != '\n') 292 if (len > 0 && buffer[len-1] != '\n')
295 printf("\n"); 293 printf("\n");
296 free (buffer); 294 free (buffer);
295 return 0;
297 } 296 }
......
...@@ -737,6 +737,27 @@ _action_send (void *item, void *data) ...@@ -737,6 +737,27 @@ _action_send (void *item, void *data)
737 return 0; 737 return 0;
738 } 738 }
739 739
740 static int
741 _add_to_mesg_list (size_t num, mu_message_t msg, void *data)
742 {
743 char const *path = data;
744 struct list_elt *elt;
745 size_t uid;
746 int rc;
747
748 elt = xmalloc (sizeof *elt);
749 elt->msg = msg;
750 mu_message_get_uid (msg, &uid);
751 elt->file_name = mu_make_file_name (path, mu_umaxtostr (0, uid));
752 rc = mu_list_append (mesg_list, elt);
753 if (rc)
754 {
755 mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", NULL, rc);
756 exit (1);
757 }
758 return 0;
759 }
760
740 int 761 int
741 main (int argc, char **argv) 762 main (int argc, char **argv)
742 { 763 {
...@@ -758,13 +779,12 @@ main (int argc, char **argv) ...@@ -758,13 +779,12 @@ main (int argc, char **argv)
758 779
759 if (draftfolder) 780 if (draftfolder)
760 { 781 {
761 mh_msgset_t msgset; 782 mu_msgset_t msgset;
762 mu_url_t url; 783 mu_url_t url;
763 const char *path; 784 const char *path;
764 size_t i;
765 785
766 mbox = mh_open_folder (draftfolder, MU_STREAM_RDWR|MU_STREAM_CREAT); 786 mbox = mh_open_folder (draftfolder, MU_STREAM_RDWR|MU_STREAM_CREAT);
767 mh_msgset_parse (mbox, &msgset, argc, argv, draftmessage); 787 mh_msgset_parse (&msgset, mbox, argc, argv, draftmessage);
768 mu_mailbox_get_url (mbox, &url); 788 mu_mailbox_get_url (mbox, &url);
769 mu_url_sget_path (url, &path); 789 mu_url_sget_path (url, &path);
770 if ((rc = mu_list_create (&mesg_list))) 790 if ((rc = mu_list_create (&mesg_list)))
...@@ -772,25 +792,9 @@ main (int argc, char **argv) ...@@ -772,25 +792,9 @@ main (int argc, char **argv)
772 mu_error (_("cannot create message list: %s"), mu_strerror (rc)); 792 mu_error (_("cannot create message list: %s"), mu_strerror (rc));
773 exit (1); 793 exit (1);
774 } 794 }
775 for (i = 0; i < msgset.count; i++) 795 mu_msgset_foreach_message (msgset, _add_to_mesg_list, (void*)path);
776 {
777 struct list_elt *elt;
778 size_t uid;
779
780 elt = xmalloc (sizeof *elt);
781 mu_mailbox_get_message (mbox, msgset.list[i], &elt->msg);
782 mu_message_get_uid (elt->msg, &uid);
783 elt->file_name =
784 mu_make_file_name (path, mu_umaxtostr (0, uid));
785 rc = mu_list_append (mesg_list, elt);
786 if (rc)
787 {
788 mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", NULL, rc);
789 exit (1);
790 }
791 }
792 796
793 mh_msgset_free (&msgset); 797 mu_msgset_free (msgset);
794 } 798 }
795 else 799 else
796 { 800 {
......
...@@ -92,7 +92,10 @@ static int limit; ...@@ -92,7 +92,10 @@ static int limit;
92 static int verbose; 92 static int verbose;
93 static mu_mailbox_t mbox; 93 static mu_mailbox_t mbox;
94 static const char *mbox_path; 94 static const char *mbox_path;
95 static mh_msgset_t msgset; 95
96 static size_t *msgarr;
97 static size_t msgcount;
98
96 static size_t current_num; 99 static size_t current_num;
97 100
98 #define ACTION_REORDER 0 101 #define ACTION_REORDER 0
...@@ -416,17 +419,17 @@ shell_sort () ...@@ -416,17 +419,17 @@ shell_sort ()
416 int h, s, i, j; 419 int h, s, i, j;
417 size_t hold; 420 size_t hold;
418 421
419 for (h = startdst (msgset.count, &s); s > 0; s--, h = prevdst (h)) 422 for (h = startdst (msgcount, &s); s > 0; s--, h = prevdst (h))
420 { 423 {
421 if (verbose > 1) 424 if (verbose > 1)
422 fprintf (stderr, _("distance %d\n"), h); 425 fprintf (stderr, _("distance %d\n"), h);
423 for (j = h; j < msgset.count; j++) 426 for (j = h; j < msgcount; j++)
424 { 427 {
425 hold = msgset.list[j]; 428 hold = msgarr[j];
426 for (i = j - h; 429 for (i = j - h;
427 i >= 0 && comp0 (hold, msgset.list[i]) < 0; i -= h) 430 i >= 0 && comp0 (hold, msgarr[i]) < 0; i -= h)
428 msgset.list[i + h] = msgset.list[i]; 431 msgarr[i + h] = msgarr[i];
429 msgset.list[i + h] = hold; 432 msgarr[i + h] = hold;
430 } 433 }
431 } 434 }
432 } 435 }
...@@ -467,12 +470,12 @@ transpose(size_t i, size_t n) ...@@ -467,12 +470,12 @@ transpose(size_t i, size_t n)
467 { 470 {
468 size_t j; 471 size_t j;
469 472
470 for (j = i+1; j < msgset.count; j++) 473 for (j = i+1; j < msgcount; j++)
471 if (msgset.list[j] == n) 474 if (msgarr[j] == n)
472 { 475 {
473 size_t t = msgset.list[i]; 476 size_t t = msgarr[i];
474 msgset.list[i] = msgset.list[j]; 477 msgarr[i] = msgarr[j];
475 msgset.list[j] = t; 478 msgarr[j] = t;
476 break; 479 break;
477 } 480 }
478 } 481 }
...@@ -489,26 +492,25 @@ void ...@@ -489,26 +492,25 @@ void
489 sort () 492 sort ()
490 { 493 {
491 size_t *oldlist, i; 494 size_t *oldlist, i;
492 oldlist = xmalloc (msgset.count * sizeof (*oldlist)); 495 oldlist = xmalloc (msgcount * sizeof (*oldlist));
493 memcpy (oldlist, msgset.list, msgset.count * sizeof (*oldlist)); 496 memcpy (oldlist, msgarr, msgcount * sizeof (*oldlist));
494 497
495 switch (algorithm) 498 switch (algorithm)
496 { 499 {
497 case ARG_QUICKSORT: 500 case ARG_QUICKSORT:
498 qsort(msgset.list, msgset.count, sizeof (msgset.list[0]), 501 qsort (msgarr, msgcount, sizeof (msgarr[0]), comp);
499 comp);
500 break; 502 break;
501 503
502 case ARG_SHELL: 504 case ARG_SHELL:
503 shell_sort(); 505 shell_sort ();
504 break; 506 break;
505 } 507 }
506 508
507 switch (action) 509 switch (action)
508 { 510 {
509 case ACTION_LIST: 511 case ACTION_LIST:
510 for (i = 0; i < msgset.count; i++) 512 for (i = 0; i < msgcount; i++)
511 list_message (msgset.list[i]); 513 list_message (msgarr[i]);
512 break; 514 break;
513 515
514 default: 516 default:
...@@ -519,16 +521,16 @@ sort () ...@@ -519,16 +521,16 @@ sort ()
519 521
520 if (verbose) 522 if (verbose)
521 fprintf (stderr, _("Transpositions:\n")); 523 fprintf (stderr, _("Transpositions:\n"));
522 for (i = 0, got_signal = 0; !got_signal && i < msgset.count; i++) 524 for (i = 0, got_signal = 0; !got_signal && i < msgcount; i++)
523 { 525 {
524 if (msgset.list[i] != oldlist[i]) 526 if (msgarr[i] != oldlist[i])
525 { 527 {
526 size_t old_num, new_num; 528 size_t old_num, new_num;
527 mu_message_t msg; 529 mu_message_t msg;
528 530
529 mu_mailbox_get_message (mbox, oldlist[i], &msg); 531 mu_mailbox_get_message (mbox, oldlist[i], &msg);
530 mh_message_number (msg, &old_num); 532 mh_message_number (msg, &old_num);
531 mu_mailbox_get_message (mbox, msgset.list[i], &msg); 533 mu_mailbox_get_message (mbox, msgarr[i], &msg);
532 mh_message_number (msg, &new_num); 534 mh_message_number (msg, &new_num);
533 transpose (i, oldlist[i]); 535 transpose (i, oldlist[i]);
534 if (verbose) 536 if (verbose)
...@@ -563,6 +565,38 @@ sort () ...@@ -563,6 +565,38 @@ sort ()
563 mh_mailbox_set_cur (mbox, current_num); 565 mh_mailbox_set_cur (mbox, current_num);
564 } 566 }
565 } 567 }
568
569 static int
570 _add_msgno (size_t n, void *data)
571 {
572 size_t *pidx = data;
573 msgarr[*pidx] = n;
574 ++*pidx;
575 return 0;
576 }
577
578 static void
579 fill_msgarr (mu_msgset_t msgset)
580 {
581 size_t i;
582 int rc;
583
584 rc = mu_msgset_count (msgset, &msgcount);
585 if (rc)
586 {
587 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_count", NULL, rc);
588 exit (1);
589 }
590
591 msgarr = xcalloc (msgcount, sizeof (msgarr[0]));
592 i = 0;
593 rc = mu_msgset_foreach_msgno (msgset, _add_msgno, &i);
594 if (rc)
595 {
596 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_foreach_msgno", NULL, rc);
597 exit (1);
598 }
599 }
566 600
567 601
568 /* Main */ 602 /* Main */
...@@ -572,6 +606,7 @@ main (int argc, char **argv) ...@@ -572,6 +606,7 @@ main (int argc, char **argv)
572 { 606 {
573 int index; 607 int index;
574 mu_url_t url; 608 mu_url_t url;
609 mu_msgset_t msgset;
575 610
576 MU_APP_INIT_NLS (); 611 MU_APP_INIT_NLS ();
577 mh_argp_init (); 612 mh_argp_init ();
...@@ -597,7 +632,9 @@ main (int argc, char **argv) ...@@ -597,7 +632,9 @@ main (int argc, char **argv)
597 632
598 mh_mailbox_get_cur (mbox, &current_num); 633 mh_mailbox_get_cur (mbox, &current_num);
599 634
600 mh_msgset_parse (mbox, &msgset, argc, argv, "all"); 635 mh_msgset_parse (&msgset, mbox, argc, argv, "all");
636 fill_msgarr (msgset);
637 mu_msgset_free (msgset);
601 sort (); 638 sort ();
602 mh_global_save_state (); 639 mh_global_save_state ();
603 mu_mailbox_destroy (&mbox); 640 mu_mailbox_destroy (&mbox);
......
...@@ -25,7 +25,7 @@ mark -sequence andro -add 3-5 ...@@ -25,7 +25,7 @@ mark -sequence andro -add 3-5
25 sed -n '/^andro:/{s/ */ /g;s/ $//;p;}' Mail/inbox/.mh_sequences 25 sed -n '/^andro:/{s/ */ /g;s/ $//;p;}' Mail/inbox/.mh_sequences
26 ], 26 ],
27 [0], 27 [0],
28 [andro: 2 3 4 5 28 [andro: 2-5
29 ]) 29 ])
30 30
31 MH_CHECK([mark -add -zero],[mark01 mark-add-zero],[ 31 MH_CHECK([mark -add -zero],[mark01 mark-add-zero],[
...@@ -48,7 +48,7 @@ mark -nopublic -sequence andro -add 1 2 3 ...@@ -48,7 +48,7 @@ mark -nopublic -sequence andro -add 1 2 3
48 sed -n '/^atr-andro/{s/ */ /g;s/ $//;s/^[[^:]]*:/atr-andro:/;p;}' Mail/context 48 sed -n '/^atr-andro/{s/ */ /g;s/ $//;s/^[[^:]]*:/atr-andro:/;p;}' Mail/context
49 ], 49 ],
50 [0], 50 [0],
51 [atr-andro: 1 2 3 51 [atr-andro: 1-3
52 ]) 52 ])
53 53
54 MH_CHECK([mark -del],[mark03 mark-del],[ 54 MH_CHECK([mark -del],[mark03 mark-del],[
...@@ -67,7 +67,7 @@ MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) ...@@ -67,7 +67,7 @@ MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
67 echo 'Current-Folder: inbox' > Mail/context 67 echo 'Current-Folder: inbox' > Mail/context
68 inbox=`pwd`/Mail/inbox 68 inbox=`pwd`/Mail/inbox
69 cat > Mail/context <<EOT 69 cat > Mail/context <<EOT
70 atr-andro-$inbox: 2 3 4 5 70 atr-andro-$inbox: 2-5
71 EOT 71 EOT
72 mark -nopublic -sequence andro -del 3 72 mark -nopublic -sequence andro -del 3
73 sed -n '/^atr-andro/{s/ */ /g;s/ $//;s/^[[^:]]*:/atr-andro:/;p;}' Mail/context 73 sed -n '/^atr-andro/{s/ */ /g;s/ $//;s/^[[^:]]*:/atr-andro:/;p;}' Mail/context
......
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
17 17
18 #include <mh.h> 18 #include <mh.h>
19 19
20 static int
21 _add_to_list (size_t num, mu_message_t msg, void *data)
22 {
23 mu_list_t list = data;
24 return mu_list_append (list, msg);
25 }
26
20 void 27 void
21 mh_whatnow_env_from_environ (struct mh_whatnow_env *wh) 28 mh_whatnow_env_from_environ (struct mh_whatnow_env *wh)
22 { 29 {
...@@ -39,38 +46,15 @@ mh_whatnow_env_from_environ (struct mh_whatnow_env *wh) ...@@ -39,38 +46,15 @@ mh_whatnow_env_from_environ (struct mh_whatnow_env *wh)
39 wh->anno_field = NULL; 46 wh->anno_field = NULL;
40 else 47 else
41 { 48 {
42 size_t i; 49 mu_msgset_t msgset;
43 struct mu_wordsplit ws;
44 mh_msgset_t msgset;
45 mu_mailbox_t mbox = mh_open_folder (folder, MU_STREAM_RDWR); 50 mu_mailbox_t mbox = mh_open_folder (folder, MU_STREAM_RDWR);
46 51
47 if (mu_wordsplit (p, &ws, 52 mh_msgset_parse_string (&msgset, mbox, p, "cur");
48 MU_WRDSF_DEFFLAGS & ~MU_WRDSF_CESCAPES))
49 {
50 mu_error (_("cannot parse mhmessages (%s): %s"), p,
51 mu_wordsplit_strerror (&ws));
52 exit (1);
53 }
54 mh_msgset_parse (mbox, &msgset, ws.ws_wordc, ws.ws_wordv, "cur");
55 mu_wordsplit_free (&ws);
56 53
57 wh->mbox = mbox; 54 wh->mbox = mbox;
58 mu_list_create (&wh->anno_list); 55 mu_list_create (&wh->anno_list);
59 for (i = 0; i < msgset.count; i++) 56 mu_msgset_foreach_message (msgset, _add_to_list, wh->anno_list);
60 { 57 mu_msgset_free (msgset);
61 mu_message_t msg;
62 int rc = mu_mailbox_get_message (mbox, msgset.list[i], &msg);
63 if (rc)
64 {
65 mu_error (_("cannot get message %lu from %s: %s"),
66 (unsigned long) msgset.list[i],
67 folder,
68 mu_strerror (rc));
69 continue;
70 }
71 mu_list_append (wh->anno_list, msg);
72 }
73 mh_msgset_free (&msgset);
74 /* FIXME: 58 /* FIXME:
75 wh->anno_inplace = getenv ("mhinplace"); 59 wh->anno_inplace = getenv ("mhinplace");
76 */ 60 */
......
...@@ -118,13 +118,13 @@ parse_msgset (const char *arg) ...@@ -118,13 +118,13 @@ parse_msgset (const char *arg)
118 mu_msgset_t msgset; 118 mu_msgset_t msgset;
119 char *p; 119 char *p;
120 120
121 status = mu_msgset_create (&msgset, NULL, 0); 121 status = mu_msgset_create (&msgset, NULL, MU_MSGSET_NUM);
122 if (status) 122 if (status)
123 { 123 {
124 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, status); 124 mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, status);
125 return NULL; 125 return NULL;
126 } 126 }
127 status = mu_msgset_parse_imap (msgset, arg, &p); 127 status = mu_msgset_parse_imap (msgset, MU_MSGSET_NUM, arg, &p);
128 if (status) 128 if (status)
129 { 129 {
130 mu_error (_("failed to parse message set near \"%s\": %s"), 130 mu_error (_("failed to parse message set near \"%s\": %s"),
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 #include <mailutils/mailutils.h> 19 #include <mailutils/mailutils.h>
20 20
21 static void 21 static void
22 parse_msgset (char *arg, struct mu_msgrange *range) 22 parse_msgrange (char *arg, struct mu_msgrange *range)
23 { 23 {
24 size_t msgnum; 24 size_t msgnum;
25 char *p; 25 char *p;
...@@ -52,14 +52,36 @@ parse_msgset (char *arg, struct mu_msgrange *range) ...@@ -52,14 +52,36 @@ parse_msgset (char *arg, struct mu_msgrange *range)
52 range->msg_end = msgnum; 52 range->msg_end = msgnum;
53 } 53 }
54 54
55 mu_msgset_t
56 parse_msgset (const char *arg, mu_mailbox_t mbox,
57 int create_mode, int parse_mode)
58 {
59 int rc;
60 mu_msgset_t msgset;
61 char *end;
62
63 MU_ASSERT (mu_msgset_create (&msgset, mbox, create_mode));
64 if (arg)
65 {
66 rc = mu_msgset_parse_imap (msgset, parse_mode, arg, &end);
67 if (rc)
68 {
69 mu_error ("mu_msgset_parse_imap: %s near %s",
70 mu_strerror (rc), end);
71 exit (1);
72 }
73 }
74 return msgset;
75 }
76
55 int 77 int
56 main (int argc, char **argv) 78 main (int argc, char **argv)
57 { 79 {
58 int i; 80 int i;
59 char *msgset_string = NULL; 81 char *msgset_string = NULL;
60 mu_msgset_t msgset; 82 mu_msgset_t msgset;
61 int rc; 83 int create_mode = MU_MSGSET_NUM;
62 int flags = 0; 84 int parse_mode = MU_MSGSET_NUM;
63 mu_mailbox_t mbox = NULL; 85 mu_mailbox_t mbox = NULL;
64 86
65 mu_set_program_name (argv[0]); 87 mu_set_program_name (argv[0]);
...@@ -70,14 +92,23 @@ main (int argc, char **argv) ...@@ -70,14 +92,23 @@ main (int argc, char **argv)
70 92
71 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0) 93 if (strcmp (arg, "-h") == 0 || strcmp (arg, "-help") == 0)
72 { 94 {
73 mu_printf ("usage: %s [-msgset=SET] [-add X[:Y]] [-del X:[Y]]...\n", 95 mu_printf ("usage: %s [-msgset[uid]=SET] [-uid] [-add[uid]=X[:Y]] [-del[uid]=X[:Y]] "
96 "[-addset[uid]=SET] [-delset[uid]=SET] ...\n",
74 mu_program_name); 97 mu_program_name);
75 return 0; 98 return 0;
76 } 99 }
77 else if (strncmp (arg, "-msgset=", 8) == 0) 100 else if (strncmp (arg, "-msgset=", 8) == 0)
78 msgset_string = arg + 8; 101 {
102 parse_mode = MU_MSGSET_NUM;
103 msgset_string = arg + 8;
104 }
105 else if (strncmp (arg, "-msgsetuid=", 11) == 0)
106 {
107 parse_mode = MU_MSGSET_UID;
108 msgset_string = arg + 11;
109 }
79 else if (strcmp (arg, "-uid") == 0) 110 else if (strcmp (arg, "-uid") == 0)
80 flags |= MU_MSGSET_UID; 111 create_mode = MU_MSGSET_UID;
81 else if (strncmp (arg, "-mailbox=", 9) == 0) 112 else if (strncmp (arg, "-mailbox=", 9) == 0)
82 { 113 {
83 MU_ASSERT (mu_mailbox_create (&mbox, arg + 9)); 114 MU_ASSERT (mu_mailbox_create (&mbox, arg + 9));
...@@ -87,18 +118,7 @@ main (int argc, char **argv) ...@@ -87,18 +118,7 @@ main (int argc, char **argv)
87 break; 118 break;
88 } 119 }
89 120
90 MU_ASSERT (mu_msgset_create (&msgset, mbox, flags)); 121 msgset = parse_msgset (msgset_string, mbox, create_mode, parse_mode);
91 if (msgset_string)
92 {
93 char *end;
94 rc = mu_msgset_parse_imap (msgset, msgset_string, &end);
95 if (rc)
96 {
97 mu_error ("mu_msgset_parse_imap: %s near %s",
98 mu_strerror (rc), end);
99 return 1;
100 }
101 }
102 122
103 for (; i < argc; i++) 123 for (; i < argc; i++)
104 { 124 {
...@@ -107,15 +127,95 @@ main (int argc, char **argv) ...@@ -107,15 +127,95 @@ main (int argc, char **argv)
107 127
108 if (strncmp (arg, "-add=", 5) == 0) 128 if (strncmp (arg, "-add=", 5) == 0)
109 { 129 {
110 parse_msgset (arg + 5, &range); 130 parse_msgrange (arg + 5, &range);
111 MU_ASSERT (mu_msgset_add_range (msgset, range.msg_beg, 131 MU_ASSERT (mu_msgset_add_range (msgset,
112 range.msg_end)); 132 range.msg_beg, range.msg_end,
133 MU_MSGSET_NUM));
113 } 134 }
114 else if (strncmp (arg, "-sub=", 5) == 0) 135 else if (strncmp (arg, "-sub=", 5) == 0)
115 { 136 {
116 parse_msgset (arg + 5, &range); 137 parse_msgrange (arg + 5, &range);
117 MU_ASSERT (mu_msgset_sub_range (msgset, range.msg_beg, 138 MU_ASSERT (mu_msgset_sub_range (msgset,
118 range.msg_end)); 139 range.msg_beg, range.msg_end,
140 MU_MSGSET_NUM));
141 }
142 else if (strncmp (arg, "-adduid=", 8) == 0)
143 {
144 parse_msgrange (arg + 8, &range);
145 MU_ASSERT (mu_msgset_add_range (msgset,
146 range.msg_beg, range.msg_end,
147 MU_MSGSET_UID));
148 }
149 else if (strncmp (arg, "-subuid=", 8) == 0)
150 {
151 parse_msgrange (arg + 8, &range);
152 MU_ASSERT (mu_msgset_sub_range (msgset,
153 range.msg_beg, range.msg_end,
154 MU_MSGSET_UID));
155 }
156 else if (strncmp (arg, "-addset", 7) == 0)
157 {
158 mu_msgset_t tset;
159 int m;
160
161 arg += 7;
162 if (strncmp (arg, "uid", 3) == 0)
163 {
164 m = MU_MSGSET_UID;
165 arg += 3;
166 }
167 else
168 m = MU_MSGSET_NUM;
169 if (*arg == '=')
170 arg++;
171 else
172 {
173 mu_error ("unknown option %s", argv[i]);
174 return 1;
175 }
176
177 tset = parse_msgset (arg, mbox, m, m);
178 if (!msgset)
179 msgset = tset;
180 else
181 {
182 MU_ASSERT (mu_msgset_add (msgset, tset));
183 mu_msgset_free (tset);
184 }
185 }
186 else if (strncmp (arg, "-subset=", 8) == 0)
187 {
188 mu_msgset_t tset;
189 int m;
190
191 arg += 7;
192 if (strncmp (arg, "uid", 3) == 0)
193 {
194 m = MU_MSGSET_UID;
195 arg += 3;
196 }
197 else
198 m = MU_MSGSET_NUM;
199 if (*arg == '=')
200 arg++;
201 else
202 {
203 mu_error ("unknown option %s", argv[i]);
204 return 1;
205 }
206
207 tset = parse_msgset (arg, mbox, m, m);
208
209 if (!msgset)
210 {
211 mu_error ("no initial message set");
212 exit (1);
213 }
214 else
215 {
216 MU_ASSERT (mu_msgset_sub (msgset, tset));
217 mu_msgset_free (tset);
218 }
119 } 219 }
120 else if (strcmp (arg, "-neg") == 0) 220 else if (strcmp (arg, "-neg") == 0)
121 { 221 {
......